# Kế hoạch triển khai: Cấu hình Docker để Chạy Server & Phát triển (Hot-reload) Kế hoạch này phác thảo cách cấu hình Docker và Docker Compose cho dự án YoTrip. Cấu hình này sẽ đáp ứng đồng thời hai nhu cầu: 1. **Môi trường Phát triển (Development)**: Đồng bộ mã nguồn trực tiếp (bind mounts) từ máy local vào container, hỗ trợ hot-reload cho cả backend (NestJS watch) và frontend (Vite HMR). 2. **Môi trường Triển khai (Production)**: Đóng gói tối ưu thành các image độc lập, sử dụng Nginx để phục vụ frontend tĩnh và tối ưu hóa hiệu năng NestJS backend. --- ## User Review Required > [!IMPORTANT] > - **Biến môi trường trong Docker**: Khi chạy trong Docker Compose, địa chỉ kết nối cơ sở dữ liệu (`DATABASE_URL`) và Redis (`REDIS_URL`) phải trỏ đến tên các service của container (ví dụ: `postgres` thay vì `localhost`). Chúng tôi sẽ cấu hình Docker Compose ghi đè (override) các biến này một cách tự động để tránh làm hỏng cấu hình chạy trực tiếp bằng `npm run start:dev` trên máy local của bạn. > - **Cổng mạng (Ports)**: > - Backend: Cổng `3001` được mở ra ngoài. > - Frontend: Cổng `5173` (cho Dev) và cổng `3002` (cho Production thông qua Nginx). > - Database: Cổng `5432` (mở để truy cập quản trị nếu cần). > - Redis: Cổng `6379`. --- ## Proposed Changes ### 1. Dockerfile cho Backend #### [NEW] [Dockerfile](file:///home/locpham/travelplanning/backend/Dockerfile) - Thiết lập môi trường chạy Node.js (phiên bản `20-alpine`). - Cài đặt các gói phụ thuộc hệ thống cần thiết (như openssl cho Prisma). - Cấu hình chạy chế độ phát triển (sử dụng volume mounts để hot-reload) và chế độ production (build code JS). - Chạy Prisma client generation lúc build. --- ### 2. Dockerfile cho Frontend #### [NEW] [Dockerfile](file:///home/locpham/travelplanning/frontend/Dockerfile) - Sử dụng chiến lược Multi-stage build để tối ưu hóa dung lượng: - **Stage 1 (Build)**: Cài đặt dependencies và build mã nguồn React/Vite thành thư mục tĩnh `dist`. - **Stage 2 (Nginx)**: Copy thư mục `dist` vào container chạy Nginx để phục vụ các file tĩnh ở cổng `80` (phục vụ môi trường production). - Hỗ trợ chạy Node.js trực tiếp cho môi trường phát triển để dùng Vite dev server và HMR. --- ### 3. Docker Compose cho Phát triển & Sửa Code (Hot-reload) #### [NEW] [docker-compose.yml](file:///home/locpham/travelplanning/docker-compose.yml) - Khởi tạo 4 services chính: 1. `postgres`: Cơ sở dữ liệu PostgreSQL 15, lưu trữ dữ liệu bền vững qua volume `pg_data`. 2. `redis`: Caching và WebSockets. 3. `backend`: Mount thư mục `backend/` vào container, chạy lệnh `npm run start:dev` để tự động reload khi sửa code trên máy host. 4. `frontend`: Mount thư mục `frontend/` vào container, chạy lệnh `npm run dev -- --host` để phục vụ Vite dev server hỗ trợ HMR (Hot Module Replacement). - Đồng bộ hóa các volume ẩn `node_modules` để tránh xung đột hệ điều hành giữa máy host và container. --- ### 4. Docker Compose cho Triển khai lên Server (Production) #### [NEW] [docker-compose.prod.yml](file:///home/locpham/travelplanning/docker-compose.prod.yml) - Cấu hình tối ưu để triển khai lên server cloud: - Builds production image cho `backend` và chạy trực tiếp file JS đã build (`dist/src/main.js`). - Builds production image cho `frontend` sử dụng Nginx để phục vụ client, tối ưu hóa tốc độ tải trang và bảo mật. - Tự động restart dịch vụ nếu gặp sự cố (`restart: always`). --- ## Verification Plan ### Automated Tests - Kiểm tra tính hợp lệ của cấu hình docker-compose: ```bash docker compose config ``` ### Manual Verification 1. **Kiểm tra Môi trường Phát triển (Sửa code trực tiếp)**: - Chạy lệnh khởi động môi trường dev: ```bash docker compose up --build ``` - Truy cập giao diện tại `http://localhost:5173`. - Sửa đổi một dòng văn bản trong frontend (ví dụ: nhãn nút ở `LandingPage.tsx`) hoặc backend và kiểm tra xem container có tự động tải lại (hot-reload) tức thì hay không. 2. **Kiểm tra Môi trường Production (Triển khai server)**: - Chạy lệnh khởi động môi trường prod: ```bash docker compose -f docker-compose.prod.yml up --build -d ``` - Xác nhận mọi service khởi chạy ngầm thành công. - Truy cập ứng dụng qua cổng `80` (http://localhost) và xác nhận hoạt động bình thường.