1. Install Docker
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
sudo apt update
apt-cache policy docker-ce
sudo apt install docker-ce
sudo systemctl status docker
sudo usermod -aG docker ${USER}
newgrp docker
2. Một số lệnh cơ bản
#kiểm tra phiên bản
docker --version
#liệt kê các image
docker images -a
#xóa một image (phải không container nào đang dùng)
docker images rm imageid
#tải về một image (imagename) từ hub.docker.com
docker pull imagename
#liệt kê các container
docker container ls -a
#xóa container
docker container rm containerid
#tạo mới một container
docker run -it imageid
#thoát termial vẫn giữ container đang chạy
CTRL +P, CTRL + Q
#Vào termial container đang chạy
docker container attach containerid
#Chạy container đang dừng
docker container start -i containerid
#Chạy một lệnh trên container đang chạy
docker exec -it containerid command
3. Docker File
Dockerfile là một file văn bản (Text file) dùng để định nghĩa cách tạo ra một Docker image.
Mục đích của Dockerfile
– Tự động hóa việc tạo image
– Quản lý môi trường đồng nhất: mọi môi trường (dev, staging, production) đều giống nhau.
– Dễ chia sẻ và triển khai
– Dễ bảo trì và CI/CD
Cấu trúc cơ bản của một Dockerfile
Ví dụ: Dockerfile Python
From python:3.11-slim
WORKDIR /app
COPY requirement.txt
RUN pip install -r requirement.txt
COPY . .
CMD ["python", "main.py"]
Ví dụ: Dockerfile Nodejs
#1. Dùng image nào FROM: node:20-alpine#2. Đặt thư mục làm việc WORKDIR /app
#3. Sao chép file vào containerCOPY package*.json ./
#4. Cài dependenciesRUN npm install
#5. Copy toàn bộ source code vào containerCOPY . .
#6. Expose cổng mà EXPOSE 3000
#7. Lệnh chạy chínhCMD ["npm", "start"]
Ví dụ: Dockerfile cho Dot.net Core
#Build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORK /src
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o /app
#Runtime staga
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "MyApp.dll"
Ví dụ: Dockerfile cho Golang
#Build stage
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .
#Runtime stage
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/main .
EXPOSE 8080
ENTRYPOINT ["./main"]
Ví dụ: Dockerfile cho Java
my-java-app/
├── Dockerfile
├── pom.xml
└── src/
└── main/
└── java/…
#--- Stage 1: Build JAR file ---
FROM maven:3.9.6-eclipse-temurin-17 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
#--- Stage 2: Run the app ---
FROM eclipse-temurin:17-jdk-jammy
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Một số lệnh liên quan đến Dockerfile
docker build -t <image-name> . #Dấu . là thư mục hiện tại chứa Dockerfile
docker build -t <image-name> /path/to/app #Build image ở một thư mục chỉ định
docker build -t <image-name> -f Dockerfile.dev . #Build image từ Dockerfile.dev
docker build --build-arg VERSION=1.0 -t myapp:1.0 . #Thêm biến môi trường (build ARG)
docker build --no-cache -t myapp . #Không dùng cache khi build
docker build --progress=plan -t myapp . #In log chi tiết khi build
Push image lên Docker Hub
docker build -t docker_hub_user/myapp .
docker push docker_hub_user/myapp
Kiểm tra sau khi build
docker images #Liệt kê các image đã build
docker run myapp #Chạy thử image mới build
docker history myapp #Xem lịch sử build từng lớp
docker run -it --rm myapp sh #Chạy docker và vào shell sh để kiểm tra
4. Docker compose
Docker compose là một công cụ cho việc định nghĩa và khởi chạy nhiều container với docker. Khai bao nhiều container trong cùng một file
– Khai báo app’s enviroment với Dockerfile
– Khai báo các services cần thiết để chạy app trong docker-compose.yml
– Run docker-compose up
Cấu trúc file docker-compose.yml
version: 'x.x'
services:
<service-name>:
image: hoặc build:
ports:
volumes:
environment:
depends_on:
volumes:
<volume-name>:
networks:
<network-name>:
Giải thích từng phần:
version: Phiên bản cú pháp của Docker Compose (3.8 là phổ biến)
services: Tập hợp các container muốn khởi chạy cùng nhau
app: Tên dịch vụ (container) đầu tiên – ứng dụng Java
build: Xây image từ Dockerfile hiện tại
ports: Mở cổng từ máy thật → container (host:container)
volumes: Mount thư mục (host ↔ container)
depends_on: Đảm bảo dịch vụ db khởi động trước dịch vụ app
environment: Biến môi trường truyền vào container
image: Image được kéo từ Docker Hub (ở đây là postgres:15)
volumes: Định nghĩa volume để giữ dữ liệu (nếu không sẽ mất khi container bị xóa)
Ví dụ: docker-compose.yml cho spring boot và postgres
version: '3.8' # phiên bản cú pháp docker-compose
services:
app:
build: .
ports:
- "8080:8080"
volumes:
- .:/app
depends_on:
- db
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydb
- SPRING_DATASOURCE_USERNAME=postgres
- SPRING_DATASOURCE_PASSWORD=123456
db:
image: postgres:15
restart: always
environment:
POSTGRES_DB: mydb
POSTGRES_USER: postgres
POSTGRES_PASSWORD: 123456
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Ví dụ: PHP + MySQL
version: '3.8'
services:
web:
image: php:apache
ports:
- "80:80"
volumes:
- ./src:/var/www/html
depends_on:
- db
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: mydb
Lệnh sử dụng docker-compose
docker-compose up #Tạo & chạy tất cả container
docker-compose up -d #Chạy ở chế độ nền (background)
docker-compose down #Dừng và xóa container + network
docker-compose build #Build lại các image từ Dockerfile
docker-compose logs -f #Xem log toàn bộ dịch vụ
5. Docker swarm
Docker Swarm là công cụ native clustering cho Docker. Cho phép ta có thể gom một số Docker host lại với nhau thành dạng cụm (cluster) và ta có xem nó như một máy chủ Docker ảo (virtual Docker host) duy nhất. Và một Swarm là một cluster của một hoặc nhiều Docker Engine đang chạy. Và Swarm mode cung cấp cho ta các tính năng để quản lý và điều phối cluster.

Swarm: là một cluster của một hoặc nhiều Docker Engine đang run (cụ thể ở đây là các node) trong chế độ Swarm, thay vì phải chạy các container bằng câu lệnh thì ta sẽ thiết lập các services để phân bổ các bản replicas tới các node.
Node: Một node là một máy vật lý hay máy ảo đang run phiên bản Docker Engine trong chế độ Swarm. Node sẽ gồm hai loại: Manager Node và Worker Node.
Manager Node: Là node nhận các define service từ user, nó quản lý và điều phối các task đến các node Worker. Theo mặc định node Manager cũng được coi là node Worker.
Worker Node: là node nhận và thực thi các task từ node Manager.
Service: Một service xác định image của container và số lượng các replicas (bản sao) mong muốn khởi chạy trong swarm.
Task: là một tác vụ mà node worker phải thực hiện. Tác vụ này sẽ do node Manager phân bổ xuống. Một task mang một Docker Container và các lệnh để chạy bên container.
Khởi tạo swarm
docker swarm init --advertise-addr
docker swarm join --token <host>:<port>
docker swarm init --advertise-addr 10.10.1.34
docker swarm join --token SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-1awxwuwd3z9j1z3puu7rcgdbx 10.10.1.34:2377
docker service ls
docker service ps
Tạo network và service trong swarm
docker network create \
--scope=swarm \
--attachable \
-d overlay \
my_network
docker service create \
--name my-web --with-registry-auth --replicas 2 \
--network my_network\
--publish published=8090,target=80,protocol=tcp \
--workdir /app \
my-registry.com/my.web/product:18eb15c9
5. Quản lý docker bằng Portainer
#Deploy portainer trên docker
docker run -d \-p 8000:8000 \-p 9443:9443 \--name portainer \--restart=always \-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data portainer/portainer-ce:2.20.3
Deploy stack trên swarm
$ curl -L https://downloads.portainer.io/portainer-agent-stack.yml -o portainer-agent-stack.yml
$ docker stack deploy --compose-file=portainer-agent-stack.yml portainer
