পিএইচপি ডেভেলপারদের জন্য ডকার

dockericon

ডকার কি?

ডকার হচ্ছে এক ধরনের টুল যা ডেভেলোপারদেরকে তাদের অ্যাপ্লিকেশন ও অ্যাপ্লিকেশনের ডিপেন্ডেন্সিগুলোকে কন্টেইনার এ করে ডিপ্লয় / রান করতে সাহায্য করে।

ধরুন আপনার পিএইচপির একটা অ্যাাপ আছে যার জন্য আপনার যথাক্রমে php-fpm, nginx, mariadb, redis এই সার্ভিস গুলো দরকার তাহলে আপনি ডকারের মাধ্যমে খুব সহজেই ৪টি পৃথক ইমেজ থেকে ৪টি পৃথক কন্টেইনার বানিয়ে এই কাজ করতে পারেন। আর সেইম কন্টেইনার গুলো আপনার টিমের সাথে শেয়ার করতে পারবেন এতে করে একই কন্টেইনার ডেভেলপ, স্টেগিং, ডেপ্লয় মেশিনে চালানো সম্ভব। তাতে করে কোডবেইস ও সেইম থাকবে আর সময়ও অনেকাংশে কমিয়ে দিবে।

ডকার মূলত একটা লিনাক্স কার্নেল ব্যাবহার করে সবগুলো কন্টেইনারকে Isolate করে। এটি লিনাক্সের বিল্ট-ইন লাইব্রেরী বা ফিচার Container (LXC), Namespaces, Cgroups ইত্যাদি ব্যাবহার করে একটা সিঙ্গেল লিনাক্সকে ভাগ করে থাকে প্রতিটা ডকার কন্টেইনার এর জন্য।

ডকার লিনাক্স অপারেটিং সিস্টেম এ সেটআপ দিলে উক্ত অপারেটিং সিস্টেম এর কার্নেল ব্যাবহার করে থাকে। আবার অন্য অপারেটিং সিস্টেম হলে একটা ভার্চুয়াল মেশিন তৈরি করে ডকার কাজ করে।

আরেকটি গুরুত্বপূর্ণ বিষয় হচ্ছে ডকার golang এ লেখা।

docker-linux-interfaces-svg

ডকারের মেইন পার্ট সমূহঃ

১. Docker Daemon ঃ এটি হোস্ট মেশিনে ডকার কন্টেইনার গুলোকে ম্যানেজ করে থাকে ।

২. Docker CLI ঃ কমান্ড চালাতে আর docker daemon এর সাথে কমুনিকেট করতে ব্যাবহ্রিত হয়।

৩. Docker Image Index ঃ এটাকে আমরা এক কথায় Docker Hub বলতে পারি যেখানে পাবলিক অথবা প্রাইভেট ইমেজ গুলো থাকে।

ডকারের মেইন ইলিমেন্ট সমূহঃ

১. Docker Container ঃ ডকার কন্টেইনার হচ্ছে ডকার ইমেজের রানটাইম ইনস্ট্যান্স যা একটা বড় মাপের অ্যাপ্লিকেশনের অংশ বিশেষ অনেকগুলো অথবা প্রয়োজনীয় কন্টেইনার এর সমন্বয়ে একটি অ্যাপ্লিকেশন স্বয়ংসম্পুর্ণ অথবা কার্জকর হয়। আমরা আগেই জেনেছি php-fpm, nginx, mariadb, redis এর কথা।

ডকার কন্টেইনার এর বড় সুবিধা হচ্ছে সব কন্টেইনার একই লিনাক্স কার্নেল শেয়ার করে কিন্তু প্রতিটা কন্টেইনার Isolate করা থাকে মানে লিনাক্সের রিসোর্সগুলো প্রতিটা কন্টেইনার এর সাথে ভাগ করা থাকে।

২. Docker Image ঃ ডকার ইমেজ হচ্ছে ডকার কন্টেইনারের বেইজ। এটি বিল্ড করার পর অপরিবর্তনীয় থাকে আর একই ইমেজ একাধিক কন্টেইনারে ব্যাবহার করা যায়। যেমনঃ nginx image, mysql image

৩. Dockerfile ঃ ডকারফাইল হচ্ছে অনেকগুলো ইন্সট্রাকশনের সমন্বয়ে গঠিত একটা ফাইল যা একটা বেইজ ইমেজকে কেন্দ্র করে নতুন ইমেজ তৈরি করে। নিজের ইমেজ তৈরি করে সেটা Docker Hub এ রাখা যায়।

ভার্চুয়াল মেশিন ও ডকারের মধ্যে পার্থক্যঃ

ভার্চুয়াল মেশিন প্রয়োজনীয় রিসোর্স সহ একটা পুরা গেস্ট মেশিনের সমন্বয়ে গঠিত। 

অপরদিকে ডকার একই লিনাক্স কার্নেল এর মধ্যে গ্রুপিং করে পৃথক পৃথক কন্টেইনার তৈরি করে।

mjhfm1c

ইন্সটলেশন ও কার্জ প্রক্রিয়াঃ

চলুন এবার দেখি কিভাবে আমাদের একটা অ্যাাপ এর জন্য ডকার ইনভায়রনমেন্ট সেটআপ করা যায়।
প্রথমেই ডকার ইন্সটলারটি www.docker.com সাইট থেকে OS অনুযায়ী নামিয়ে ইন্সটল করে নিতে হবে।

ইন্সটল হয়ে গেলে কনফার্ম হওয়ার জন্য টার্মিনালে docker কিংবা docker -v কমান্ড দিয়ে সেটা করা যাবে।

এবার ধরুন, আমাদের অ্যাাপ এর জন্য ৪টি ইমেজ php-fpm, nginx, mariadbredis দরকার, আমরা সবগুলো ইমেজ অফিশিয়াল রিপো থেকে ব্যাবহার করব শুধুমাত্র পিএইচপির জন্য আমরা ubuntu ইমেজটিকে এক্সটেন্ড করে একটা app.docker ফাইল তৈরি করব এর মেইন কারণ হচ্ছে পিএইচপির কনফিগারেশন এর সুবিধা ও ফ্লেক্সিবিলিটি। app.docker ফাইলটি দেখতে নিচের মত হবেঃ

FROM ubuntu:16.04

RUN apt-get update \
    && apt-get install -y locales \
    && locale-gen en_US.UTF-8

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

RUN apt-get update \

    && apt-get install -y curl zip unzip git software-properties-common \
    && add-apt-repository -y ppa:ondrej/php \
    && apt-get update \
    && apt-get install -y php7.1-fpm php7.1-cli php7.1-mcrypt php7.1-gd php7.1-mysql php7.1-pgsql \
       php7.1-xdebug php7.1-imap php7.1-memcached php7.1-mbstring php7.1-xml php7.1-curl \
    && php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
    && mkdir /run/php \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN sed -i -e "s/;\?daemonize\s*=\s*yes/daemonize = no/g" /etc/php/7.1/fpm/php-fpm.conf
RUN sed -i s'/listen = \/run\/php\/php7.1-fpm.sock/listen = 0.0.0.0:9000/' /etc/php/7.1/fpm/pool.d/www.conf

ADD ./docker/php.ini /etc/php/7.1/fpm/php.ini

EXPOSE 9000

CMD ["php-fpm7.1"]

উক্ত ফাইলে কিছু প্রয়োজনীয় প্যাকেজ ইন্সটলের কমান্ড লেখা আছে সাথে php-fpm কনফিগার করার জন্য sed কমান্ড আছে।

আমাদের ডিরেক্টরি স্ট্রাকচার মূলত নিচের মত হবেঃ

data/
docker/
 - app.docker
 - vhost.conf
sites/
 - index.php
 - site1/
 - site2/
docker-compose.yml

এখানে data ডিরেক্টরির মধ্যে আমাদের mysql/maridb এর ডাটাবেস গুলো থাকবে।

docker ডিরেক্টরির মধ্যে ২টি ফাইল app.docker যা আগেই কোডসহ দেখা হয়েছে আর vhost.conf হচ্ছে nginx এর ভার্চুয়াল হোস্ট।

sites ডিরেক্টরির মধ্যে আমরা আমদের এখাধিক সাইট রাখতে পারি সেইক্ষত্রে ভার্চুয়াল হোস্ট এ চিনায় দিতে হবে। আপাতত আমরা index.php তে টেস্ট কোড লিখব।

এবার আমরা docker-compose.yml ফাইলটি ব্যাবহার করব যাতে করে এক জায়গা ও একাধিক ইমেজ থেকে কন্টেইনার তৈরি করা যায় এক এক কমান্ডের মাধ্যমে।

সার্ভারের কথা চিন্তা করলে আমরা যদি এক সার্ভারে কন্টেইনার গুলো রান করাইতে চাই তাহলে docker-compose.yml ফাইলটি ব্যাবহার করতে পারি অন্যথায়, ভিন্ন ভিন্ন সার্ভারে হলে ভিন্ন ভিন্ন ভাবে কন্টেইনার রান করাইতে হবে।

যেমনঃ যদি আমাদের দরকার পরে অ্যাপটি phpnginx কন্টেইনার সহ একটা সার্ভারে থাকবে আর mariadb ডাটাবেস সার্ভারে থাকবে আবার redis আলাদা সার্ভারে থাকবে তাহলে আমাদেরকে আলাদাভাবে কন্টেইনার রান করাইতে হবে।
এতে স্কেলিং এর সুবিধা হবে কিংবা মাইক্রোসার্ভিস আর্কিটেকচার করা সম্ভব ।

আমাদের docker-compose.yml ফাইলটি নিচের মত হবেঃ

version: '2'
services:
    nginx:
        image: nginx
        ports:
            - "80:80"
        links:
            - app
        volumes:
            - ./sites:/var/www
            - ./docker/vhost.conf:/etc/nginx/conf.d/default.conf
    app:
        build:
            context: ./
            dockerfile: docker/app.docker
        volumes:
            - ./sites:/var/www
        links:
            - mysql
            - redis
    mysql:
        image: mariadb
        environment:
            - "MYSQL_ROOT_PASSWORD=1234"
            - "MYSQL_DATABASE=docker_app"
        volumes:
            - ./data:/var/lib/mysql
        ports:
            - "33061:3306"
    phpmyadmin:
        image: phpmyadmin/phpmyadmin
        restart: always
        links:
            - mysql
        ports:
            - 8183:80
        environment:
            MYSQL_USERNAME: root
            MYSQL_ROOT_PASSWORD: 1234
            PMA_ARBITRARY: 1
    redis:
        image: redis
        ports:
            - "63791:6379"

কন্টেইনারগুলো কম্পোজ করতে কিংবা একসাথে চালু করতে dokcer-compose up -d কমান্ডটি চালাইতে হবে উক্ত ডিরেক্টরি থেকে।

কন্টেইনার গুলো আপ হয়ে গেলে অ্যাপটি অ্যাকসেস করা যাবে এই লিঙ্ক থেকে http://localhost

আবার কোন নির্দিষ্ট কন্টেইনার এ ঠুকতে গেলে docker exec -it mydocker_app_1 bash এই কমান্ড চালাইতে হবে। এখানে mydocker_app_1 এর পরিবর্তে আপনার কন্টেইনার এর নাম দিলেই কাংখিত কন্টেইনার এ যাওয়া যাবে।

এবার যদি আমরা docker-compose.yml ছাড়া app.docker ফাইলটি বিল্ড এবং রান করতে চাই তাহলে নিচের মত করে কমান্ড লিখতে হবেঃ

docker build -t app -f docker/app.docker ./

প্রয়োজনীয় কমান্ড সমূহঃ

docker -v (ডকার ভার্সন দেখার জন্য)

docker build -t <NAME> -f <PATH/app.docker> ./ (ডকারফাইল থেকে ইমেজ বিল্ড করার জন্য)

docker run (ইমেজ থেকে কন্টেইনার রান করার জন্য)

docker-compose up -d (মাল্টিপল কন্টেইনার রান করার জন্য)

docker exec -it <CONTAINER_NAME> bash (কন্টেইনার এর ভিতরে যাওয়ার জন্য)

docker-compose down (কন্টেইনার স্টপ ও রিমুভ করার জন্য)

docker images (ইমেজ লিস্ট দেখার জন্য)

docker rmi <IMAGE_ID> (ইমেজ রিমুভ করার জন্য)

docker ps -a (কন্টেইনার লিস্ট দেখার জন্য)

এই লিঙ্ক থেকে আপনারা ডকার এর প্রজেক্টি পাবেন।
আবার এখানে একটা লারাভেল ও ডকার এর স্যাম্পল অ্যাপ্লিকেশন দেয়া আছে।