Skip to content

Buổi 3: Docker Containers

🎯 Mục tiêu

  • Quản lý vòng đời container: run, stop, start, rm
  • Sử dụng exec để chạy lệnh trong container đang chạy
  • Đọc logs từ container
  • Hiểu port mappingenvironment variables
  • Biết cách attach/detach container

1. Vòng đời Container

Các trạng thái của container

                    docker create
        ┌──────────────────────────────┐
        │                              ▼
   ┌─────────┐   docker start   ┌──────────┐
   │ Created  │────────────────▶│ Running  │
   └─────────┘                  └────┬─────┘
        ▲                            │
        │                     docker stop │
        │                            │    │ docker kill
        │                            ▼    ▼
        │                       ┌──────────┐
        │     docker restart    │ Stopped  │
        │◀──────────────────────│ (Exited) │
        │                       └────┬─────┘
        │                            │
        │                     docker rm │
        │                            ▼
        │                       ┌──────────┐
        └───────────────────────│ Removed  │
                                └──────────┘

2. Chạy Container (docker run)

Cú pháp cơ bản

bash
docker run [OPTIONS] IMAGE [COMMAND] [ARGS...]

Các cách chạy phổ biến

bash
# Chạy nền (detached)
$ docker run -d --name web nginx

# Chạy tương tác (interactive)
$ docker run -it --name my-ubuntu ubuntu bash

# Chạy và tự xóa khi dừng
$ docker run --rm nginx

# Chạy với port mapping
$ docker run -d -p 8080:80 --name web nginx

# Chạy với environment variables
$ docker run -d -e MYSQL_ROOT_PASSWORD=secret --name db mysql:8

# Chạy với giới hạn tài nguyên
$ docker run -d --memory=512m --cpus=1.0 --name app my-app

Bảng tổng hợp flags quan trọng

FlagViết đầy đủÝ nghĩa
-d--detachChạy nền
-it--interactive --ttyChạy tương tác
-p--publishMap port host:container
-e--envĐặt biến môi trường
-v--volumeMount volume
--name--nameĐặt tên container
--rm--rmTự xóa khi dừng
--restart--restartChính sách restart
-w--workdirThư mục làm việc
--network--networkChọn network

3. Quản lý Container

Liệt kê containers

bash
# Container đang chạy
$ docker ps

# Output:
CONTAINER ID   IMAGE   COMMAND                  CREATED         STATUS         PORTS                  NAMES
a1b2c3d4e5f6   nginx   "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   0.0.0.0:8080->80/tcp   web

# Tất cả containers (kể cả đã dừng)
$ docker ps -a

# Chỉ hiện ID
$ docker ps -q

# Format tùy chỉnh
$ docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}"

Dừng và xóa container

bash
# Dừng container (gửi SIGTERM, chờ 10s, rồi SIGKILL)
$ docker stop web

# Dừng ngay lập tức (SIGKILL)
$ docker kill web

# Khởi động lại container đã dừng
$ docker start web

# Restart container
$ docker restart web

# Xóa container đã dừng
$ docker rm web

# Xóa container đang chạy (force)
$ docker rm -f web

# Xóa tất cả container đã dừng
$ docker container prune

docker stop vs docker kill

docker stopdocker kill
SignalSIGTERM → SIGKILLSIGKILL
Timeout10s mặc địnhNgay lập tức
Graceful✅ App có thể cleanup❌ Bị kill ngay
Dùng khiBình thườngContainer bị treo

4. Exec – Chạy lệnh trong container

Cú pháp

bash
docker exec [OPTIONS] CONTAINER COMMAND [ARGS...]

Ví dụ thực tế

bash
# Mở shell trong container đang chạy
$ docker exec -it web bash

# Chạy lệnh đơn lẻ
$ docker exec web ls /usr/share/nginx/html

# Kiểm tra process
$ docker exec web ps aux

# Xem biến môi trường
$ docker exec web env

# Chạy lệnh với user khác
$ docker exec -u root web whoami

docker run vs docker exec

docker rundocker exec
Tạo container✅ Tạo mới❌ Dùng container có sẵn
Trạng tháiBất kỳ imageContainer phải đang chạy
Use caseKhởi tạoDebug, admin

5. Logs – Xem nhật ký container

bash
# Xem toàn bộ logs
$ docker logs web

# Xem 20 dòng cuối
$ docker logs --tail 20 web

# Theo dõi logs real-time (như tail -f)
$ docker logs -f web

# Logs với timestamp
$ docker logs -t web

# Logs từ thời điểm cụ thể
$ docker logs --since 2h web
$ docker logs --since 2025-01-01T00:00:00 web

# Kết hợp: 50 dòng cuối + real-time
$ docker logs --tail 50 -f web

6. Port Mapping

Cách mapping port

          Host Machine                Container
    ┌────────────────────┐     ┌─────────────────┐
    │                    │     │                  │
    │  localhost:8080 ───┼─────┼──▶  port 80      │
    │                    │     │    (nginx)        │
    │  localhost:3000 ───┼─────┼──▶  port 3000    │
    │                    │     │    (node app)     │
    │  localhost:5432 ───┼─────┼──▶  port 5432    │
    │                    │     │    (postgres)     │
    └────────────────────┘     └─────────────────┘

Các cách map port

bash
# Map port cụ thể: host:container
$ docker run -d -p 8080:80 nginx

# Map nhiều port
$ docker run -d -p 8080:80 -p 8443:443 nginx

# Map port ngẫu nhiên
$ docker run -d -P nginx
# Docker tự chọn port host ngẫu nhiên

# Map chỉ localhost (không public)
$ docker run -d -p 127.0.0.1:8080:80 nginx

# Map UDP
$ docker run -d -p 5353:53/udp dns-server

# Xem port mapping
$ docker port web
80/tcp -> 0.0.0.0:8080

7. Environment Variables

Truyền biến môi trường vào container

bash
# Dùng -e flag
$ docker run -d \
  -e MYSQL_ROOT_PASSWORD=secret \
  -e MYSQL_DATABASE=mydb \
  -e MYSQL_USER=admin \
  --name db mysql:8

# Dùng --env-file
$ docker run -d --env-file .env --name app my-app

# Kiểm tra biến môi trường
$ docker exec db env | grep MYSQL
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=mydb
MYSQL_USER=admin

File .env

env
# .env
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=mydb
MYSQL_USER=admin
MYSQL_PASSWORD=admin123
NODE_ENV=production

8. Inspect & Stats

Xem chi tiết container

bash
# Toàn bộ thông tin container
$ docker inspect web

# Lấy IP address
$ docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web

# Xem mount points
$ docker inspect -f '{{json .Mounts}}' web | jq

# Xem trạng thái
$ docker inspect -f '{{.State.Status}}' web

Theo dõi tài nguyên

bash
# Real-time stats tất cả containers
$ docker stats

# Stats cho container cụ thể
$ docker stats web

# Output:
CONTAINER ID   NAME   CPU %   MEM USAGE / LIMIT    MEM %   NET I/O          BLOCK I/O
a1b2c3d4e5f6   web    0.05%   10.5MiB / 7.77GiB   0.13%   1.2kB / 648B     0B / 0B

🏋️ Bài tập thực hành

Bài 1: Quản lý vòng đời container

  1. Chạy container nginx: docker run -d --name web -p 8080:80 nginx
  2. Kiểm tra: docker ps
  3. Dừng: docker stop web
  4. Kiểm tra: docker ps -a
  5. Khởi động lại: docker start web
  6. Xóa: docker rm -f web

Bài 2: Exec và Logs

  1. Chạy nginx: docker run -d --name web -p 8080:80 nginx
  2. Mở shell: docker exec -it web bash
  3. Sửa trang web: echo "Hello Docker!" > /usr/share/nginx/html/index.html
  4. Thoát: exit
  5. Kiểm tra: curl http://localhost:8080
  6. Xem logs: docker logs web

Bài 3: Environment variables

  1. Chạy MySQL: docker run -d -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=testdb --name db -p 3306:3306 mysql:8
  2. Kết nối: docker exec -it db mysql -uroot -psecret
  3. Kiểm tra database: SHOW DATABASES;
  4. Thoát: exit

Bài 4: Multi-container

  1. Chạy 3 containers nginx trên các port khác nhau (8081, 8082, 8083)
  2. Xem stats: docker stats
  3. Dừng tất cả: docker stop $(docker ps -q)
  4. Xóa tất cả: docker container prune