कबूल करने का समय। Honeybadger पर काम करने के चार वर्षों में मेरा विकास वातावरण ज्यादा नहीं बदला है। लेकिन उस समय में Honeybadger बहुत अधिक परिष्कृत हो गया है, कार्य करने के लिए लगभग दस सेवाओं पर निर्भर करता है।
यही कारण है कि हम स्थानीय विकास के लिए Docker की ओर बढ़ रहे हैं। हर डेवलपर को Postgres, Cassandra, Memcached और बाकी को सेट अप करने के बजाय, हम docker-compose का उपयोग करके एक पूर्व-निर्मित वातावरण को स्पिन अप कर सकते हैं। यह बहुत बढ़िया है।
स्वाभाविक रूप से, मुझे आश्चर्य होने लगा कि Dockerized एप्लिकेशन को डेप्लॉय करना कितना आसान होगा।
Docker के साथ डेप्लॉय करना
Docker docker-machine और docker-swarm जैसी यूटिलिटीज के साथ आता है जो डेप्लॉयमेंट को दर्द रहित बनाने के लिए माना जाता है। अभी तक उन्होंने उस वादे को पूरा नहीं किया है। यदि आप उनकी कमियों के बारे में सब पढ़ना चाहते हैं, तो इस हालिया हैकर न्यूज पोस्ट को देखें।
यही कारण है कि मैंने Amazon के ECS (EC2 Container Service) पर ध्यान केंद्रित करना चुना।
ECS क्या है?
ECS docker-compose और docker-swarm का एक बड़ा, प्रोडक्शन-रेडी मैशअप जैसा है।
ECS के साथ आप कह सकते हैं "मेरे वेब ऐप की तीन कॉपी चलाएं" और यह आपके EC2 इंस्टेंस के क्लस्टर के अंदर उचित Docker कंटेनरों को बुद्धिमानी से स्पिन अप करेगा।
यह आपके कंटेनरों में अनुरोधों को लोड-बैलेंस कर सकता है, और लोड के आधार पर आपके क्लस्टर को ऊपर या नीचे स्केल कर सकता है।
Dockerized Sinatra ऐप बनाना
यहां एक साधारण Sinatra ऐप है। यह वर्तमान समय प्रिंट करता है, इसलिए आप जान जाएंगे कि क्या आप एक कैश्ड संस्करण देखते हैं। यह ऐप चलाने वाले कंप्यूटर का नाम भी प्रिंट करता है। बाद में, हम इस ऐप को चलाने वाले कई सर्वर स्पिन अप करने जा रहे हैं और अनुरोधों को रूट करने के लिए लोड बैलेंसर का उपयोग करेंगे। होस्टनाम वापस करके, हम बता सकते हैं कि किस सर्वर ने एक विशेष अनुरोध को सर्व किया।
ऐप
मैं आपको जो Dockerized Sinatra ऐप दिखाने वाला हूं वह tcnksm-sample/docker-sinatra का भारी रूप से रीराइट किया गया संस्करण है।
require 'sinatra'
require 'sinatra/base'
class App < Sinatra::Base
get '/' do
"Hello from sinatra! The time is #{ Time.now.to_i } on #{ `hostname` }!"
end
end
यहां Gemfile है:
# Gemfile
source 'https://rubygems.org'
gem 'sinatra'
gem 'thin'
...और यहां config.ru फ़ाइल है:
$:.unshift(File.dirname(__FILE__))
require 'app'
run App
Dockerfile
हमें इस ऐप के लिए एक Docker इमेज बनाने के लिए एक Dockerfile की आवश्यकता होगी। यह ऐप के लिए डायरेक्टरी बनाता है, फ़ाइलों को कॉपी करता है, और पोर्ट 80 पर एक वेब सर्वर चलाता है।
FROM ruby:2.3.1-slim
RUN apt-get update -qq && apt-get install -y build-essential
ENV APP_ROOT /var/www/docker-sinatra
RUN mkdir -p $APP_ROOT
WORKDIR $APP_ROOT
ADD Gemfile* $APP_ROOT/
RUN bundle install
ADD . $APP_ROOT
EXPOSE 80
CMD ["bundle", "exec", "rackup", "config.ru", "-p", "80", "-s", "thin", "-o", "0.0.0.0"]
इमेज बनाना और चलाना
सबसे पहले, हम Docker को वर्तमान डायरेक्टरी में Dockerfile से एक इमेज बनाने के लिए कहेंगे। फिर हम इसे चलाएंगे, कंटेनर के पोर्ट 80 को localhost:4000 पर मैप करेंगे।
docker build -t docker-sinatra .
docker run -p 4000:80 docker-sinatra
यह जांचने के लिए कि क्या यह काम करता है, अपने वेब ब्राउज़र में localhost:4000 खोलें। आपको ऐसा कुछ दिखना चाहिए:

ECS पर डेप्लॉय करना
अब ECS पर डेप्लॉय करते हैं। हम उनके सेटअप विज़ार्ड का उपयोग करने जा रहे हैं। क्या यह चीटिंग है? मुझे परवाह नहीं। :) तो ECS कंट्रोल पैनल पर जाएं।

"Get Started" पर क्लिक करें। फिर अगली स्क्रीन पर "Continue" पर क्लिक करें।"

अपनी Docker रजिस्ट्री बनाना
आप आमतौर पर अपने विकास वातावरण से प्रोडक्शन सर्वर पर Docker इमेज अपलोड नहीं करते। इसके बजाय, आप इमेज को एक Docker रजिस्ट्री में भेजते हैं - जैसे dockerhub - और सर्वर डेप्लॉय पर उन्हें खींचता है। Amazon एक निजी Docker रजिस्ट्री प्रदान करता है। यह आवश्यक नहीं है कि आप इसका उपयोग करें, लेकिन हम अभी के लिए करने जा रहे हैं।
मैं अपनी रजिस्ट्री का नाम "docker-sinatra" रखूंगा:

अपनी इमेज को रजिस्ट्री में पुश करना
फिर, मुझे अपनी इमेज बनाने और इसे रजिस्ट्री में पुश करने के लिए कमांड की एक सूची दी गई है।
पहली बार जब मैंने यह कोशिश की, तो मेरे ब्राउज़र के एड-ब्लॉकर ने कमांड को सही ढंग से प्रदर्शित होने से रोक दिया। अजीब - मुझे पता है।

अपनी टास्क डेफिनिशन बनाना
AWS नए, भ्रमित करने वाले शब्द बनाने पसंद करता है। एक "टास्क डेफिनिशन" बस कंटेनरों की एक सूची है जो एक साथ चलना चाहिए। यह एक Procfile की तरह है, या एक docker-compose कॉन्फिगरेशन।
तो, यदि आपके एप्लिकेशन में Nginx चलाने वाला एक कंटेनर, Unicorn चलाने वाला एक, और Sidekiq चलाने वाला एक है तो सभी तीन आपकी "टास्क डेफिनिशन" के भीतर समाहित हो सकते हैं।
हमारा ऐप बहुत सरल है। हमारे पास केवल एक कंटेनर है। इसलिए कॉन्फिगरेशन न्यूनतम है।
- मैं सुनिश्चित करूंगा कि सही इमेज हमारी रजिस्ट्री से खींची जाती है
- मैं कंटेनर से पोर्ट 80 को कंटेनर चलाने वाले EC2 इंस्टेंस पर पोर्ट 80 पर मैप करूंगा।

अपनी सर्विस बनाना
अधिक भ्रमित करने वाली शब्दावली! "सर्विस" कॉन्फिग्रेशन आपको यह निर्दिष्ट करने देता है कि कितने "टास्क" (यानी आपके ऐप की कॉपी) चलने चाहिए, और उन्हें कैसे लोड बैलेंस किया जाता है।
यहां, मैं अपने ऐप की तीन कॉपी चलाना चाहता हूं, पोर्ट 80 पर लोड बैलेंसिंग के साथ।

अपना क्लस्टर स्पिन अप करना
एक क्लस्टर विशिष्ट EC2 इंस्टेंस का एक समूह है जो Amazon के ECS सॉफ्टवेयर को चला रहे हैं। आप उनके साथ कुछ भी कर सकते हैं जो आप किसी अन्य EC2 इंस्टेंस के साथ कर सकते हैं। इस मामले में, मैंने निर्दिष्ट किया कि मैं तीन t2.micro इंस्टेंस चाहता हूं।
कुछ पुष्टिकरण चरणों और लगभग 5 मिनट के इंतजार के बाद, सब कुछ तैयार था।
एक बार जब आपकी सर्विस कार्यात्मक हो जाती है, तो आप एक स्क्रीन देखेंगे जो कुछ इस तरह दिखती है:

ऐप का परीक्षण
आप लोड बैलेंसर नाम पर क्लिक करके इसके विवरण खींच सकते हैं। वहां, आपको इसका सार्वजनिक डोमेन नाम मिलना चाहिए। इसे अपने ब्राउज़र में डालें और आप हमारे नमूना ऐप को देखेंगे।

यदि आप कुछ बार रीफ्रेश करते हैं, तो आप देखेंगे कि होस्टनाम बदलता है। ऐसा इसलिए है क्योंकि लोड बैलेंसर आपके अनुरोधों को सभी तीन होस्ट में बैलेंस कर रहा है।
सफाई करना
ECS विज़ार्ड ने अभी आपके AWS खाते में बहुत सारे संसाधन बनाए हैं। आप शायद उन्हें वहीं नहीं छोड़ना चाहते। वे चीजों को अव्यवस्थित कर देंगे, और आपसे पैसे खर्च हो सकते हैं।
सौभाग्य से, ECS विज़ार्ड अपने सभी संसाधनों को बनाने के लिए CloudFormation का उपयोग करता है। इसका मतलब है कि आप CloudFormation स्टैक को हटाकर सब कुछ आसानी से हटा सकते हैं।
