# Construction Timelapse — Docker Setup Guide Document này ghi lại quy trình chuẩn để build và chạy toàn bộ hệ thống timelapse. ## Cấu trúc hệ thống ``` timelapse-2/ ├── apps/ │ ├── api-server/ # NestJS API (port 3001) │ ├── web-dashboard/ # Next.js frontend (port 3000) │ ├── worker/ # Background worker │ └── device-agent/ # Device agent (Python) ├── packages/ │ ├── shared-types/ # Shared TypeScript types │ └── config/ # Shared tsconfig templates ├── docker-compose.yml ├── .env # Secrets (KHÔNG commit) └── .env.example # Template cho .env ``` ## Các bước thiết lập ### 1. Prerequisites ```bash # Docker Engine (cần API version tương thích với docker compose plugin) docker --version # >= 24.0 docker compose version # >= 2.20 # Nếu dùng Raspberry Pi / Debian cũ (docker.io package) # Cần nâng cấp lên Docker CE: curl -fsSL https://download.docker.com/linux/debian/gpg \ | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=arm64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \ https://download.docker.com/linux/debian bullseye stable" \ | sudo tee /etc/apt/sources.list.d/docker.list sudo apt-get install -y docker-ce ``` ### 2. Clone repo ```bash git clone /opt/timelapse cd /opt/timelapse ``` ### 3. Tạo file `.env` ```bash cp .env.example .env # Hoặc tạo mới với nội dung: cat > .env << 'EOF' GOGS_TOKEN= DATABASE_URL=postgres://timelapse:timelapse_dev_password@postgres:5432/timelapse_dev REDIS_URL=redis://redis:6379 JWT_SECRET= REFRESH_TOKEN_SECRET= CORS_ORIGIN=http://localhost:3000 GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= GOOGLE_CALLBACK_URL=http://localhost:3001/v1/auth/google/callback NODE_ENV=development EOF ``` > **Lưu ý:** `.env` đã được gitignore. KHÔNG bao giờ commit file này. ### 4. Build và chạy ```bash cd /opt/timelapse # Build tất cả images (lần đầu mất ~5-10 phút) sudo docker compose up -d --build # Kiểm tra trạng thái sudo docker compose ps # Xem logs sudo docker compose logs --tail=30 ``` ### 5. Kiểm tra services ```bash # API health check curl http://localhost:3001/v1/auth/health # Web dashboard curl http://localhost:3000/ | head -5 ``` **Kết quả mong đợi:** - `api-server` — Up, healthy - `postgres` — Up, healthy - `redis` — Up, healthy - `web-dashboard` — Up - `worker` — Up (hiện là stub) ### 6. Dừng hệ thống ```bash sudo docker compose down # Thêm -v để xóa volumes: sudo docker compose down -v ``` ## Dockerfiles — Tại sao khác biệt so với repo gốc Repo gốc dùng `pnpm` với `workspace:*` protocol. Docker build cần 2 thay đổi: ### Thay đổi 1: `sed` convert workspace protocol ```dockerfile # Trong mỗi Dockerfile (api-server, worker, web-dashboard): RUN sed -i 's|"@shared/types": "workspace:\*"|"@shared/types": "file:../../packages/shared-types"|g' \ apps/api-server/package.json \ apps/web-dashboard/package.json \ apps/worker/package.json ``` Vì `npm` (Alpine) không hiểu `workspace:*` protocol — chỉ pnpm mới hỗ trợ. ### Thay đổi 2: npm thay vì pnpm ```dockerfile FROM node:20-alpine RUN apk add --no-cache npm WORKDIR /app ... RUN npm install RUN cd packages/shared-types && npm run build RUN cd apps/ && npm run build ``` ## Troubleshooting ### `FATAL: database "timelapse" does not exist` Kiểm tra biến môi trường trong container: ```bash sudo docker exec timelapse-api-server-1 sh -c 'echo $DATABASE_URL' # Phải trỏ đến timelapse_dev KHÔNG phải timelapse # Đúng: postgres://timelapse:...@postgres:5432/timelapse_dev ``` ### PostgreSQL health check fail liên tục Chờ postgres khởi động xong (~10s). Kiểm tra: ```bash sudo docker exec timelapse-postgres-1 pg_isready -U timelapse ``` ### Worker restart loop Worker hiện chỉ là stub. Kiểm tra logs: ```bash sudo docker compose logs worker --tail=20 ``` ### Muốn rebuild sạch ```bash sudo docker compose down sudo docker builder prune -f sudo docker compose up -d --build ``` ## Cấu hình thêm ### Redis memory overcommit warning Thêm vào `/etc/sysctl.conf` (cần reboot): ``` vm.overcommit_memory = 1 ``` Hoặc chạy ngay: ```bash sudo sysctl vm.overcommit_memory=1 ``` ### Google OAuth (tuỳ chọn) Điền `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` trong `.env` và restart: ```bash sudo docker compose restart api-server ```