DDevArchive
Đăng nhập

Docker & containerization: đóng gói ứng dụng

"Chạy được trên máy tôi" là câu nói của thời kỳ đồ đá. Container gói ứng dụng kèm toàn bộ môi trường chạy, nên môi trường dev, test, production giống hệt nhau. Đây là kỹ năng bắt buộc của mọi Junior hiện đại.

Container khác máy ảo thế nào

Máy ảo (VM)Container
KernelMỗi VM một kernel riêngChia sẻ kernel host
NặngGBMB
Khởi độngPhútGiây
Cô lậpMạnhĐủ dùng cho ứng dụng

Dockerfile: công thức đóng gói

// File: Dockerfile
FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --omit=dev

COPY . .
EXPOSE 3000

USER node
CMD ["node", "src/server.js"]
Đừng chạy container bằng root

Container dùng chung kernel với host — nếu bị chiếm quyền mà chạy root là lên thẳng host. Luôn tạo user thường trong image (như USER node ở trên).

Build và chạy

// File: terminal.sh
# Build image từ Dockerfile
docker build -t my-app .

# Chạy container, map cổng 3000 host -> 3000 container
docker run -p 3000:3000 --name my-app my-app

# Liệt kê, log, dừng
docker ps
docker logs my-app
docker stop my-app

docker-compose: nhiều service một lệnh

// File: compose.yaml
services:
  web:
    build: .
    ports: ["3000:3000"]
    environment:
      DATABASE_URL: postgres://app:secret@db:5432/app
    depends_on: [db, redis]

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
    volumes: ["pgdata:/var/lib/postgresql/data"]

  redis:
    image: redis:7-alpine

volumes:
  pgdata:

Với compose, toàn bộ hệ thống (app + PostgreSQL + Redis) lên bằng một lệnh docker compose up. Lưu ý: trong mạng compose, service gọi nhau bằng tên service (db, redis), không phải localhost.

❓ Vì sao container lại "nhẹ" hơn máy ảo nhiều lần?

  • Viết Dockerfile cho Node app
  • Chạy docker build/run/ps/logs
  • Dựng compose cho app + DB + Redis
  • Không chạy container bằng root