0

Docker Compose cho dự án thực tế: từ dev đến production

Nhiều tutorial Docker Compose chỉ dừng ở mức "chạy WordPress + MySQL". Nhưng dự án thực tế phức tạp hơn nhiều. Bài này chia sẻ setup mình đang dùng cho production.

Cấu trúc thư mục

project/
├── docker-compose.yml          # Base config
├── docker-compose.dev.yml      # Dev overrides
├── docker-compose.prod.yml     # Prod overrides
├── .env.dev
├── .env.prod
└── services/
    ├── api/
        │   └── Dockerfile
            ├── worker/
                │   └── Dockerfile
                    └── nginx/
                            └── nginx.conf
                            ```
                            
                            ## Base compose file
                            
                            ```yaml
                            services:
                              api:
                                  build: ./services/api
                                      env_file: .env
                                          depends_on:
                                                db:
                                                        condition: service_healthy
                                                            networks:
                                                                  - backend
                                                                  
                                                                    db:
                                                                        image: postgres:16-alpine
                                                                            volumes:
                                                                                  - pgdata:/var/lib/postgresql/data
                                                                                      healthcheck:
                                                                                            test: pg_isready -U postgres
                                                                                                  interval: 5s
                                                                                                        retries: 5
                                                                                                            networks:
                                                                                                                  - backend
                                                                                                                  
                                                                                                                    redis:
                                                                                                                        image: redis:7-alpine
                                                                                                                            networks:
                                                                                                                                  - backend
                                                                                                                                  
                                                                                                                                  volumes:
                                                                                                                                    pgdata:
                                                                                                                                    
                                                                                                                                    networks:
                                                                                                                                      backend:
                                                                                                                                      ```
                                                                                                                                      
                                                                                                                                      ## Dev overrides
                                                                                                                                      
                                                                                                                                      ```yaml
                                                                                                                                      # docker-compose.dev.yml
                                                                                                                                      services:
                                                                                                                                        api:
                                                                                                                                            volumes:
                                                                                                                                                  - ./services/api:/app  # Hot reload
                                                                                                                                                      ports:
                                                                                                                                                            - "8000:8000"
                                                                                                                                                                command: uvicorn main:app --reload --host 0.0.0.0
                                                                                                                                                                
                                                                                                                                                                  db:
                                                                                                                                                                      ports:
                                                                                                                                                                            - "5432:5432"  # Access from host
                                                                                                                                                                            ```
                                                                                                                                                                            
                                                                                                                                                                            Chạy dev: `docker compose -f docker-compose.yml -f docker-compose.dev.yml up`
                                                                                                                                                                            
                                                                                                                                                                            ## Prod overrides
                                                                                                                                                                            
                                                                                                                                                                            ```yaml
                                                                                                                                                                            # docker-compose.prod.yml
                                                                                                                                                                            services:
                                                                                                                                                                              api:
                                                                                                                                                                                  restart: always
                                                                                                                                                                                      deploy:
                                                                                                                                                                                            resources:
                                                                                                                                                                                                    limits:
                                                                                                                                                                                                              memory: 512M
                                                                                                                                                                                                                  logging:
                                                                                                                                                                                                                        driver: json-file
                                                                                                                                                                                                                              options:
                                                                                                                                                                                                                                      max-size: "10m"
                                                                                                                                                                                                                                              max-file: "3"
                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                nginx:
                                                                                                                                                                                                                                                    image: nginx:alpine
                                                                                                                                                                                                                                                        ports:
                                                                                                                                                                                                                                                              - "80:80"
                                                                                                                                                                                                                                                                    - "443:443"
                                                                                                                                                                                                                                                                        volumes:
                                                                                                                                                                                                                                                                              - ./services/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
                                                                                                                                                                                                                                                                                  depends_on:
                                                                                                                                                                                                                                                                                        - api
                                                                                                                                                                                                                                                                                        ```
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        ## Tips từ production
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        1. **Luôn dùng healthcheck** — `depends_on` không đợi service sẵn sàng, chỉ đợi container start
                                                                                                                                                                                                                                                                                        2. **Pin image version** — `postgres:16-alpine`, không phải `postgres:latest`
                                                                                                                                                                                                                                                                                        3. **Giới hạn memory** — Tránh một container ăn hết RAM
                                                                                                                                                                                                                                                                                        4. **Log rotation** — Không set thì log file sẽ phình to vô hạn
                                                                                                                                                                                                                                                                                        5. **Named volumes cho data** — Bind mount chỉ dùng cho dev, production dùng named volume
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        ---
                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                        Bạn có tips nào khác cho Docker Compose production không? Share nhé!

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí