โดยวิธีการสร้าง Image ของ Docker นั้นมีอยู่ 2 แบบคือ

  1. ปรับปรุงจาก Image เดิมที่ Docker มีไว้ให้โดยทำการดาว์นโหลดมาปรับปรุง
  2. สร้าง Image ใหม่จาก Dockerfile

มาเริ่มกันที่การปรับปรุง Image จาก Image เดิมกันก่อนโดยใน How-To ครั้งนี้จะใช้ Image training/sinatra Image Sinatra จะเป็น Image ที่ใช้สหรับการพัฒนาภาษา Ruby ด้วย Sinatra Framework โดยเป็น Image ที่มี Base Image มาจาก Ubuntu และได้ทำการติดตั้ง Package ที่จำเป็นต่างๆไว้เรียบร้อยแล้ว ซึ่งทาง Docker ได้เตรียมไว้เพื่อให้มือใหม่ได้ทดลองเล่นกัน
ทำการดาวน์โหลด Image training/sinatra ด้วยคำสั่ง

sudo docker pull training/sinatra

เข้าไปสร้าง Container ที่ทำการปรับปรุง Image แบบง่ายๆด้วยการติดตั้ง json ด้วยคำสั่ง (ให้จดบันทึก Container ID ไว้ในโปรแกรมหรือกระดาษแล้วแต่ความถนัดเพราะต้องนำ Container ID ไปใช้งานในขั้นต่อต่อไป)

sudo docker run -t -i training/sinatra /bin/bash

gem install json

เมื่อทำการติดตั้ง json เสร็จแล้วให้ออกจาก Container ด้วยคำสั่ง

exit

ปรับ Images ใหม่ด้วยกระบวนการ Commit ด้วยคำสั่ง

sudo docker commit -m=" commit message " -a=" author" \
container_id ouruser/sinatra:v2

โดยทำการเปลี่ยนค่าดังนี้

  • commit message : ข้อความที่ต้องการในการ Commit เช่นปรับปรุงอะไรไปบ้าง
  • author : ชื่อของบุคคลที่ทำการปรับปรุง
  • container_id : Container ID ที่ได้ทำการจดบันทึกไว้
  • ouruser : ชื่อของ Image ที่มีการปรับปรุง
  • v2 : ชื่อ Tag ที่ต้องการ

ตัวอย่างเช่น

sudo docker commit -m="Added json gem" -a="Tomson Fox" \
4611ea323659 ouruser/sinatra:v2

เมื่อ Commit เสร็จแล้วทำการตรวจสอบด้วยคำสั่ง

sudo docker images

จะมี Image ที่ได้ทำการสร้างใหม่ปรากฏขึ้น

ทดลองเข้าใช้งาน Image ที่สร้างขึ้นมาใหม่ด้วยคำสั่ง

sudo docker run -t -i ouruser/sinatra:v2 /bin/bash

วิธีสร้าง Image จาก Dockerfile ใน How-To ครั้งนี้จะอ้างอิงการขั้นตอนการสร้าง Image ที่ติดตั้ง Sinatra เหมือนกับวิธีการปรับปรุง Image เพื่อแสดงให้เห็นถึงขั้นตอนการสร้าง Image ที่ชัดเจน
สร้างไดเรกทอรีและ Dockerfile ด้วยคำสั่ง

mkdir sinatra

cd sinatra

touch Dockerfile

เรียกใช้ Editor ที่ถนัดในการแก้ไข DockerFile ใน How-To ครั้งนี้ใช้ gedit เรียกใช้ gedit ด้วยคำสั่ง

gedit Dockerfile

แก้ไข Dockerfile ดังนี้

# This is a comment
FROM ubuntu:14.04
MAINTAINER Tomson Fox 
RUN apt-get update && apt-get install -y ruby ruby-dev
RUN gem install sinatra

โดยสารมารถเปลี่ยนค่าได้ดังนี้

  • This is a comment : Comment ที่ต้องการ
  • Ubuntu:14.04 : Base Image ที่ต้องการ
  • Tomson Fox : ชื่อและอีเมลของคนที่ทำ Image

หลังจากแก้ไขเสร็จให้ทำการบันทึก
คำอธิบาย Dockerfile
Image ที่สร้างขึ้นใหม่จะเรียกใช้ Base Image Ubuntu เวอร์ชัน 14.04 มาใช้เป็นพื้นฐานในการสร้างและสั่งให้อัพเดทติดตั้ง ruby, ruby-dev และ Sinatra

สร้าง Image ด้วยคำสั่ง

sudo docker build -t="myimage/sinatra:v2" .

เมื่อทำการสั่ง docker build Docker ก็จะทำการสร้าง Image ใหม่และติดตั้ง ruby, ruby-dev และ Sinatra ตามที่ได้เขียน Dockerfile ไว้

เมื่อทำการสร้าง Image ใหม่เสร็จแล้วสามารถใช้งาน Image ด้วยคำสั่ง

sudo docker run -t -i myimage/sinatra:v2 /bin/bash

สร้าง Dockerfile แบบยาก ! โดยการติดตั้ง lamp เพื่อให้รู้ถึงการใช้งาน ENV ADD และ EXPOSE กัน
สร้างไดเรกทอรีและ Dockerfile ด้วยคำสั่ง

mkdir lamp

cd lamp

สร้างไฟล์การตั้งค่าต่างเพื่อใช้สำหรับการสร้าง Image ดังนี้
สร้างไฟล์ apache_default เพื่อทำการตั้งค่าการทำงานของ Apache ด้วยคำสั่ง

gedit apache_default

แก้ไขไฟล์ apache_default

        ServerAdmin webmaster@localhost

        DocumentRoot /var/www/html
        
                Options FollowSymLinks
                AllowOverride None
        
        
                Options Indexes FollowSymLinks MultiViews
                AllowOverride FileInfo
                Order allow,deny
                allow from all
        

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/access.log combined

	#
	# Set HTTPS environment variable if we came in over secure
	#  channel.
	SetEnvIf x-forwarded-proto https HTTPS=on


แล้วทำการบันทึก
สร้างไฟล์ start-apache2.sh เพื่อทำการตั้งค่าให้ Apache

gedit start-apache2.sh

#!/bin/bash
source /etc/apache2/envvars
exec apache2 -D FOREGROUND

สร้างไฟล์ supervisord-apache2.conf เพื่อทำการตั้งค่าให้ Apache ทำงานทุกครั้งเมื่อสั่งรัน Container

gedit supervisord-apache2.sh

[program:apache2]
command=/start-apache2.sh
numprocs=1
autostart=true
autorestart=true

ไฟล์เพื่อการตั้งค่า MySQL
สร้างไฟล์ my.cnf

gedit my.cnf

[mysqld]
bind-address=0.0.0.0

สร้างไฟล์ start-mysqld.sh

gedit start-mysqld.sh

#!/bin/bash
exec mysqld_safe

สร้างไฟล์ supervisord-mysqld.conf

gedit supervisord-mysqld.conf

[program:mysqld]
command=/start-mysqld.sh
numprocs=1
autostart=true
autorestart=true

สร้างไฟล์ create_mysql_admin_user.sh

gedit create_mysql_admin_user.sh

#!/bin/bash

/usr/bin/mysqld_safe > /dev/null 2>&1 &

RET=1
while [[ RET -ne 0 ]]; do
    echo "=> Waiting for confirmation of MySQL service startup"
    sleep 5
    mysql -uroot -e "status" > /dev/null 2>&1
    RET=$?
done

PASS=${MYSQL_PASS:-$(pwgen -s 12 1)}
_word=$( [ ${MYSQL_PASS} ] && echo "preset" || echo "random" )
echo "=> Creating MySQL admin user with ${_word} password"

mysql -uroot -e "CREATE USER 'admin'@'%' IDENTIFIED BY '$PASS'"
mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION"


echo "=> Done!"

echo "========================================================================"
echo "You can now connect to this MySQL Server using:"
echo ""
echo "    mysql -uadmin -p$PASS -h -P"
echo ""
echo "Please remember to change the above password as soon as possible!"
echo "MySQL user 'root' has no password but only allows local connections"
echo "========================================================================"

mysqladmin -uroot shutdown

สร้างไฟล์ run.sh

gedit run.sh

#!/bin/bash

VOLUME_HOME="/var/lib/mysql"

sed -ri -e "s/^upload_max_filesize.*/upload_max_filesize = ${PHP_UPLOAD_MAX_FILESIZE}/" \
    -e "s/^post_max_size.*/post_max_size = ${PHP_POST_MAX_SIZE}/" /etc/php5/apache2/php.ini
if [[ ! -d $VOLUME_HOME/mysql ]]; then
    echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME"
    echo "=> Installing MySQL ..."
    mysql_install_db > /dev/null 2>&1
    echo "=> Done!"  
    /create_mysql_admin_user.sh
else
    echo "=> Using an existing volume of MySQL"
fi

exec supervisord –n

สร้าง Dockerfile

gedit Dockerfile

FROM ubuntu:14.04
MAINTAINER Tomson Fox 
# Install packages
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
  apt-get -y install supervisor git apache2 libapache2-mod-php5 mysql-server php5-mysql pwgen php-apc php5-mcrypt

# Add image configuration and scripts
ADD start-apache2.sh /start-apache2.sh
ADD start-mysqld.sh /start-mysqld.sh
ADD run.sh /run.sh
RUN chmod 755 /*.sh
ADD my.cnf /etc/mysql/conf.d/my.cnf
ADD supervisord-apache2.conf /etc/supervisor/conf.d/supervisord-apache2.conf
ADD supervisord-mysqld.conf /etc/supervisor/conf.d/supervisord-mysqld.conf

# Remove pre-installed database
RUN rm -rf /var/lib/mysql/*

# Add MySQL utils
ADD create_mysql_admin_user.sh /create_mysql_admin_user.sh
RUN chmod 755 /*.sh

# config to enable .htaccess
ADD apache_default /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite

#Enviornment variables to configure php
ENV PHP_UPLOAD_MAX_FILESIZE 10M
ENV PHP_POST_MAX_SIZE 10M

# Add volumes for MySQL 
VOLUME  ["/etc/mysql", "/var/lib/mysql" ]

EXPOSE 80 3306
CMD ["/run.sh"]

คำอธบาย Dockerfile

FROM ubuntu:14.04
MAINTAINER Tomson Fox 

กำหนดให้เรียกใช้ Base Image Ubuntu เวอร์ชัน 14.04 เป็นพื้นฐานในการสร้าง Image และระบุชื่อผู้ที่ทำการสร้าง Image

ENV DEBIAN_FRONTEND noninteractive

ตั้งค่าการใช้งานแบบ noninteractive

RUN apt-get update && \
  apt-get -y install supervisor git apache2 libapache2-mod-php5 mysql-server php5-mysql pwgen php-apc php5-mcrypt

ทำการอัพเดทและติดตั้งโปรแกรม supervisor git apache2 libapache2-mod-php5 mysql-server php5-mysql pwgen php-apc php5-mcrypt

ADD start-apache2.sh /start-apache2.sh
ADD start-mysqld.sh /start-mysqld.sh
ADD run.sh /run.sh

คัดลอกไฟล์ start-apache2.sh start-mysqld.sh และ run.sh ที่ได้ทำการสร้างขึ้นไปไว้ที่ /start-apache2.sh
/start-mysqld.sh /run.sh

RUN chmod 755 /*.sh

กำหนดสิทธิ์การใช้งานแบบ 755 ให้กับไฟล์ start-apache2.sh start-mysqld.sh run.sh ที่ได้ทำการคัดลอกไป

ADD my.cnf /etc/mysql/conf.d/my.cnf
ADD supervisord-apache2.conf /etc/supervisor/conf.d/supervisord-apache2.conf
ADD supervisord-mysqld.conf /etc/supervisor/conf.d/supervisord-mysqld.conf

คัดลอกไฟล์ my.cnf supervisord-apache2.conf supervisord-mysqld.conf ไปไว้ที่ /etc/mysql/conf.d/my.cnf /etc/supervisor/conf.d/supervisord-apache2.conf /etc/supervisor/conf.d/supervisord-mysqld.conf ตามลำดับ

RUN rm -rf /var/lib/mysql/*

ลบฐานข้อมูลทั้งหมดที่ทำการติดตั้งมาจาก MySQL

ADD create_mysql_admin_user.sh /create_mysql_admin_user.sh
RUN chmod 755 /*.sh

คัดลอกไฟล์ create_mysql_admin_user.sh ไปไว้ที่ /create_mysql_admin_user.sh เพื่อทำการสร้างผู้ใช้งาน MySQL ตามที่ไฟล์ create_mysql_admin_user.sh ได้กำหนดไว้ จากนนั้นทำการตั้งค่าสิทธิ์การใช้งานแบบ 755

ADD apache_default /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite

คัดลอกไฟล์ apache_default แทนที่ /etc/apache2/sites-available/000-default.conf เพื่อทำการตั้งค่าการทำงานของ Apache จากนั้นทำการบันทึกการตั้งค่าด้วยคำสั่ง a2enmod rewrite

ENV PHP_UPLOAD_MAX_FILESIZE 10M
ENV PHP_POST_MAX_SIZE 10M

กำหนดค่าขนาดของไฟล์ที่สามารถอัพโหลดและขนาดพื้นที่ของข้อมูลที่รับมาจากคำสั่ง POST ของ PHP ได้ไม่เกิน 10 เมกะไบต์

EXPOSE 80 3306

กำหนด Port การเชื่อมต่อที่สามารถเข้าถึงการใช้งานของ Container ได้ คือ Port 80 ที่ใช้สำหรับการเชื่อมต่อแบบ http และ 3306 ที่ใช้สำหรับการเชื่อมต่อฐานข้อมูล MySQL

CMD ["/run.sh"]

สั่งใช้งานไฟล์ run.sh ที่ได้สร้างขึ้นไว้

เมื่อทำการสร้างไฟล์ทั้งหมดเสร็จแล้วทำการสร้าง Image ด้วยคำสั่ง

sudo docker build -t="mylamp/lamp:v1" .

เมื่อทำการสร้าง Image เสร็จเรียบร้อยแล้วลองเรียกใช้งาน Image เพื่อสร้าง Container โดยการกำหนด Port การเชื่อมต่อคือ 80 และ 3306 ด้วยคำสั่ง

docker run -d -p 80:80 -p 3306:3306 mylamp/lamp:v1

เรียกดูหมายเลข IP Address ของ Docker ด้วยคำสั่ง

ifconfig docker

ไปที่เว็บเบราว์เซอร์แล้วใส่หมายเลข IP Address ของ Docker ลงไปแล้วกด Enter ก็จะพบกับหน้าจอเริ่มต้นของ Apache

เท่านี้ก็สามารถสร้าง Image ใช้งานเองกันได้แล้ว How-To ครั้งหน้าจะมาเล่นอะไรกับ Docker อีกก็คอยติดตามอ่านกันได้ในครั้งต่อไปครับ

Comments are closed.