Mở đầu#
Ở các phần trước mình đã giới thiệu tổng quan Docker Engine và kiến trúc của Docker, cũng như chạy một container đầu tiên với các image có sẵn. Ở phần này mình sẽ viết hướng dẫn tạo image bằng Dockerfile
1. Dockerfile là gì ?#
- Dockerfile là một file dạng text không có extension, và tên bắt buộc phải là Dockerfile
- Dockerfile là một file kịch bản sử dụng để tạo mới một image
2. Cấu trúc một Dockerfile#
Đây là cấu trúc một Dockerfile của ứng dụng WordPress
FROM php:7.1-apache # install the PHP extensions we need RUN set -ex; \ \ savedAptMark="$(apt-mark showmanual)"; \ \ apt-get update; \ apt-get install -y --no-install-recommends \ libjpeg-dev \ libpng-dev \ ; \ \ docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \ docker-php-ext-install gd mysqli opcache zip; \ \ # reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies apt-mark auto '.*' > /dev/null; \ apt-mark manual $savedAptMark; \ ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \ | awk '/=>/ { print $3 }' \ | sort -u \ | xargs -r dpkg-query -S \ | cut -d: -f1 \ | sort -u \ | xargs -rt apt-mark manual; \ \ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ rm -rf /var/lib/apt/lists/* # set recommended PHP.ini settings # see https://secure.php.net/manual/en/opcache.installation.php RUN { \ echo 'opcache.memory_consumption=128'; \ echo 'opcache.interned_strings_buffer=8'; \ echo 'opcache.max_accelerated_files=4000'; \ echo 'opcache.revalidate_freq=2'; \ echo 'opcache.fast_shutdown=1'; \ echo 'opcache.enable_cli=1'; \ } > /usr/local/etc/php/conf.d/opcache-recommended.ini RUN a2enmod rewrite expires VOLUME /var/www/html ENV WORDPRESS_VERSION 5.0.3 ENV WORDPRESS_SHA1 f9a4b482288b5be7a71e9f3dc9b5b0c1f881102b RUN set -ex; \ curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \ echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \ # upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress tar -xzf wordpress.tar.gz -C /usr/src/; \ rm wordpress.tar.gz; \ chown -R www-data:www-data /usr/src/wordpress COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] CMD ["apache2-foreground"]
3. Các command cơ bản trong Dockerfile#
FROM
FROM centos:centos7
FROM chỉ định rằng image build này sẽ base trên image gốc nào
LABEL
LABEL "image-type"="huy-test"
LABEL "image-type1"="huy-test1"
LABEL "image-type2"="huy-test2"
LABEL: Chỉ định label metadata của image. Để xem được các label này sử dụng câu lệnh docker inspect <IMAGE ID>
MAINTAINER
MAINTAINER huytm
MAINTERNER là author (tác giả) build image đó.
RUN
RUN yum update -y
RUN thực hiện một câu lệnh Linux. Tùy vào image gốc mà có các câu lệnh tương ứng (ví dụ Ubuntu sẽ là RUN apt-get update -y
)
COPY
COPY start.sh /start.sh
COPY Copy một file từ Dockerhost vào image trong quá trình build image
ENV
ENV source /var/www/html/
COPY index.html ${source}
ENV là biến môi trường sử dụng trong quá trình build image.
ENV chỉ có thể được sử dụng trong các command sau:
- ADD
- COPY
- ENV
- EXPOSE
- FROM
- LABEL
- STOPSIGNAL
- USER
- VOLUME
- WORKDIR
CMD
CMD ["./start.sh"]
CMD dùng để truyền một Linux command khi khởi tạo container từ image
VOLUME
VOLUME ["/etc/http"]
VOLUME Tạo một volume
nằm trong folder /var/lib/docker/volumes của docker host và mount với folder chẳng hạn /etc/http khi khởi chạy container
EXPOSE
EXPOSE 80 443
EXPOSE Chỉ định các port sẽ Listen trong container khi khởi chạy container từ image
4. Tạo images httpd với Dockerfile#
Yêu cầu:
- VPS đã cài đặt Docker, nếu bạn chưa cài đặt thì cài đặt theo bài viết này
- Giả định môi trường lý tưởng, các câu lệnh sau đều chạy dưới quyền root
a. Tạo một folder làm việc với Dockerfile
cd ~
mkdir build_image && cd build_image
b. Tạo Dockerfile để build image
touch Dockerfile
Lưu ý: Filename phải là Dockerfile và không có phần mở rộng
c. Nội dung Dockerfile như sau:
FROM centos:centos7
LABEL "image-type"="huy-test"
MAINTAINER huytm
RUN yum update -y
RUN yum install httpd -y
ENV source /var/www/html/
VOLUME ["/var/log/httpd"]
COPY index.html ${source}
COPY start.sh /start.sh
RUN chmod +x /start.sh
CMD ["/start.sh"]
EXPOSE 80
Giải thích:
- FROM centos:centos7 : Build image dựa trên image gốc là centos 7.
- RUN yum update -y và RUN yum install httpd -y : Thực hiện các command của centos để update và cài đặt httpd
- LABEL “image-type”=”huy-test” : Metadata của image có thể có hoặc không.
- MAINTAINER huytm : Tác giả viết Dockerfile để build image có thể có hoặc không.
- ENV source /var/www/html/ : Khai báo một biến môi trường tên là source và có giá trị là /var/www/html/. Biến này sẽ được sử dụng ở bước
COPY index.html ${source}
- COPY index.html ${source} : Copy file index.html từ Dockerhost vào đường dẫn biến – được khai báo ở bước trên.
- COPY start.sh /start.sh : Copy một bash script file vào đường dẫn / để thực hiện một số Linux command khi khởi tạo container từ image này.
- RUN chmod +x /start.sh : Cho phép quyền thực thi đối với script vừa copy từ bước trên.
- CMD [“/start.sh”] : Thực thi script khi khởi chạy container từ image này.
- EXPOSE 80 : Chỉ ra rằng container khi khởi chạy từ image này sẽ LISTEN port 80
- VOLUME [“/var/log/httpd”] : Chỉ định một phân vùng trên Docker host mount với container khi chạy. Ở đây mình mount theo dạng
volume
(Có ba kiểu volume, mình sẽ nói trong các bài viết sau). Mount folder /var/log/httpd của container với volume nằm tại /var/lib/portal/volume/ của Docker host
d. Tạo các file cần thiết bổ trợ cho Dockerfile
Vì ở trên mình có sử dụng COPY để COPY các file script start.sh và file source code index.html nên mình sẽ tạo tiếp hai file này.
cat <<EOF > start.sh
#!/bin/bash
rm -rf /run/httpd/* /tmp/httpd*
exec /usr/sbin/apachectl -DFOREGROUND
EOF
echo "<h1>Hello World</h1>" > index.html
e. Tạo image từ Dockerfile
docker build -t huytm/centos7-httpd .
Đây là toàn bộ log của quá trình build
Sending build context to Docker daemon 4.096kB Step 1/12 : FROM centos:centos7 ---> 1e1148e4cc2c Step 2/12 : LABEL "image-type"="huy-test" ---> Running in 220997b26a05 Removing intermediate container 220997b26a05 ---> 767cb6c0db64 Step 3/12 : MAINTAINER huytm ---> Running in 87547a35ac1f Removing intermediate container 87547a35ac1f ---> 1333a9d9ceed Step 4/12 : RUN yum update -y ---> Running in 66eb8c88d680 Loaded plugins: fastestmirror, ovl Determining fastest mirrors * base: centos-hn.viettelidc.com.vn * extras: centos-hn.viettelidc.com.vn * updates: centos-hn.viettelidc.com.vn Resolving Dependencies --> Running transaction check ---> Package bind-license.noarch 32:9.9.4-72.el7 will be updated ---> Package bind-license.noarch 32:9.9.4-73.el7_6 will be an update ---> Package device-mapper.x86_64 7:1.02.149-10.el7_6.2 will be updated ---> Package device-mapper.x86_64 7:1.02.149-10.el7_6.3 will be an update ---> Package device-mapper-libs.x86_64 7:1.02.149-10.el7_6.2 will be updated ---> Package device-mapper-libs.x86_64 7:1.02.149-10.el7_6.3 will be an update ---> Package glibc.x86_64 0:2.17-260.el7 will be updated ---> Package glibc.x86_64 0:2.17-260.el7_6.3 will be an update ---> Package glibc-common.x86_64 0:2.17-260.el7 will be updated ---> Package glibc-common.x86_64 0:2.17-260.el7_6.3 will be an update ---> Package krb5-libs.x86_64 0:1.15.1-34.el7 will be updated ---> Package krb5-libs.x86_64 0:1.15.1-37.el7_6 will be an update ---> Package nss.x86_64 0:3.36.0-7.el7_5 will be updated ---> Package nss.x86_64 0:3.36.0-7.1.el7_6 will be an update ---> Package nss-sysinit.x86_64 0:3.36.0-7.el7_5 will be updated ---> Package nss-sysinit.x86_64 0:3.36.0-7.1.el7_6 will be an update ---> Package nss-tools.x86_64 0:3.36.0-7.el7_5 will be updated ---> Package nss-tools.x86_64 0:3.36.0-7.1.el7_6 will be an update ---> Package nss-util.x86_64 0:3.36.0-1.el7_5 will be updated ---> Package nss-util.x86_64 0:3.36.0-1.1.el7_6 will be an update ---> Package openldap.x86_64 0:2.4.44-20.el7 will be updated ---> Package openldap.x86_64 0:2.4.44-21.el7_6 will be an update ---> Package systemd.x86_64 0:219-62.el7 will be updated ---> Package systemd.x86_64 0:219-62.el7_6.3 will be an update ---> Package systemd-libs.x86_64 0:219-62.el7 will be updated ---> Package systemd-libs.x86_64 0:219-62.el7_6.3 will be an update ---> Package tzdata.noarch 0:2018g-1.el7 will be updated ---> Package tzdata.noarch 0:2018i-1.el7 will be an update --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Updating: bind-license noarch 32:9.9.4-73.el7_6 updates 87 k device-mapper x86_64 7:1.02.149-10.el7_6.3 updates 292 k device-mapper-libs x86_64 7:1.02.149-10.el7_6.3 updates 320 k glibc x86_64 2.17-260.el7_6.3 updates 3.7 M glibc-common x86_64 2.17-260.el7_6.3 updates 12 M krb5-libs x86_64 1.15.1-37.el7_6 updates 803 k nss x86_64 3.36.0-7.1.el7_6 updates 835 k nss-sysinit x86_64 3.36.0-7.1.el7_6 updates 62 k nss-tools x86_64 3.36.0-7.1.el7_6 updates 515 k nss-util x86_64 3.36.0-1.1.el7_6 updates 78 k openldap x86_64 2.4.44-21.el7_6 updates 356 k systemd x86_64 219-62.el7_6.3 updates 5.1 M systemd-libs x86_64 219-62.el7_6.3 updates 406 k tzdata noarch 2018i-1.el7 updates 490 k Transaction Summary ================================================================================ Upgrade 14 Packages Total download size: 24 M Downloading packages: Delta RPMs disabled because /usr/bin/applydeltarpm not installed. warning: /var/cache/yum/x86_64/7/updates/packages/bind-license-9.9.4-73.el7_6.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY Public key for bind-license-9.9.4-73.el7_6.noarch.rpm is not installed -------------------------------------------------------------------------------- Total 5.4 MB/s | 24 MB 00:04 Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 Importing GPG key 0xF4A80EB5: Userid : "CentOS-7 Key (CentOS 7 Official Signing Key) <[email protected]>" Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5 Package : centos-release-7-6.1810.2.el7.centos.x86_64 (@CentOS) From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 Running transaction check Running transaction test Transaction test succeeded Running transaction Updating : tzdata-2018i-1.el7.noarch 1/28 Updating : glibc-2.17-260.el7_6.3.x86_64 2/28 Updating : glibc-common-2.17-260.el7_6.3.x86_64 3/28 Updating : nss-util-3.36.0-1.1.el7_6.x86_64 4/28 Updating : systemd-libs-219-62.el7_6.3.x86_64 5/28 Updating : systemd-219-62.el7_6.3.x86_64 6/28 Failed to get D-Bus connection: Operation not permitted Updating : 7:device-mapper-1.02.149-10.el7_6.3.x86_64 7/28 Updating : 7:device-mapper-libs-1.02.149-10.el7_6.3.x86_64 8/28 Updating : nss-sysinit-3.36.0-7.1.el7_6.x86_64 9/28 Updating : nss-3.36.0-7.1.el7_6.x86_64 10/28 Updating : nss-tools-3.36.0-7.1.el7_6.x86_64 11/28 Updating : openldap-2.4.44-21.el7_6.x86_64 12/28 Updating : krb5-libs-1.15.1-37.el7_6.x86_64 13/28 Updating : 32:bind-license-9.9.4-73.el7_6.noarch 14/28 Cleanup : 32:bind-license-9.9.4-72.el7.noarch 15/28 Cleanup : openldap-2.4.44-20.el7.x86_64 16/28 Cleanup : nss-tools-3.36.0-7.el7_5.x86_64 17/28 Cleanup : nss-sysinit-3.36.0-7.el7_5.x86_64 18/28 Cleanup : nss-3.36.0-7.el7_5.x86_64 19/28 Cleanup : 7:device-mapper-1.02.149-10.el7_6.2.x86_64 20/28 Cleanup : 7:device-mapper-libs-1.02.149-10.el7_6.2.x86_64 21/28 Cleanup : systemd-219-62.el7.x86_64 22/28 Cleanup : systemd-libs-219-62.el7.x86_64 23/28 Cleanup : nss-util-3.36.0-1.el7_5.x86_64 24/28 Cleanup : krb5-libs-1.15.1-34.el7.x86_64 25/28 Cleanup : glibc-common-2.17-260.el7.x86_64 26/28 Cleanup : glibc-2.17-260.el7.x86_64 27/28 Cleanup : tzdata-2018g-1.el7.noarch 28/28 Verifying : systemd-libs-219-62.el7_6.3.x86_64 1/28 Verifying : nss-tools-3.36.0-7.1.el7_6.x86_64 2/28 Verifying : systemd-219-62.el7_6.3.x86_64 3/28 Verifying : 32:bind-license-9.9.4-73.el7_6.noarch 4/28 Verifying : nss-util-3.36.0-1.1.el7_6.x86_64 5/28 Verifying : 7:device-mapper-libs-1.02.149-10.el7_6.3.x86_64 6/28 Verifying : krb5-libs-1.15.1-37.el7_6.x86_64 7/28 Verifying : nss-sysinit-3.36.0-7.1.el7_6.x86_64 8/28 Verifying : nss-3.36.0-7.1.el7_6.x86_64 9/28 Verifying : tzdata-2018i-1.el7.noarch 10/28 Verifying : glibc-2.17-260.el7_6.3.x86_64 11/28 Verifying : glibc-common-2.17-260.el7_6.3.x86_64 12/28 Verifying : 7:device-mapper-1.02.149-10.el7_6.3.x86_64 13/28 Verifying : openldap-2.4.44-21.el7_6.x86_64 14/28 Verifying : nss-3.36.0-7.el7_5.x86_64 15/28 Verifying : openldap-2.4.44-20.el7.x86_64 16/28 Verifying : nss-util-3.36.0-1.el7_5.x86_64 17/28 Verifying : 7:device-mapper-1.02.149-10.el7_6.2.x86_64 18/28 Verifying : systemd-libs-219-62.el7.x86_64 19/28 Verifying : glibc-common-2.17-260.el7.x86_64 20/28 Verifying : systemd-219-62.el7.x86_64 21/28 Verifying : nss-tools-3.36.0-7.el7_5.x86_64 22/28 Verifying : glibc-2.17-260.el7.x86_64 23/28 Verifying : krb5-libs-1.15.1-34.el7.x86_64 24/28 Verifying : 7:device-mapper-libs-1.02.149-10.el7_6.2.x86_64 25/28 Verifying : 32:bind-license-9.9.4-72.el7.noarch 26/28 Verifying : nss-sysinit-3.36.0-7.el7_5.x86_64 27/28 Verifying : tzdata-2018g-1.el7.noarch 28/28 Updated: bind-license.noarch 32:9.9.4-73.el7_6 device-mapper.x86_64 7:1.02.149-10.el7_6.3 device-mapper-libs.x86_64 7:1.02.149-10.el7_6.3 glibc.x86_64 0:2.17-260.el7_6.3 glibc-common.x86_64 0:2.17-260.el7_6.3 krb5-libs.x86_64 0:1.15.1-37.el7_6 nss.x86_64 0:3.36.0-7.1.el7_6 nss-sysinit.x86_64 0:3.36.0-7.1.el7_6 nss-tools.x86_64 0:3.36.0-7.1.el7_6 nss-util.x86_64 0:3.36.0-1.1.el7_6 openldap.x86_64 0:2.4.44-21.el7_6 systemd.x86_64 0:219-62.el7_6.3 systemd-libs.x86_64 0:219-62.el7_6.3 tzdata.noarch 0:2018i-1.el7 Complete! Removing intermediate container 66eb8c88d680 ---> 7827c1f58d69 Step 5/12 : RUN yum install httpd -y ---> Running in b3b027cccc5b Loaded plugins: fastestmirror, ovl Loading mirror speeds from cached hostfile * base: centos-hn.viettelidc.com.vn * extras: centos-hn.viettelidc.com.vn * updates: centos-hn.viettelidc.com.vn Resolving Dependencies --> Running transaction check ---> Package httpd.x86_64 0:2.4.6-88.el7.centos will be installed --> Processing Dependency: httpd-tools = 2.4.6-88.el7.centos for package: httpd-2.4.6-88.el7.centos.x86_64 --> Processing Dependency: system-logos >= 7.92.1-1 for package: httpd-2.4.6-88.el7.centos.x86_64 --> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-88.el7.centos.x86_64 --> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-88.el7.centos.x86_64 --> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-88.el7.centos.x86_64 --> Running transaction check ---> Package apr.x86_64 0:1.4.8-3.el7_4.1 will be installed ---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed ---> Package centos-logos.noarch 0:70.0.6-3.el7.centos will be installed ---> Package httpd-tools.x86_64 0:2.4.6-88.el7.centos will be installed ---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: httpd x86_64 2.4.6-88.el7.centos base 2.7 M Installing for dependencies: apr x86_64 1.4.8-3.el7_4.1 base 103 k apr-util x86_64 1.5.2-6.el7 base 92 k centos-logos noarch 70.0.6-3.el7.centos base 21 M httpd-tools x86_64 2.4.6-88.el7.centos base 90 k mailcap noarch 2.1.41-2.el7 base 31 k Transaction Summary ================================================================================ Install 1 Package (+5 Dependent packages) Total download size: 24 M Installed size: 31 M Downloading packages: -------------------------------------------------------------------------------- Total 4.9 MB/s | 24 MB 00:04 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : apr-1.4.8-3.el7_4.1.x86_64 1/6 Installing : apr-util-1.5.2-6.el7.x86_64 2/6 Installing : httpd-tools-2.4.6-88.el7.centos.x86_64 3/6 Installing : centos-logos-70.0.6-3.el7.centos.noarch 4/6 Installing : mailcap-2.1.41-2.el7.noarch 5/6 Installing : httpd-2.4.6-88.el7.centos.x86_64 6/6 Verifying : mailcap-2.1.41-2.el7.noarch 1/6 Verifying : apr-util-1.5.2-6.el7.x86_64 2/6 Verifying : httpd-tools-2.4.6-88.el7.centos.x86_64 3/6 Verifying : httpd-2.4.6-88.el7.centos.x86_64 4/6 Verifying : apr-1.4.8-3.el7_4.1.x86_64 5/6 Verifying : centos-logos-70.0.6-3.el7.centos.noarch 6/6 Installed: httpd.x86_64 0:2.4.6-88.el7.centos Dependency Installed: apr.x86_64 0:1.4.8-3.el7_4.1 apr-util.x86_64 0:1.5.2-6.el7 centos-logos.noarch 0:70.0.6-3.el7.centos httpd-tools.x86_64 0:2.4.6-88.el7.centos mailcap.noarch 0:2.1.41-2.el7 Complete! Removing intermediate container b3b027cccc5b ---> ceaa2c4dc611 Step 6/12 : ENV source /var/www/html/ ---> Running in 0dae76377156 Removing intermediate container 0dae76377156 ---> 3d6abf9b4e60 Step 7/12 : VOLUME ["/var/log/httpd"] ---> Running in a5851687922f Removing intermediate container a5851687922f ---> 5bedc77aef79 Step 8/12 : COPY index.html ${source} ---> 233244890ca7 Step 9/12 : COPY start.sh /start.sh ---> dde006532a47 Step 10/12 : RUN chmod +x /start.sh ---> Running in e639aca6cafe Removing intermediate container e639aca6cafe ---> eeb387dba352 Step 11/12 : CMD ["/start.sh"] ---> Running in 2ae88e34619b Removing intermediate container 2ae88e34619b ---> 1e9cab6ef65f Step 12/12 : EXPOSE 80 ---> Running in e697bcee7199 Removing intermediate container e697bcee7199 ---> 97ba637ff1df Successfully built 97ba637ff1df Successfully tagged huytm/centos7-httpd:latest
f. Kiểm tra lại image vừa build
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
huytm/centos7-httpd latest 97ba637ff1df 4 minutes ago 457MB
centos centos7 1e1148e4cc2c 2 months ago 202MB
g. Chạy container với image vừa build
docker run -itd -p 9000:80 --name huytm huytm/centos7-httpd
h. Truy cập vào apache của container
Truy cập vào apache của container theo địa chỉ
http://<Docker_host_ip>:9000
Tổng kết#
Như vậy, trong bài viết này mình đã giới thiệu cách build một image từ Dockerfile cũng như giải thích các command trong cấu trúc file của Dockerfile.
Ở bài viết tiếp theo mình sẽ viết về các command cở của Docker, để thao tác với container.