Cách tạo Docker Images bằng Dockerfile trên Ubuntu 22.04 LTS

theanh

Administrator
Nhân viên
Docker là một công nghệ ảo hóa cấp hệ điều hành chủ yếu hướng đến các nhà phát triển và quản trị viên hệ thống. Docker giúp việc xây dựng và triển khai các ứng dụng trong môi trường biệt lập trở nên dễ dàng hơn.

Dockerfile là một tập lệnh chứa các tập hợp lệnh và hướng dẫn được thực thi tự động lần lượt trong môi trường Docker để tạo một hình ảnh Docker mới.

Hướng dẫn này sẽ chỉ cho bạn cách tạo hình ảnh Docker của riêng mình bằng Dockerfile. Chúng tôi giải thích chi tiết cách tạo hình ảnh Docker của riêng bạn bằng Dockerfile.

Điều kiện tiên quyết

Đối với hướng dẫn này, chúng tôi sẽ sử dụng Ubuntu 22.04 với 1GB RAM, 25GB dung lượng đĩa trống và 2 CPU. Ngoài ra, chúng tôi sẽ sử dụng Ubuntu 22.04 làm hình ảnh cơ sở để xây dựng hình ảnh Docker tùy chỉnh.

Giới thiệu về lệnh Dockerfile​

Dockerfile là một tập lệnh chứa tất cả các lệnh để xây dựng hình ảnh Docker. Dockerfile chứa tất cả các hướng dẫn sẽ được sử dụng để tạo hình ảnh Docker bằng lệnh 'docker build'.

Trước khi tạo Dockerfile đầu tiên, bạn nên làm quen với hướng dẫn Dockerfile. Dưới đây là một số hướng dẫn Dockerfile mà bạn phải biết.

TỪ

Đặt hình ảnh cơ sở cho hình ảnh mới mà bạn muốn tạo. Lệnh FROM sẽ khởi tạo giai đoạn xây dựng mới và phải nằm ở đầu Dockerfile.

LABEL

Với lệnh này, bạn có thể thêm thông tin bổ sung về hình ảnh Docker của mình, chẳng hạn như phiên bản, mô tả, người bảo trì, v.v. Lệnh LABEL là một cặp khóa-giá trị cho phép bạn thêm nhiều nhãn và giá trị nhiều dòng.

RUN

Lệnh này được sử dụng để thực thi lệnh trong quá trình xây dựng hình ảnh Docker. Bạn có thể cài đặt các gói bổ sung cần thiết cho hình ảnh Docker của mình.

ADD

Lệnh ADD được sử dụng để sao chép các tệp, thư mục hoặc tệp từ xa từ URL đến hình ảnh Docker của bạn, từ 'src' đến đường dẫn tuyệt đối 'dest'. Ngoài ra, bạn có thể thiết lập quyền sở hữu mặc định cho tệp của mình.

ENV

Lệnh ENV định nghĩa một biến môi trường có thể được sử dụng trong giai đoạn xây dựng và cũng có thể được thay thế trực tuyến trong nhiều giai đoạn.

CMD

Lệnh CMD định nghĩa lệnh mặc định để thực thi khi chạy vùng chứa. Và Dockerfile chỉ được chứa một lệnh CMD và nếu có nhiều lệnh CMD, lệnh CMD cuối cùng sẽ được chạy.

EXPOSE

Lệnh này sẽ hiển thị cổng vùng chứa trên các cổng mạng cụ thể khi chạy. Giao thức mặc định được hiển thị là TCP, nhưng bạn có thể chỉ định TCP hoặc UDP.

ARG

Lệnh ARG được sử dụng để xác định một biến mà người dùng có thể truyền vào tại thời điểm dựng. Bạn có thể sử dụng lệnh này trong lệnh 'build command' của docker trong thời gian dựng bằng tùy chọn '--build-arg variable=value' và có thể truyền qua Dockerfile. Ngoài ra, bạn có thể sử dụng nhiều ARG tại Dockerfile.

ENTRYPOINT

Lệnh ENTRYPOINT được sử dụng để xác định lệnh đầu tiên và lệnh mặc định sẽ được thực thi khi container đang chạy. Xác định lệnh để khởi động ứng dụng của bạn bằng lệnh ENTRYPOINT.

WORKDIR

Lệnh WORKDIR được sử dụng để xác định thư mục làm việc mặc định của hình ảnh Docker của bạn. Các lệnh RUN, CMD, ENTRYPOINT và ADD tuân theo lệnh WORKDIR. Bạn có thể thêm nhiều lệnh WORKDIR vào Dockerfile của mình và nếu không có, lệnh đó sẽ được tự động tạo.

USER

Lệnh USER được sử dụng để xác định người dùng hoặc gid mặc định khi chạy hình ảnh. RUN, CMD và ENTRYPOINT tuân theo lệnh USER trong Dockerfile.

VOLUME

Lệnh VOLUME được sử dụng để cho phép truy cập/liên kết thư mục giữa vùng chứa và máy chủ.

Bây giờ, chúng ta hãy bắt đầu tạo Dockerfile đầu tiên.

Bước 1 - Cài đặt Docker trên Ubuntu 22.04​

Trước khi tạo Dockerfile, chúng ta sẽ cài đặt Docker vào hệ thống Ubuntu 22.04 của mình, có sẵn theo mặc định trong kho lưu trữ Ubuntu.

Cập nhật tất cả danh sách các gói trên kho lưu trữ Ubuntu và cài đặt Docker bằng lệnh apt bên dưới.
Mã:
sudo apt update
sudo apt install docker.io
Sau khi hoàn tất quá trình cài đặt, hãy khởi động dịch vụ Docker và thêm nó vào hệ thống khởi động.
Mã:
systemctl start docker
systemctl enable docker
Bây giờ hãy kiểm tra dịch vụ Docker bằng lệnh bên dưới.
Mã:
systemctl status docker
Dịch vụ Docker đang hoạt động trên Ubuntu 22.04.


data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%22750%22%20height=%22306%22%3E%3C/svg%3E


Tiếp theo, chạy lệnh docker bên dưới để đảm bảo cài đặt chính xác.
Mã:
docker run hello-world
Dưới đây là kết quả bạn sẽ get.
Mã:
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 (amd64)
3. The Docker daemon created a new container from that image which runs the
 executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
 to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
[URL=https://docs.docker.com/get-started/?utm_source=diendancongnghe.com]https://docs.docker.com/get-started/[/URL]
Như bạn thấy, bạn nhận được thông báo Hello World từ Docker và quá trình cài đặt Docker trên Ubuntu 22.04 đã hoàn tất thành công.

Bước 2 - Tạo Dockerfile và các cấu hình khác​

Trong bước này, chúng tôi sẽ chỉ cho bạn cách xây dựng hình ảnh Docker tùy chỉnh cho ứng dụng của bạn bằng Dockerfile. Chúng tôi sẽ tạo một hình ảnh Docker tùy chỉnh mới dựa trên hình ảnh Ubuntu 22.04, cho các dịch vụ PHP-FPM và Nginx, sau đó chạy vùng chứa mới bằng một tập lệnh phpinfo đơn giản.

Đầu tiên, hãy tạo một thư mục dự án mới và tạo một Dockerfile trống.
Mã:
mkdir -p nginx-image
cd nginx-image/
touch Dockerfile
Bây giờ hãy chỉnh sửa tập lệnh 'Dockerfile' bằng trình chỉnh sửa của riêng bạn (trong ví dụ này, chúng tôi đang sử dụng nano).
Mã:
nano Dockerfile
Trên cùng của dòng, thêm hình ảnh cơ sở Ubuntu 22.04 bằng cách sử dụng lệnh FROM như bên dưới.
Mã:
# Download base image ubuntu 22.04
FROM ubuntu:22.04
Bây giờ thêm thông tin chi tiết về hình ảnh tùy chỉnh bằng cách sử dụng NHÃN hướng dẫn.
Mã:
# LABEL about the custom image
LABEL maintainer="[emailprotected]"
LABEL version="0.1"
LABEL description="This is a custom Docker Image for PHP-FPM and Nginx."
Chúng tôi sẽ bỏ qua bất kỳ bước tương tác nào sau khi cài đặt để cài đặt các gói apt bằng cách sử dụng biến môi trường 'DEBIAN_FRONTEND=noninteractive'.
Mã:
# Disable Prompt During Packages Installation
ARG DEBIAN_FRONTEND=noninteractive
Tiếp theo, hãy chạy lệnh 'apt update' trước khi cài đặt bất kỳ các gói.
Mã:
# Update Ubuntu Software repository
RUN apt update
Bây giờ hãy cài đặt các gói Nginx, PHP-FPM và Supervisor. Sau khi hoàn tất cài đặt, hãy xóa tất cả bộ đệm gói để giảm kích thước của ảnh tùy chỉnh.
Mã:
# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt install -y nginx php-fpm supervisor
RUN rm -rf /var/lib/apt/lists/*
RUN apt clean
Xác định một biến môi trường mới có thể được truyền vào ảnh tùy chỉnh.
Mã:
# Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/8.1/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.conf
Bây giờ hãy sao chép cấu hình mặc định của Nginx vào biến 'nginx_vhost', thay thế cấu hình PHP 'cgi.fix_pathinfo=1' bằng 'cgi.fix_pathinfo=0' trên tệp cấu hình php.ini, sau đó thêm tùy chọn 'daemon off' vào biến 'nginx_conf' mặc định.
Mã:
# Enable PHP-fpm on nginx virtualhost configuration
COPY default ${nginx_vhost}
RUN sed -i -e 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' ${php_conf} && echo "\ndaemon off;" >> ${nginx_conf}
Sao chép cấu hình giám sát tùy chỉnh vào biến 'supervisor_conf'.
Mã:
#Copy supervisor configuration
COPY supervisord.conf ${supervisor_conf}
Tạo một thư mục mới cho tệp sock PHP-FPM, thay đổi quyền sở hữu của thư mục web-root '/var/www/html' và thư mục PHP-FPM '/run/php' cho người dùng mặc định 'www-data'.
Mã:
RUN mkdir -p /run/php
RUN chown -R www-data:www-data /var/www/html
RUN chown -R www-data:www-data /run/php
Xác định ổ đĩa cho hình ảnh tùy chỉnh để chúng ta có thể gắn tất cả các thư mục đó vào máy chủ.
Mã:
# Volume configuration
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]
Bây giờ hãy thêm tập lệnh 'start.sh' và xác định lệnh chứa mặc định bằng cách sử dụng CMD hướng dẫn như bên dưới.
Mã:
# Copy start.sh script and define default command for the container
COPY start.sh /start.sh
CMD ["./start.sh"]
Và cuối cùng, mở các cổng HTTP và HTTPS mặc định trên container bằng lệnh EXPOSE.
Mã:
# Expose Port for the Application 
EXPOSE 80 443
Lưu và đóng.

Dưới đây là tập lệnh Dockerfile hoàn chỉnh mà chúng ta vừa đã tạo.
Mã:
# Download base image ubuntu 22.04
FROM ubuntu:22.04

# LABEL about the custom image
LABEL maintainer="[emailprotected]"
LABEL version="0.1"
LABEL description="This is a custom Docker Image for PHP-FPM and Nginx."

# Disable Prompt During Packages Installation
ARG DEBIAN_FRONTEND=noninteractive

# Update Ubuntu Software repository
RUN apt update
RUN apt upgrade -y

# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt install -y nginx php-fpm supervisor
RUN rm -rf /var/lib/apt/lists/*
RUN apt clean
 
# Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/8.1/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.conf

# Enable PHP-fpm on nginx virtualhost configuration
COPY default ${nginx_vhost}
RUN sed -i -e 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' ${php_conf} && echo "\ndaemon off;" >> ${nginx_conf}
 
# Copy supervisor configuration
COPY supervisord.conf ${supervisor_conf}

RUN mkdir -p /run/php
RUN chown -R www-data:www-data /var/www/html
RUN chown -R www-data:www-data /run/php
 
# Volume configuration
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]

# Copy start.sh script and define default command for the container
COPY start.sh /start.sh
CMD ["./start.sh"]

# Expose Port for the Application 
EXPOSE 80 443
Tiếp theo, chúng ta sẽ tạo cấu hình bổ sung cho Nginx, supervisord và tập lệnh start.sh.

Cấu hình máy chủ ảo Nginx 'mặc định' sẽ chứa phần dành cho PHP-FPM. Trên thực tế, bạn có thể chạy tập lệnh PHP bằng cách sử dụng hình ảnh Tùy chỉnh mà không cần bất kỳ thay đổi nào.

Tạo cấu hình máy chủ ảo 'mặc định' Nginx mới bằng trình chỉnh sửa của bạn.
Mã:
nano default
Dán cấu hình sau vào đó.
Mã:
server {
 listen 80 default_server;

 root /var/www/html;
 index index.html index.htm index.nginx-debian.html;

 server_name _;

 location / {
 try_files $uri $uri/ =404;
 }

 location ~ \.php$ {
 include snippets/fastcgi-php.conf;
 fastcgi_pass unix:/run/php/php8.1-fpm.sock;
 }
}
Lưu và đóng.

Tiếp theo, chúng ta sẽ tạo 'supervisrod.conf' cấu hình, chứa cả chương trình Nginx và PHP-FPM sẽ được chạy tự động.

Tạo tệp 'supervisrod.conf' bằng trình soạn thảo của bạn.
Mã:
nano supervisord.conf
Dán cấu hình sau vào đó.
Mã:
[unix_http_server]
file=/dev/shm/supervisor.sock ; (the path to the socket file)

[supervisord]
logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
user=root ;

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///dev/shm/supervisor.sock ; use a unix:// URL for a unix socket

[include]
files = /etc/supervisor/conf.d/*.conf

[program:php-fpm8.1]
command=/usr/sbin/php-fpm8.1 -F
numprocs=1
autostart=true
autorestart=true

[program:nginx]
command=/usr/sbin/nginx
numprocs=1
autostart=true
autorestart=true
Lưu và đóng.

Bây giờ, hãy tạo tập lệnh 'start.sh' bằng trình soạn thảo có chứa lệnh supervisord để bắt đầu.
Mã:
nano start.sh
Dán cấu hình sau vào đó.
Mã:
#!/bin/sh
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
Lưu và đóng.

Tạo tập lệnh 'start.sh' có thể thực thi.
Mã:
chmod +x start.sh
Kết quả là, tất cả cấu hình cho hình ảnh Docker tùy chỉnh của chúng tôi đã được tạo, bên dưới là tất cả các cấu hình chúng tôi đã tạo.
Mã:
ls -la
Chúng tôi đã sẵn sàng tạo một hình ảnh tùy chỉnh mới dựa trên các cấu hình này ngay bây giờ.


data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%22672%22%20height=%22222%22%3E%3C/svg%3E

Bước 3 - Xây dựng tùy chỉnh mới và chạy container mới​

Để tạo hình ảnh tùy chỉnh Docker, hãy vào thư mục dự án 'nginx-image' và chạy lệnh 'docker build' như bên dưới.
Mã:
docker build -t nginx-image .
Lệnh sẽ tải xuống hình ảnh cơ sở Ubuntu 22.04 và tạo một hình ảnh tùy chỉnh mới có tên 'nginx-image.

Sau khi hoàn tất toàn bộ quá trình, hãy kiểm tra danh sách hình ảnh Docker khả dụng trên hệ thống của bạn bằng lệnh sau.
Mã:
docker image ls
Dưới đây là kết quả bạn sẽ lấy.


data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%22750%22%20height=%22179%22%3E%3C/svg%3E


Như có thể thấy, hình ảnh Docker tùy chỉnh mới 'nginx-image' đã được tạo.

Tiếp theo, chúng ta sẽ chạy vùng chứa Docker mới dựa trên 'nginx-image'.

Trên máy cục bộ của bạn, hãy tạo một thư mục mới có tên '/var/webroot' sẽ được sử dụng để lưu trữ tất cả các trang web files.
Mã:
mkdir -p /var/webroot
Bây giờ hãy tạo một container mới có tên là test-container bằng lệnh docker run bên dưới.
Mã:
docker run -d -v /var/webroot:/var/www/html -p 8080:80 --name test-container nginx-image
Lưu ý:
  • --name test-container nginx-image = Chúng tôi tạo một container mới có tên là 'test-container', dựa trên docker image 'nginx-image'.
  • -p 8080:80 = container test-container đang chạy trên cổng 8080 trên máy chủ.
  • -v /var/webroot:/var/www/html = thư mục /var/webroot trên máy chủ, hãy viết lại thư mục /var/www/html trên container.
Sau đó, hãy kiểm tra tất cả các container đang chạy trên hệ thống của bạn bằng lệnh sau.
Mã:
docker ps
Dưới đây là kết quả bạn sẽ nhận được.


data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%22750%22%20height=%22188%22%3E%3C/svg%3E


Kết quả là, container mới có tên 'test-container' dựa trên 'nginx-image' và hiển thị cổng 8080 đã hoạt động.

Bước 4 - Kiểm tra​

Để đảm bảo container đang chạy đúng cách, chúng tôi sẽ tạo một tệp index.html và phpinfo mới trên thư mục gốc '/webroot' của máy chủ. Bởi vì thư mục '/var/webroot' được gắn vào thư mục chứa '/var/www/html'.

Tạo tệp index.html trên thư mục '/webroot' bằng lệnh sau.
Mã:
echo '[HEADING=1]Nginx and PHP-FPM 8.1 inside Docker Container with Ubuntu 22.04 Base Image[/HEADING]' > /var/webroot/index.html
Bây giờ hãy thử truy cập vào vùng chứa của bạn bằng lệnh curl trên cổng 8080.
Mã:
curl server-ip:8080
curl -I server-ip:8080
Kết quả là bạn sẽ nhận được trang index.html mặc định mà chúng ta vừa tạo.


data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%22750%22%20height=%22311%22%3E%3C/svg%3E


Tiếp theo, tạo một tệp PHP mới 'info.php' trên thư mục '/webroot' để đảm bảo rằng dịch vụ PHP-FPM đang chạy.

Tạo tệp 'info.php' bằng lệnh sau.
Mã:
echo '' > /var/webroot/info.php
Tiếp theo, mở trình duyệt web của bạn và nhập địa chỉ IP máy chủ của bạn với cổng '8080' theo sau là đường dẫn của tệp 'info.php'.


Bây giờ bạn sẽ nhận được trang phpinfo như bên dưới.


data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%22750%22%20height=%22423%22%3E%3C/svg%3E


Như có thể thấy, 'test-container' đã tải thành công tập lệnh PHP.

Và kết quả là chúng tôi đã tạo thành công một hình ảnh Docker tùy chỉnh mới và chạy container mới dựa trên nó mà không có bất kỳ lỗi nào.
 
Back
Bên trên