কনফেশন টাইম। Honeybadger-এ কাজ করার গত চার বছরে আমার ডেভেলপমেন্ট এনভায়রনমেন্ট অনেক পরিবর্তন হয়নি। কিন্তু সেই সময় Honeybadger অনেক বেশি সোফিস্টিকেটেড হয়ে গেছে, প্রায় দশটি সার্ভিসের ওপর ডিপেন্ড করে।
সেজন্য আমরা লোকাল ডেভেলপমেন্টের জন্য Docker-এ মুখ ফেরিয়েছি। প্রতিটি ডেভেলপার Postgres, Cassandra, Memcached এবং বাকিগুলো সেট আপ করার বদলে, আমরা docker-compose ব্যবহার করে একটি প্রি-মেড এনভায়রনমেন্ট স্পিন আপ করতে পারি। এটি অসাধারণ।
স্বাভাবিকভাবেই, আমার মনে প্রশ্ন উঠল ডকারাইজড অ্যাপ্লিকেশন ডিপ্লয় করা কতটা সহজ।
ডকার দিয়ে ডিপ্লয়
Docker-এর সাথে docker-machine এবং docker-swarm-এর মতো ইউটিলিটি আছে যেগুলো ডিপ্লয়মেন্ট পেইনলেস করতে সাপোর্ট করা হয়। কিন্তু এখন পর্যন্ত সেগুলো সেটি ডেলিভার করতে পারেনি। আপনি যদি তাদের কمیatudins পড়তে চান, এই সাম্প্রতিক Hacker News পোস্ট চেক করুন।
সেজন্য আমি Amazon ECS (EC2 Container Service)-এ ফোকাস করলাম।
ECS কী?
ECS একটু docker-compose এবং docker-swarm-এর মতো একটি প্রোডাকশন-রেডি ম্যাশআপ।
ECS-এ আপনি বলতে পারেন "আমার ওয়েব অ্যাপের তিন কপি চালাও" এবং এটি বুদ্ধিমানভাবে আপনার EC2 ইনস্ট্যান্সের ক্লাস্টারের ভেতরে উপযুক্ত ডকার কন্টেইনার স্পিন আপ করবে।
এটি আপনার কন্টেইনারগুলোর মাঝে রিকোয়েস্ট লোড-ব্যালেন্স করতে পারে, এবং লোডের ওপর নির্ভর করে আপনার ক্লাস্টার স্কেল আপ বা ডাউন করতে পারে।
ডকারাইজড সিন্যাট্রা অ্যাপ তৈরি
এখানে একটি সহজ সিন্যাট্রা অ্যাপ। এটি বর্তমান টাইম প্রিন্ট করে, যাতে আপনি জানতে পারেন ক্যাশ্ড ভার্সন দেখছেন কিনা। এটি কম্পিউটারের নামও প্রিন্ট করে যা অ্যাপটি চালাচ্ছে। পরে, আমরা এই অ্যাপ চালানোর জন্য একাধিক সার্ভার স্পিন আপ করব এবং রিকোয়েস্ট রাউট করার জন্য একটি লোড ব্যালেন্সার ব্যবহার করব। হোস্টনেম রিটার্ন করে, আমরা জানতে পারব কোন সার্ভার একটি নির্দিষ্ট রিকোয়েস্ট সার্ভ করেছে।
দ্য অ্যাপ
আমি যে ডকারাইজড সিন্যাট্রা অ্যাপটি আপনাকে দেখাতে যাচ্ছি সেটি 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 লাগবে। এটি অ্যাপের জন্য ডিরেক্টরি তৈরি করে, ফাইলগুলো কপি করে, এবং পোর্ট ৮০-এ একটি ওয়েব সার্ভার চালায়।
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"]
ইমেজ বিল্ড এন্ড রান
প্রথমে, আমরা ডকারকে বলব কারেন্ট ডিরেক্টরির Dockerfile থেকে একটি ইমেজ বিল্ড করতে। তারপর আমরা এটি রান করব, কন্টেইনারের পোর্ট ৮০ লোকালহোস্ট:৪০০০-এ ম্যাপ করে।
docker build -t docker-sinatra .
docker run -p 4000:80 docker-sinatra
চেক করতে localhost:4000 আপনার ওয়েব ব্রাউজারে খুলুন। আপনি কিছু এইরকম দেখতে পাবেন:

ECS-এ ডিপ্লয়
এখন ECS-এ ডিপ্লয় করি। আমরা তাদের সেটআপ উইজার্ড ব্যবহার করব। ইট চিটিং? আমি পারাহ নই। :) তাই ECS কন্ট্রোল প্যানেলে যান।

"Get Started"-এ ক্লিক করুন। পরবর্তী স্ক্রিনে "Continue"-এ ক্লিক করুন।

আপনার ডকার রেজিস্ট্রি তৈরি
আপনি সাধারণত ডেভেলপমেন্ট এনভায়রনমেন্ট থেকে প্রোডাকশন সার্ভারে ডকার ইমেজ আপলোড করেন না। বরং, আপনি ইমেজগুলো একটি ডকার রেজিস্ট্রিতে পাঠান—যেমন dockerhub—এবং সার্ভার সেগুলো ডিপ্লয়ের সময় পুল করে। Amazon একটি প্রাইভেট ডকার রেজিস্ট্রি প্রদান করে। এটি ব্যবহার করা বাধ্যতামূলক নয়, কিন্তু আমরা এখন এর জন্য ব্যবহার করব।
আমি আমার রেজিস্ট্রিকে "docker-sinatra" নাম দেব:

রেজিস্ট্রিতে ইমেজ পাশ
তারপর, আমাকে ইমেজ বিল্ড এবং রেজিস্ট্রিতে পাশ করার জন্য কমান্ডের একটি লিস্ট দেওয়া হয়।
প্রথমবার আমি চেষ্টা করলাম, আমার ব্রাউজারের অ্যাড-ব্লকার কমান্ডগুলো সঠিকভাবে দেখাতে পারেনি। বেড়া-আশ್ಚর্য।

আপনার টাস্ক ডেফিনিশন তৈরি
AWS নতুন, বিভ্রান্তিকর টার্মিনোলজি গড়ে তোলা পছন্দ করে। একটি "টাস্ক ডেফিনিশন" সিম্পলি কন্টেইনারের একটি লিস্ট যা একসাথে চালানো উচিত। এটি একটি প্রোকফাইল বা ডকার-কম্পোজ কনফিগারেশনের মতো।
তাই, যদি আপনার অ্যাপ্লিকেশনে একটি কন্টেইনার Nginx চলে, একটি Unicorn চলে, এবং একটি Sidekiq চলে, তবে তিনটিই আপনার "টাস্ক ডেফিনিশন"-এ থাকতে পারে।
আমাদের অ্যাপ খুব সিম্পল। আমাদের শুধু একটি কন্টেইনার আছে। তাই কনফিগারেশন মিনিমাল।
- সঠিক ইমেজ আমাদের রেজিস্ট্রি থেকে পুল হবে তা নিশ্চিত করব
- কন্টেইনারের পোর্ট ৮০ EC2 ইনস্ট্যান্সের পোর্ট ৮০-এ ম্যাপ করব যা কন্টেইনারটি চালাচ্ছে।

আপনার সার্ভিস তৈরি
আরও বিভ্রান্তিকর টার্মিনোলজি! "সার্ভিস" কনফিগারেশন আপনাকে স্পেসিফাই করতে দেয় কতটি "টাস্ক" (অর্থাৎ আপনার অ্যাপের কপি) চালানো উচিত, এবং সেগুলো কীভাবে লোড ব্যালেন্সড।
এখানে, আমি আমার অ্যাপের তিন কপি চালাতে চাই, পোর্ট ৮০-এ লোড ব্যালেন্সিং के সাথে।

আপনার ক্লাস্টার স্পিন আপ
একটি ক্লাস্টার হচ্ছে কিছু টিপিক্যাল EC2 ইনস্ট্যান্স যেগুলো Amazon-এর ECS সফটওয়্যার রান করছে। আপনি সেগুলোর সাথে যেকোনো কিছু করতে পারেন যা আপনি অন্য EC2 ইনস্ট্যান্সের সাথে করতে পারেন। এই কেসে, আমি তিনটি t2.micro ইনস্ট্যান্স স্পেসিফাই করলাম।
কয়েকটি কনফার্মেশন স্টেপ এবং প্রায় ৫ মিনিট অপেক্ষার পর, সব কিছু রেডি।
একবার আপনার সার্ভিস ফাংশনাল হলে, আপনি এমন একটি স্ক্রিন দেখবেন:

অ্যাপ টেস্টিং
আপনি লোড ব্যালেন্সার নামের ওপর ক্লিক করে এর ডিটেইলস দেখতে পারেন। সেখানে, আপনাকে এর পাবলিক ডোমেইন নাম পাওয়া উচিত। সেটি আপনার ব্রাউজারে দিন এবং আপনি আমাদের স্যাম্পল অ্যাপ দেখবেন।

আপনি যদি কয়েকবার রিফ্রেশ করেন, আপনি দেখবেন হোস্টনেম পরিবর্তন হচ্ছে। এর কারণ লোড ব্যালেন্সার আপনার রিকোয়েস্টগুলো সব তিন হোস্টের মাঝে ব্যালেন্স করছে।
ক্লিন আপ
ECS উইজার্ড আপনার AWS একাউন্টে এখন অনেক রিসোর্স তৈরি করেছে। আপনি সম্ভবত সেগুলো রেখে রাখতে চাবেন না। সেগুলো জিনিসপত্র লাগাবে, এবং আপনাকে টাকা খরচ করতে হতে পারে।
সৌভাগ্যtois, ECS উইজার্ড CloudFormation ব্যবহার করে তার সব রিসোর্স তৈরি করে। অর্থাৎ আপনি সব কিছু ডিলিট করতে পারেন শুধু CloudFormation স্ট্যাকটি রিমুভ করে।
