4.2. Docker#
4.2.1. Khái niệm cơ bản#
Tìm hiểu về docker và các khái niệm
1. Docker Image
Một Docker Image là một read-only
template dùng để tạo ra các containers. Image được cấu tạo theo dạng layer và tất cả các layer đều là read-only
. Một image có thể được tạo ra dựa trên một image khác với một số tùy chỉnh bổ sung. Nói ngắn gọn, Docker Image là nơi lưu trữ các cài đặt môi trường như OS, package, phần mềm cần chạy, …
Từ 1 image chúng ta có thể tạo ra nhiều containers với môi trường bên trong giống hệt nhau.
Trong Image có thể chứa: OS (Ubuntu,…), Packages (Git, …) hoặc các ứng dụng phần mềm khác.
2. Docker File
Dockerfile là một file dạng text không có phần đuôi mở rộng, chứa các đặc tả về một trường thực thi phần mềm, cấu trúc cho Docker image. Từ những câu lệnh đó, Docker sẽ build ra Docker image (thường có dung lượng nhỏ từ vài MB đến lớn vài GB).
3. Docker Container
Docker Container được tạo ra từ Docker Image, là nơi chứa mọi thứ cần thiết để có thể chạy ứng dụng. Là ảo hóa nhưng Container lại rất nhẹ, có thể coi như là một process của hệ thống. Chỉ mất vài giây để start
, stop
hoặc restart
một Container. Với một máy chủ vật lý, thay vì chạy được vài cái máy ảo truyền thống thì ta có thể chạy vài chục, thậm chí vài trăm cái Docker Container.
Các trạng thái có thể có:
run
started
stopped
moved
deleted
4. Docker Network
Docker network có nhiệm vụ cung cấp private network (VLAN) để các container trên một host có thể liên lạc được với nhau, hoặc các container trên nhiều hosts có thể liên lạc được với nhau (multi-host networking).
5. Docker Volume
Docker volume là cơ chế tạo và sử dụng dữ liệu của docker, có nhiệm vụ lưu trữ dữ liệu độc lập với vòng đời của container.
Có 3 trường hợp sử dụng Docker Volume:
Giữ lại dữ liệu khi một Container bị xóa.
Để chia sẻ dữ liệu giữa máy chủ vật lý và Docker Container.
Chia sẻ dữ liệu giữa các Docker Container.
6. Docker Hub
Nếu bạn là developer thì chắc hẳn bạn đã quen với công cụ github dùng để upload code của mình lên đó, hiểu đơn giản thì Docker hub cũng tương tự như github nhưng dành cho DockerFile, Docker Images. Ở đây có những DockerFile, Images của người dùng cũng như những bản chính thức từ các nhà phát triển lớn như Google, Oracle, Microsoft, …
Ngoài ra còn có Docker Hub cho phép quản lý các image với những câu lệnh giống như Github như push, pull… để bạn có thể quản lý dễ dàng image của mình.
7. Docker Registry Nơi lưu trữ Docker image. Docker Hub là một registry công khai mà bất cứ ai cũng có thể sử dụng và Docker được cấu hình để tìm kiếm image trên Docker Hub theo mặc định. Bạn thậm chí có thể chạy registry riêng của mình. Có hai loại registry là public hoặc private registry.
8. Docker Compose
Docker compose là công cụ dùng để định nghĩa và run multi-container
cho Docker application. Với compose bạn sử dụng file YAML
để config các services cho application của bạn. Sau đó dùng command để create
và run
từ những config đó.
Sử dụng cũng khá đơn giản chỉ với ba bước:
Khai báo app’s environment trong Dockerfile.
Khai báo các services cần thiết để chạy application trong file
docker-compose.yml
.Run
docker-compose up
để start và run app.
4.2.2. Các câu lệnh cơ bản#
4.2.2.1. Docker Initial#
4.2.2.1.1. Docker authen#
docker login
4.2.2.1.2. Initial template docker project#
Docker cung cấp câu lệnh đơn giản để khởi tạo docker project theo config
docker init
4.2.2.2. Image Command#
4.2.2.2.1. Search & Pull & Push image#
Search Image
docker search <keyword>
: search thông tin các image theo keyword có trên docker hub
docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 13970 [OK]
mariadb MariaDB Server is a high performing open sou… 5325 [OK]
phpmyadmin phpMyAdmin - A web interface for MySQL and M… 766 [OK]
percona Percona Server is a fork of the MySQL relati… 602 [OK]
databack/mysql-backup Back up mysql databases to... anywhere 82
bitnami/mysql Bitnami MySQL Docker Image 80 [OK]
linuxserver/mysql-workbench 48
ubuntu/mysql MySQL open source fast, stable, multi-thread… 43
linuxserver/mysql A Mysql container, brought to you by LinuxSe… 38
circleci/mysql MySQL is a widely used, open-source relation… 29
google/mysql MySQL server for Google Compute Engine 23 [OK]
rapidfort/mysql RapidFort optimized, hardened image for MySQL 14
Pull Image từ các Hub : mặc định là dockerhub
docker pull
: Lệnh này dùng để tải các image trên docker hub về.
docker pull asia-southeast1-docker.pkg.dev/ext-pinetree-dw/dev-aiml-model/sentiment-fast-api
Push Image lên các Hub : mặc định là dockerhub
docker push
:
docker push asia-southeast1-docker.pkg.dev/ext-pinetree-dw/dev-aiml-model/sentiment-fast-api
4.2.2.2.2. Build image#
docker build
: Lệnh này dùng để build một image từ Dockerfile và Context.
Context ở đây là một tập file được xác đinh bởi đường dẫn hoặc url cụ thể.
Ta có thể sử dụng thêm tham số -t
để gắn nhãn cho image.
`docker build -t your_name_container`
docker build -t datkt98/exam02 .
4.2.2.2.3. List images#
docker images
: Lệnh này dùng để liệt kê các image có trên máy tính
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
datkt98/exam02 latest 324475812f6b 4 seconds ago 887MB
datkt98/exam01 latest 1b3ec0e42e26 21 minutes ago 887MB
python 3 74707af2d4ec 2 days ago 871MB
4.2.2.2.4. Xóa images#
docker rmi <list_image_id>
: Lệnh này dùng để xóa một hoặc nhiều images.
docker rmi -f b4d961f671a2
4.2.2.2.5. Lưu trữ image#
docker save [OPTIONS] IMAGE [IMAGE...]
: save docker image to a tar archive
# using STDOUT
docker save image_name01 > image_name01.tar
# using Write to a file, instead of STDOUT (want to specific output path)
docker save -o image_name01.tar > image_name01
#gzip to smaller file
docker save image_name01:latest | gzip > image_name01.tar.gz
4.2.2.2.6. Load image từ file lưu trữ#
docker load [OPTIONS]
: load docker image from a tar archive or STDIN
# using STDIN
docker load < image_name01.tar.gz
# Read from tar archive file (want to specific input path), instead of STDIN
docker load --input image_name01.tar
4.2.2.3. Container Command#
4.2.2.3.1. Run container#
docker run
: Lệnh này dùng để tạo 1 container với images của bạn, ví dụ để tạo 1 container với image ubuntu đã tải về trước đó, bạn dùng lệnh
`docker run -it ubuntu`
Các option thường dùng với docker run
Trong các lệnh trên có lẽ docker run là lệnh hữu ích nhất và ta sẽ thường sử dụng nhất. Nó sử dụng để tạo container dựa vào một image cụ thể. Có nhiều option có thể sử dụng với docker run.
--detach
,-d
Mặc định docker container chạy thì mọi input, output, lỗi được hiện thị trực tiếp trên màn hình terminal. Tuy nhiên với tùy chọn –detach/-d, container sẽ được chạy ngầm vì vậy mọi output, lỗi sẽ không hiển thị.--entrypoint
Thiết lập hoặc ghi đè các lệnh mặc định khi chạy images. Entrypoint là một tập các lệnh và tham số sẽ chạy đầu tiên khi container được chạy từ image. Bất kỳ câu lệnh và tham số được truyền vào sau docker run sẽ được nối vào entrypoint.--env
,-e
Thiết lập biến môi trường sử dụng cặp (key=value). Nếu ta có biến môi trường trong file ta có thể truền nó vào file bằng tùy chọn –env-file.--ip
Khai báo địa chỉ IP cho container--name
Gắn tên cho container--publish
,-p
|--publish-all
,-P
Do các container của docker được gộp và chạy trong một network riêng nên nó sẽ độc lập với máy chủ mà docker chạy trên đó. Để mở các cổng của network các container và ánh xạ nó với cổng của máy host ta sử dụng tùy chọn –publish, -p. Hoặc sử dụng –publish-all, -P sẽ mở tất cả các cổng của container.docker run --publish 80:80 <image_name> bash
--rm
Tự động xóa container khi nó thoát.--tty
,-t
Cấp một terminal ảo cho container. Tùy chọn này thường được sử dụng với –interactive, -i giúp cho STDIN mở ngay cả khi container chạy ở dạng ngầm.--volume
,-v
Gắn một volume vào một container, cho phép chúng ta thao tác ở container nhưng dữ liệu vẫn được lưu trữ ở máy chủ.docker run --volume /volume_name <image_name> bash
--workdir
,-w
Chỉ định thư mục sẽ làm việc bên trong container. Giả sử ta sẽ làm việc với thư mục app trong dockerdocker run --workdir /app <image_name> bash
Ví dụ 1: Run app
docker run --name con_exam01 datkt98/exam01
hello world
Ví dụ 2: Thay đổi port từ container sang local
Trên app container ta cần sử dụng port 8888
, và ta muốn ánh xạ sang 1 port khác là 9000
trên host
docker run --name con_exam02 -p 9000:8888 datkt98/exam02
Trên host, lúc này ta truy cập http://172.17.0.2:5555
Ví dụ 3: entry tới thư mục trong container
docker run --rm -it --entrypoint bash myimage01
4.2.2.3.2. Run multiple-container (by docker-compose)#
Xem mục docker compose
4.2.2.3.3. List running container#
docker ps
: Lệnh này để liệt kê các container đang chạy
Khi sử dụng với các tham số
-a
/-all
: Liệt kê tất cả các container, kể cả đang chạy hay đã kể thúc-q
/-quiet
: chỉ liệt kê ra id của các container.
Để liệt kệ các container đã tạo trước đó bạn dùng lệnh docker ps -a
docker ps -a
4.2.2.3.4. Stop container#
docker stop <container_id>
: Lệnh này dùng để dừng 1 container đang chạy. Ví dụ như hình bên dưới bạn có container đang chạy với ID là 03a1db578cc3, bạn dùng lệnh docker stop 03a1
docker stop a6e267c
4.2.2.3.5. Start container#
docker start <container_id>
: Để start lại container đã dừng trước đó, bạn dùng lệnh docker start, ví dụ bạn start lại container đã stop phía trên dùng lệnh
docker start 03a1
4.2.2.3.6. Xóa containers#
docker rm
: Lệnh này dùng để xóa 1 or nhiều container đã tạo trước đó, nếu container đang chạy, bạn cần thêm tham số -f
docker rm -f 9978bf498c50
4.2.2.3.7. Execute command#
docker exec
: Lệnh này dùng để chạy 1 lệnh trong container, ví dụ bên dưới là liệt kê các tệp tin, thư mục trong folder root của container
docker exec 03a1 ls -la /root
4.2.2.3.8. View Log#
docker logs
: Lệnh này được sử dụng để hiển thị logs của một container, ta cần phải chỉ rõ container để hiển thị logs thông qua tên của nó. Ngoài cũng có thể sử dụng thêm một số flag như --follow
để giữ việc theo dõi logs.
docker logs --follow <your_name_container>
4.2.2.3.9. List used volumns#
docker volume ls
: Lệnh này dùng để liệt kê ra các volumn mà các container sử dụng, volume là một cơ chế dùng để lưu trữ dữ liệu sinh ra và sử dụng bởi Docker.
docker volume ls
4.2.2.3.10. List network#
docker network ls
: liệt kê tất cả các network có sẵn
docker network ls
4.2.2.3.11. Liên kết network giữa các container#
docker network
: tạo connect vào một network mới. Nó giúp container giao tiếp được với một container khác qua tên thay vì mở cổng IP để giao tiếp trên host.
docker network
4.2.3. Dockerfile#
Câu lệnh tạo file docker
# tạo thư mục
mkdir viblo
# truy cập thư mục
cd viblo
# tại file Dockerfile
touch Dockerfile
# open Dockerfile in VSCode
code Dockerfile
Dockerfile là một file dạng text không có phần đuôi mở rộng, chứa các đặc tả về một trường thực thi phần mềm, cấu trúc cho Docker Image. Từ những câu lệnh đó, Docker sẽ build ra Docker image (thường có dung lượng nhỏ từ vài MB đến lớn vài GB).
Dockerfile chứa tập hợp các lệnh để docker có thể đọc hiểu và thực hiện theo thứ tự để đóng gói thành một image theo yêu cầu người dùng
Lệnh |
Mô tả bằng tiếng Việt |
Cú pháp |
Ví dụ |
---|---|---|---|
FROM |
Tạo một giai đoạn build mới từ một image cơ sở. Là base image để chúng ta tiến hành build một image mới. Command này phải được đặt trên cùng của Dockerfile |
|
|
ARG |
Sử dụng biến trong quá trình build. |
|
|
LABEL |
Thêm metadata cho image. |
|
|
MAINTAINER |
Chỉ định tác giả của image. |
|
|
ENV |
Đặt các biến môi trường. |
|
|
WORKDIR |
Thay đổi thư mục làm việc mặc định trong container. Về sau, tất cả các câu lệnh sẽ chạy từ thư mục này. Phải set |
|
|
COPY |
Sao chép tệp và thư mục. Chỉ thị |
|
|
ADD |
Thêm tệp và thư mục từ nguồn cục bộ hoặc từ xa. |
|
|
RUN |
Thực thi các lệnh trong quá trình build và kết quả của các lệnh này được lưu trữ trong layer của image. |
|
|
EXPOSE |
Chỉ ra các cổng mà ứng dụng lắng nghe. Chỉ thị |
|
|
ENTRYPOINT |
Chỉ định chương trình thực thi mặc định của container. |
|
|
CMD |
Chỉ định lệnh mặc định khi container chạy. |
|
|
HEALTHCHECK |
Kiểm tra tình trạng của container khi khởi động. |
|
|
SHELL |
Đặt shell mặc định của image. |
|
|
USER |
Thiết lập người dùng và nhóm ID. |
|
|
VOLUME |
Tạo các mount điểm volume. Cho phép truy cập / liên kết thư mục giữa các container và máy chủ (host machine). Tạo 1 volume bên ngoài từ host hoặc 1 container khác mà container có thể giao tiếp được. |
|
|
STOPSIGNAL |
Chỉ định tín hiệu hệ thống để thoát container. |
|
|
ONBUILD |
Chỉ định các lệnh sẽ được thực thi khi image được sử dụng. |
|
|
4.2.4. Docker compose#
Docker Compose xây dựng template cho việc run docker image thành container, trong đó có thể run multi-container từ nhiều image cùng lúc.
Docker Compose giúp đơn giản hóa việc quản lý và triển khai các ứng dụng phức tạp với nhiều container. Bằng cách sử dụng tệp cấu hình docker-compose.yml
, bạn có thể định nghĩa rõ ràng các dịch vụ, mạng, và volumes cần thiết cho ứng dụng của mình, giúp cho việc triển khai và quản lý trở nên dễ dàng hơn rất nhiều.
Trường hợp NÊN dùng docker-compose
Docker Compose thường được sử dụng để khởi động nhiều container trên local environment hoặc trên các môi trường tự quản lý (on-premises).
Nó cho phép định nghĩa cấu trúc của các dịch vụ trong tệp
docker-compose.yml
, bao gồm các container chạy từ Docker image (ở đây là từ Artifact Registry), và các yếu tố liên quan như mạng, volume, biến môi trường…Nếu bạn chỉ muốn test hoặc chạy container trên máy cục bộ, bạn có thể sử dụng Docker Compose để pull image từ Artifact Registry và khởi động container.
Mỗi service nên được khởi tạo từ một image riêng, phù hợp với mục đích của từng service trong ứng dụng. Việc này giúp tối ưu hóa hiệu suất, dễ dàng quản lý, cập nhật và mở rộng các thành phần của ứng dụng.
Phân chia vai trò rõ ràng: Mỗi service trong
docker-compose
đại diện cho một phần chức năng độc lập của ứng dụng (ví dụ: service web, service database, service cache,…). Vì vậy, mỗi service nên sử dụng một image khác nhau, được tối ưu hóa cho từng vai trò riêng biệt (VD: web service sử dụng imagenginx
, database service sử dụng imagemysql
).Dễ dàng bảo trì và cập nhật: Nếu mỗi service sử dụng một image riêng, bạn có thể dễ dàng cập nhật từng image độc lập mà không ảnh hưởng tới các service khác. Điều này giúp giảm thiểu rủi ro khi cập nhật hoặc triển khai ứng dụng.
Tối ưu hóa hiệu suất: Mỗi image thường được tối ưu hóa cho một mục đích cụ thể. Ví dụ, image của database sẽ được cấu hình để tối ưu hóa cho việc xử lý dữ liệu, trong khi image của web server sẽ được tối ưu hóa cho việc xử lý HTTP request.
Tăng khả năng tái sử dụng: Sử dụng nhiều image khác nhau sẽ giúp bạn có thể tái sử dụng các image này trong các dự án khác, thay vì phải tạo mới từ đầu.
Trường hợp KHÔNG NÊN dùng docker-compose
Tuy nhiên, Docker Compose không phải là công cụ phù hợp để quản lý các container trong môi trường cloud như Google Cloud, trừ khi bạn đang triển khai trên một máy chủ đơn lẻ hoặc sử dụng Google Compute Engine và tự quản lý các dịch vụ của mình. Khi triển khai trong môi trường đám mây, bạn sẽ cần các công cụ mạnh mẽ hơn để quản lý container, đặc biệt là về tính năng scale, bảo mật, và tích hợp với các dịch vụ khác. —> Sử dụng Terraform
TERRAFORM là công cụ mạnh mẽ hơn cho việc triển khai hạ tầng và container trên môi trường cloud như GCP. Nếu bạn đang tìm cách chạy container trên GCP sau khi đẩy image lên Artifact Registry, Terraform có thể giúp bạn thực hiện điều đó một cách dễ dàng thông qua các dịch vụ như:
Google Kubernetes Engine (GKE): Terraform có thể tạo các cluster Kubernetes trên GKE, và bạn có thể chạy container từ Artifact Registry trên đó.
Cloud Run: Terraform có thể triển khai trực tiếp container lên Google Cloud Run, một dịch vụ không cần quản lý hạ tầng, tự động scale container và tích hợp tốt với Artifact Registry.
4.2.4.1. Cấu trúc Tổng Quan#
VÍ DỤ Triển khai một hệ thống mô hình AI tóm tắt văn bản với Docker Compose, chúng ta sẽ cần xây dựng một giải pháp bao gồm các thành phần chính sau:
Ứng dụng Streamlit: Để tạo giao diện người dùng tương tác cho người dùng nhập văn bản và xem bản tóm tắt.
Mô hình AI: Dịch vụ chạy mô hình tóm tắt văn bản.
Cơ sở dữ liệu: Để lưu trữ các bản tóm tắt và văn bản gốc.
SOURCE CODE
Streamlit App (app.py): Chạy ứng dụng giao diện người dùng.
Streamlit App (app.py)
import streamlit as st
import requests
import psycopg2
# Connect to database
conn = psycopg2.connect("dbname=summarizer user=user password=password host=db")
cursor = conn.cursor()
# Streamlit UI
st.title("Text Summarization App")
text = st.text_area("Enter text here:")
if st.button("Summarize"):
if text:
# Call model API
response = requests.post("http://model:5000/summarize", json={"text": text})
summary = response.json().get('summary', '')
# Display summary
st.write("Summary:")
st.write(summary)
# Save to database
cursor.execute("INSERT INTO summaries (original_text, summary) VALUES (%s, %s)", (text, summary))
conn.commit()
st.write("Summary saved to database.")
else:
st.write("Please enter some text.")
Summary Model (model_server.py): Chạy mô hình tóm tắt văn bản, có thể là một API hoặc một dịch vụ mà Streamlit có thể gọi.
Model Server (model_server.py)
from flask import Flask, request, jsonify
from your_model_library import load_model, summarize_text
app = Flask(__name__)
model = load_model('/models/summarization_model')
@app.route('/summarize', methods=['POST'])
def summarize():
data = request.json
text = data.get('text', '')
summary = summarize_text(model, text)
return jsonify({'summary': summary})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Database: Lưu trữ dữ liệu văn bản và bản tóm tắt.
CÁCH HOẠT ĐỘNG
Ứng dụng Streamlit cung cấp giao diện người dùng để nhập văn bản và hiển thị bản tóm tắt.
Khi người dùng nhấn nút “Summarize”, ứng dụng Streamlit gửi yêu cầu đến dịch vụ mô hình (model service) qua API.
Dịch vụ mô hình nhận yêu cầu, xử lý văn bản bằng mô hình tóm tắt và trả kết quả về cho ứng dụng Streamlit.
Ứng dụng Streamlit lưu bản tóm tắt và văn bản gốc vào cơ sở dữ liệu PostgreSQL để lưu trữ.
Cơ sở dữ liệu lưu trữ tất cả các bản tóm tắt và văn bản gốc.
4.2.4.2. Cấu trúc tệp docker-compose.yml
#
Tệp docker-compose.yml
sẽ định nghĩa ba dịch vụ: streamlit
, model
, và db
.
version: '3.8' # Phiên bản của Docker Compose
services: # Các dịch vụ (service) được định nghĩa ở đây
streamlit: # Tên của service
image: streamlit/streamlit:latest # docker image của service
ports:
- "8501:8501"
volumes:
- ./streamlit_app:/app
working_dir: /app # Thư mục làm việc bên trong container
command: streamlit run app.py # Lệnh chạy trong container
depends_on: # Service này phụ thuộc vào những service khác, đảm bảo các service khác được khởi động trước
- model
- db
environment: # Các biến môi trường
- MODEL_API_URL=http://model:5000
- DATABASE_URL=postgresql://user:password@db:5432/summarizer
model:
image: yourmodelimage:latest
container_name: ai_model_container # Tên container (không bắt buộc)
build: # sử dụng khi image là base image và cần build tiếp thông qua dockerfile
context: . # Thư mục chứa Dockerfile
dockerfile: Dockerfile # Tên Dockerfile nếu không phải mặc định
ports: # Mapping cổng host : container
- "5000:5000"
environment:
- MODEL_PATH=/models/summarization_model
volumes: # Kết nối giữa thư mục trong container và hệ thống file host
- ./model:/models
command: python model_server.py
expose:
- "5000"
db:
image: postgres:latest
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: summarizer
volumes:
- db_data:/var/lib/postgresql/data
volumes: # Khai báo các volume nếu cần
db_data:
Streamlit Service
Image: Sử dụng image của Streamlit. Bạn cần tạo một Dockerfile cho Streamlit hoặc sử dụng một image đã có sẵn.
Ports: Ánh xạ cổng 8501 của container đến cổng 8501 của máy chủ để bạn có thể truy cập ứng dụng Streamlit qua
http://localhost:8501
.Volumes: Liên kết thư mục chứa mã nguồn Streamlit (
./streamlit_app
) với thư mục/app
trong container.Working Directory: Đặt thư mục làm việc trong container thành
/app
.Command: Chạy ứng dụng Streamlit từ tệp
app.py
.Depends On: Đảm bảo dịch vụ
model
vàdb
đã được khởi động trước khi Streamlit chạy.Environment:
MODEL_API_URL
: URL của dịch vụ mô hình, dùng để Streamlit gọi API mô hình.DATABASE_URL
: URL kết nối đến cơ sở dữ liệu PostgreSQL.
Model Service
Image: Sử dụng image cho mô hình AI của bạn (
yourmodelimage:latest
). Bạn cần xây dựng image này từ Dockerfile mà bạn tạo cho dịch vụ mô hình.Ports: Ánh xạ cổng 5000 của container đến cổng 5000 của máy chủ để mô hình có thể nhận các yêu cầu API.
Volumes: Liên kết thư mục chứa mã nguồn mô hình (
./model
) với thư mục/models
trong container.Command: Chạy mô hình từ tệp
model_server.py
. Bạn có thể sử dụng Flask hoặc FastAPI để triển khai mô hình.Expose: Mở cổng 5000 cho các dịch vụ nội bộ trong mạng Docker.
Database Service
Image: Sử dụng image của PostgreSQL.
Environment: Thiết lập các biến môi trường cần thiết để cấu hình cơ sở dữ liệu.
POSTGRES_USER
: Tên người dùng.POSTGRES_PASSWORD
: Mật khẩu.POSTGRES_DB
: Tên cơ sở dữ liệu.
Volumes: Lưu trữ dữ liệu cơ sở dữ liệu trong volume
db_data
để bảo vệ dữ liệu khỏi bị mất khi container dừng hoặc bị xóa.
4.2.4.3. Docker Compose command#
Khởi động các dịch vụ
docker-compose up
Hoặc để chạy dưới chế độ nền:
docker-compose up -d
Khi bạn sử dụng lệnh docker-compose up
mà không có tùy chọn -d
, Docker sẽ hiển thị logs của tất cả các container trực tiếp trên terminal, và terminal sẽ bị “khóa” cho đến khi bạn dừng ứng dụng bằng cách nhấn Ctrl+C
.
Các container sẽ được khởi động trong chế độ nền, nghĩa là:
Bạn không thấy logs xuất hiện trực tiếp trong terminal.
Terminal sẽ trở lại trạng thái sẵn sàng cho bạn nhập các lệnh khác ngay lập tức.
Các container vẫn sẽ chạy phía sau (ở chế độ nền) cho đến khi bạn dừng chúng bằng lệnh
docker-compose down
hoặc một lệnh tương tự.
Tóm lại, chạy dưới chế độ nền giúp bạn quản lý và khởi động nhiều container mà không cần giữ terminal mở liên tục, tiện lợi khi bạn muốn thực hiện các tác vụ khác mà không bị gián đoạn.
Dừng các dịch vụ
docker-compose down
Xem logs của các dịch vụ
docker-compose logs
Xem logs của một dịch vụ cụ thể
docker-compose logs ai_summarizer
Tái khởi động các container sau khi thay đổi cấu hình
docker-compose restart
Xây dựng lại hình ảnh nếu có thay đổi Dockerfile
docker-compose build
Xem trạng thái các dịch vụ đang chạy
docker-compose ps
4.2.5. Optimization#
Kỹ thuật |
Lợi ích |
---|---|
1. Alpine Linux |
Giảm kích thước image |
2. Gộp lệnh RUN |
Giảm số layer |
3. .dockerignore |
Giảm file không cần thiết |
4. Multi-stage Build |
Loại bỏ tool build |
5. Tận dụng cache |
Giảm thời gian build |
6. Xóa cache tạm |
Giảm kích thước image |
7. Distroless/Scratch |
Giảm layer hệ điều hành |
8. Squash Layer |
Gộp layer giảm kích thước |
9. Giảm dependencies |
Giảm dung lượng |
10. Prune image |
Dọn dẹp image cũ |
1. Sử dụng Alpine Linux hoặc Minimal Base Image
Vấn đề: Docker image mặc định từ các hệ điều hành như Ubuntu, Debian có kích thước lớn (~50MB+).
Giải pháp: Dùng Alpine Linux (chỉ ~5MB) hoặc các phiên bản minimal như
python:3.9-slim
,node:18-alpine
.
Ví dụ:
FROM python:3.9-slim
2. Giảm số lượng Layer bằng cách gộp các lệnh
Vấn đề: Mỗi lệnh trong Dockerfile (RUN, COPY, ADD) tạo một layer riêng biệt, làm tăng kích thước image.
Giải pháp: Gộp các lệnh RUN lại với nhau bằng && và sử dụng \ để dễ đọc.
Ví dụ: Giúp giảm số lượng layers, tránh lưu lại cache không cần thiết.
RUN apt-get update && apt-get install -y \
curl \
vim \
&& rm -rf /var/lib/apt/lists/*
3. Sử dụng .dockerignore để loại bỏ file không cần thiết
Vấn đề: Thư mục node_modules, venv, .git, pycache có thể bị copy vào image làm tăng kích thước.
Giải pháp: Tạo file
.dockerignore
để loại trừ chúng, hoặc chỉ copy những file/thư mục cần thiết.
Ví dụ:
.git
__pycache__
node_modules
venv
4. Sử dụng Multi-stage Build
Vấn đề: Các công cụ build như gcc, make, pip không cần thiết khi chạy ứng dụng.
Giải pháp: Sử dụng multi-stage build để chỉ giữ lại những file cần thiết. Giúp loại bỏ tất cả các công cụ không cần thiết khỏi image final.
Ví dụ:
# Stage 1: Build
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# Stage 2: Runtime
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]
5. Caching hiệu quả bằng cách sắp xếp lại Dockerfile
Vấn đề: Nếu bạn thay đổi một file source code nhỏ, Docker phải rebuild lại tất cả từ đầu.
Giải pháp: Copy và cài đặt dependencies trước khi copy toàn bộ source code để tận dụng caching. Nếu chỉ thay đổi code, Docker không cần phải cài lại dependencies.
Ví dụ:
# Copy dependencies trước (tận dụng cache)
COPY requirements.txt .
RUN pip install -r requirements.txt
# Copy source code sau cùng
COPY . .
6. Xóa cache và file tạm sau khi cài đặt
Vấn đề: Các file tạm như
/var/lib/apt/lists/*
,.cache
củapip/node_modules
vẫn tồn tại trong layer.Giải pháp: Xóa cache sau khi cài đặt.
Ví dụ: --no-cache-dir
giúp pip không lưu cache.
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir -r requirements.txt
7. Sử dụng Distroless hoặc Scratch Base Image
Vấn đề: Base image như Alpine vẫn có nhiều file hệ thống không cần thiết.
Giải pháp: Distroless Chỉ giữ lại runtime của ngôn ngữ (Java, Node.js, Python, Go).
Ví dụ:
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
FROM gcr.io/distroless/static
COPY --from=builder /app/myapp /
CMD ["/myapp"]
8. Giảm số lượng Layer bằng Squash hoặc Flatten
Vấn đề: Mỗi layer trong Docker chiếm dung lượng lưu trữ.
Giải pháp:
Sử dụng
docker build --squash
để gộp tất cả layer lại thành một.Sử dụng
docker export
+docker import
để flatten image.
Ví dụ:
docker build --squash -t myapp .
docker save myimage | docker import - myimage-slim
9. Giảm kích thước của dependencies
Python: Dùng –no-cache-dir khi cài package.
RUN pip install --no-cache-dir -r requirements.txt
Node.js: Chỉ cài dependencies cần thiết.
RUN npm install --only=production
Java: Dùng JLink để tạo JRE minimal thay vì full JDK.
10. Dọn dẹp image không sử dụng
Vấn đề: Các image cũ và dangling image làm đầy ổ cứng.
Giải pháp: Dọn dẹp image không sử dụng bằng
docker image prune
ordocker system prune
.