Text of Relipa

Docker cho người mới bắt đầu. Phần 2 – Xây dựng môi trường

Phần 1 – Docker cho người mới bắt đầu

 

Trong phần 1 chúng ta đã phần nào nắm sơ qua về cách hoạt động cũng như cách triển khai môi trường thông qua các image. TIếp tục trong phần này, chúng ta sẽ tìm hiểu về các bước để tạo một image với các thành phần cần thiết cho project.

Một image trong Docker được tạo thành từ các lớp layer, các layer này về bản chất là những thư mục core của hệ điều hành Linux nhưng chúng chỉ chứa các file cần thiết của các thành phần mà chúng ta cài đặt thêm, để khi ghép vào với nhau sẽ tạo nên một môi trường hoàn chỉnh với các package cần thiết cho project

Các lớp layer trong 1 image

 

Các thành phần trong 1 layer

Có 2 cách để tạo ra 1 image, bạn có thể build automatic từ Dockerfile hoặc build bằng tay bằng cách run 1 container, cài đặt các package và pull nó lên Dockerhub.

1. Build automatic từ Dockerfile

Trước hết, để viết được một Dockerfile hoàn chỉnh, các bạn cần hiểu được các command của Dockerfile:

Tiến hành tạo Dockerfile:

touch Dockerfile

# Extend từ image php phiên bản 7.1.2
 FROM php:7.1.2

MAINTAINER Chungpt <it.chungpt1291@gmail.com>

# Thư mục làm việc mặc định
 WORKDIR /app

# Chạy command cài đặt
 RUN apt-get update
 RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
 RUN apt-get install zlib1g-dev && docker-php-ext-install pdo pdo_mysql zip

# Copy thư mục và file từ host vào image
 ADD helpers /home/helpers/
 ADD start.sh /home/
 RUN chmod +x /home/start.sh

# Public port 80
 EXPOSE 80

# Chạy file start.sh
 CMD ["/home/start.sh"]

Tạo file functions.sh trong thư mục helpers

touch helpers/functions.sh

#!/bin/bash

HOME=/home

appendToFileOnLine()
{
    sed -i "$1s,.*,$2," $3
}

appendToFile()
{
    echo $1 >> $2
}

appendAfterStringWithString()
{
    sed -i "/$1/a \\$2\\" $3

}

appendAfterStringWithFileContent()
{
    sed -i "/$1/r $2" $3
}

searchStringAndReplaceWith()
{
    sed -i "s/$1/$2/g" $3
}

clearCurrentFolder()
{
    find . -mindepth 1 -delete
    rm -rf ./*
}

setUpMySQL()
{
    source $HOME/helpers/mysqlConfig.sh

    #configure env file    
    searchStringAndReplaceWith "DB_HOST=127.0.0.1" "DB_HOST=${MYSQL_CONFIG[DB_HOST]}" .env    
    searchStringAndReplaceWith "DB_DATABASE=homestead" "DB_DATABASE=${MYSQL_CONFIG[DB_DATABASE]}" .env
    searchStringAndReplaceWith "DB_USERNAME=homestead" "DB_USERNAME=${MYSQL_CONFIG[DB_USERNAME]}" .env
    searchStringAndReplaceWith "DB_PASSWORD=secret" "DB_PASSWORD=${MYSQL_CONFIG[DB_PASSWORD]}" .env
}

Tạo file mysqlConfig.sh trong thư mục helpers

#!/bin/sh

declare -A MYSQL_CONFIG

MYSQL_CONFIG[DB_HOST]="mysql"
MYSQL_CONFIG[DB_DATABASE]="laravelApp"
MYSQL_CONFIG[DB_USERNAME]="laravelDbUser"
MYSQL_CONFIG[DB_PASSWORD]="laravelDbPass!"

Tạo file start.sh

#!/bin/bash

source /home/helpers/functions.sh

if [ ! -f artisan ]; then

    echo "Dir does not contain artisan, create Laravel project"

    #clear any file or hidden file in special for macOs users .DS_STORE
    clearCurrentFolder

    #add compooser dependecies
    composer create-project laravel/laravel ./ --prefer-dist

    setUpMySQL

fi

composer update

#start project
php artisan serve --port=80 --host=0.0.0.0

Cấu trúc thư mục sau khi làm xong các bước:

Tiến hành build image

Như vậy chúng ta đã tạo được image laravelenv-automatic-build của mình. Tiếp đến chúng ta sẽ chạy image này để tạo ra 1 container dùng để dev Laravel, với image này chúng ta sẽ chỉ khởi chạy, mọi việc từ download source Laravel, lib Composer, … sẽ được tự động chạy khi khởi tạo container.

docker run -itd -e MYSQL_ROOT_PASSWORD=rootPass123! -e MYSQL_DATABASE=laravelApp -e MYSQL_USER=laravelDbUser -e MYSQL_PASSWORD=laravelDbPass! --name mysql mysql &&  docker run -itd -v $(pwd):/app -p 80:80 --link mysql:lmysql --name laravel_application laravelenv-automatic-build

Kiểm tra lại thành quả

2 container là laravel và mysql đã được tạo, thư mục của bạn đã được setup đầy đủ các thành phần của laravel, và truy cập http://localhost/  xem site đã hoạt động hay chưa. Lưu ý lần đầu chạy image sẽ mất chút thời gian vì script sẽ phải clone Laravel frame work và download các thư viện Composer về, trong lúc đó hãy tìm cho mình 1 cốc cafe nhé 😀

 

2. Build image thủ công

Qua phần đầu chúng ta có thể thấy việc build tự động từ Dockerfile sẽ rất dễ dàng trong việc tùy biến các thành phần trong image, nhưng nếu không biết các command run trong script có hoạt động đúng hay không thì sao? Việc này chúng ta có thể build 1 cách thủ công, nó tương tự như việc cài đặt server truyền thống, truy cập và run command.

Trong phần này mình sẽ chọn image ubuntu:latest để demo vì đã quen với các cài đặt trên ubuntu, nếu quen dùng Distro khác bạn có thể search trên DockerHub, đủ cả.

Pull image ubuntu:latest (thời điểm viết bài nó tương ứng với version 16.04)

docker pull ubuntu

Khởi chạy và truy cập vào container

docker run -itd -p 8080:80 –name ubuntu_demo ubuntu &&  docker exec -it ubuntu_demo bash

Thử cài nginx

apt-get update
apt-get install -y nginx
service nginx restart

Sau khi khởi động lại nginx, port 80 của container này sẽ được expose ra port 8080 của host machine. Chúng ta sẽ vào http://localhost:8080 để kiểm tra

Tiếp theo chúng ta sẽ tiến hành push image này lên DockerHub, để làm được bước này trước hết bạn phải có tài khoản DockerHub và login trên máy

docker login -u <tên tài khoản>

Commit và push image lên DockerHub

Như vậy, những lần sau khi cần chúng ta sẽ chỉ phải pull image này về và chạy, rất tiện phải ko 😀