Docker da thay doi cach chung ta xay dung, phan phoi va chay phan mem. Thay vi "chay duoc tren may cua toi", Docker dam bao rang ung dung cua ban chay giong nhau o moi noi - tren laptop cua ban, tren may cua dong nghiep, trong CI/CD va trong production. Trong huong dan nay, chung ta se di tu con so khong den viec deploy mot ung dung thuc te.
Docker la gi?
Docker la mot nen tang dong goi ung dung cua ban va tat ca cac phu thuoc cua no vao mot don vi chuan hoa goi la container. Container la mot tien trinh co lap, nhe, chia se kernel OS cua may chu nhung co he thong tap tin, mang va khong gian tien trinh rieng.
Container vs May Ao
| Khia canh | Container | May Ao |
|---|---|---|
| Khoi dong | Giay | Phut |
| Kich thuoc | MB | GB |
| OS | Chia se kernel may chu | OS khach day du |
| Co lap | Cap tien trinh | Cap phan cung |
| Hieu suat | Gan nhu native | Chi phi tu hypervisor |
| Mat do | Hang tram moi may chu | Hang chuc moi may chu |
Cai dat Docker
# macOS brew install --cask docker # Ubuntu/Debian curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # Verify installation docker --version docker run hello-world
Cac Khai niem Cot loi
Image
Image la mot template chi doc voi cac huong dan de tao container. Hay nghi ve no nhu mot ban chup nhanh cua ung dung va moi truong cua no.
# Pull an image from Docker Hub docker pull node:20-alpine # List local images docker images # Remove an image docker rmi node:20-alpine
Container
Container la mot phien ban dang chay cua mot image. Ban co the tao, khoi dong, dung va xoa container.
# Run a container docker run -d --name my-app -p 3000:3000 node:20-alpine # List running containers docker ps # List all containers (including stopped) docker ps -a # Stop a container docker stop my-app # Remove a container docker rm my-app # View logs docker logs my-app # Execute a command inside a running container docker exec -it my-app sh
Viet Dockerfile
Dockerfile la mot tap tin van ban voi cac huong dan de xay dung image. Moi huong dan tao mot layer.
Dockerfile Co ban cho Ung dung Node.js
# Use an official Node.js runtime as base image FROM node:20-alpine # Set working directory WORKDIR /app # Copy package files first (better caching) COPY package.json package-lock.json ./ # Install dependencies RUN npm ci --only=production # Copy application code COPY . . # Expose the port the app runs on EXPOSE 3000 # Command to run the application CMD ["node", "server.js"]
Build va Chay
# Build the image docker build -t my-node-app . # Run the container docker run -d -p 3000:3000 my-node-app # Visit http://localhost:3000
Multi-Stage Build
Multi-stage build giu cho image production cua ban nho bang cach tach moi truong build khoi runtime.
# Stage 1: Build FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # Stage 2: Production FROM node:20-alpine AS runner WORKDIR /app COPY /app/dist ./dist COPY /app/node_modules ./node_modules COPY /app/package.json ./ EXPOSE 3000 CMD ["node", "dist/server.js"]
Dieu nay tao ra mot image chi chua dau ra da bien dich va cac phu thuoc production - khong co ma nguon, khong co phu thuoc phat trien, khong co cong cu build.
Vi du Multi-Stage cho Next.js
FROM node:20-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci FROM node:20-alpine AS builder WORKDIR /app COPY /app/node_modules ./node_modules COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY /app/public ./public COPY /app/.next/standalone ./ COPY /app/.next/static ./.next/static EXPOSE 3000 CMD ["node", "server.js"]
Volume: Du lieu Ben vung
Mac dinh, du lieu ben trong container se mat khi container bi xoa. Volume giai quyet van de nay.
# Create a named volume docker volume create my-data # Run with a volume docker run -d -v my-data:/app/data my-app # Bind mount (map host directory to container) docker run -d -v $(pwd)/data:/app/data my-app # List volumes docker volume ls
Mang
Docker tao cac mang co lap de cac container giao tiep voi nhau.
# Create a custom network docker network create my-network # Run containers on the same network docker run -d --name api --network my-network my-api docker run -d --name db --network my-network postgres:16 # Containers can reach each other by name # From "api" container: postgres://db:5432
Docker Compose
Docker Compose cho phep ban dinh nghia va chay cac ung dung nhieu container voi mot tap tin YAML duy nhat.
docker-compose.yml
services: api: build: ./api ports: - "3000:3000" environment: - DATABASE_URL=postgres://user:pass@db:5432/mydb depends_on: - db db: image: postgres:16-alpine environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB=mydb volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" redis: image: redis:7-alpine ports: - "6379:6379" volumes: pgdata:
Cac Lenh
# Start all services docker compose up -d # View logs docker compose logs -f # Stop all services docker compose down # Rebuild and restart docker compose up -d --build # Scale a service docker compose up -d --scale api=3
.dockerignore
Giong nhu .gitignore, tap tin nay ngan cac tap tin khong can thiet bi sao chep vao image.
node_modules .git .env *.md .next dist coverage
Cac Phuong phap Tot nhat cho Production
1. Su dung Image Co so Nho
# Bad: 1GB+ FROM node:20 # Good: ~180MB FROM node:20-alpine
2. Khong Chay voi Quyen Root
FROM node:20-alpine RUN addgroup -S app && adduser -S app -G app USER app WORKDIR /home/app COPY . .
3. Su dung Tag Image Cu the
# Bad: can change unexpectedly FROM node:latest # Good: pinned version FROM node:20.11-alpine3.19
4. Tan dung Build Cache
Sap xep cac huong dan Dockerfile tu it thay doi nhat den thay doi nhieu nhat:
FROM node:20-alpine WORKDIR /app # These change rarely - cached COPY package.json package-lock.json ./ RUN npm ci --only=production # This changes often - not cached COPY . .
5. Health Check
HEALTHCHECK \ CMD wget -qO- http://localhost:3000/health || exit 1
6. Su dung Bien Moi truong
ENV NODE_ENV=production ENV PORT=3000
Bang Tham chieu Nhanh cac Lenh Docker Thuong dung
# Images docker build -t name:tag . # Build image docker images # List images docker rmi image_name # Remove image docker image prune # Remove unused images # Containers docker run -d -p 3000:3000 image # Run detached docker ps # List running docker stop container_name # Stop docker rm container_name # Remove docker logs -f container_name # Follow logs docker exec -it container sh # Shell into container # Compose docker compose up -d # Start services docker compose down # Stop services docker compose logs -f # Follow all logs docker compose ps # List services # Cleanup docker system prune -a # Remove everything unused
Tu Docker den Kubernetes
Docker quan ly cac container rieng le. Khi ban can dieu phoi hang tram container tren nhieu may chu, ban can Kubernetes. Docker va Kubernetes bo sung cho nhau:
- Docker: xay dung va chay container
- Kubernetes: dieu phoi container o quy mo lon (lap lich, mo rong, tu phuc hoi)
Neu ban quan tam den buoc tiep theo, hay xem bai viet cua toi ve Gioi thieu Kubernetes.
Ket luan
Docker la mot ky nang co ban cho cac nha phat trien hien dai. No loai bo su khong nhat quan ve moi truong, don gian hoa viec deploy va la nen tang cho viec dieu phoi container voi Kubernetes. Bat dau voi mot Dockerfile don gian, chuyen sang Docker Compose cho cac ung dung nhieu dich vu, va ap dung multi-stage build cung cac phuong phap bao mat tot nhat khi ban phat trien.
Cach tot nhat de hoc Docker la container hoa mot du an ma ban dang lam viec. Hay bat dau ngay hom nay.