Files
ocdp-go/docker-compose.yml
Ivan087 17acb7d018 fix: clear tsbuildinfo cache in frontend-build to prevent stale builds
- Add rm -rf node_modules/.tmp before npm run build
- Without this, tsc -b reads stale .tsbuildinfo from Docker volume
  and skips recompiling changed files, causing old JS to be served
2026-05-21 15:01:14 +08:00

161 lines
5.1 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ==================================================
# OCDP Docker Compose (complete local stack)
# ==================================================
# 使用方式:
# docker compose up --build
#
# 说明:
# - 本文件是本地部署主入口,包含 PostgreSQL、Backend、前端构建和 Nginx。
# - 默认使用高位宿主端口,避免和本机其他项目冲突。
# - Nginx 统一监听容器内 80/443默认映射 WEB_HTTP_PORT=18080、WEB_HTTPS_PORT=18443
# 根据路径转发:/api/* → backend其他路径 → 前端静态文件。
# ==================================================
services:
# --------------------------------------------------
# PostgreSQL 数据库
# --------------------------------------------------
postgres:
image: postgres:17-alpine
container_name: ocdp-postgres
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB:-ocdp}
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=C --lc-ctype=C"
ports:
- "${POSTGRES_PORT:-15432}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./backend/scripts/init-db.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-ocdp}"]
interval: 10s
timeout: 5s
retries: 30
start_period: 60s
networks:
- ocdp-network
# --------------------------------------------------
# Backend API
# --------------------------------------------------
backend:
build:
context: ./backend
dockerfile: Dockerfile
args:
GOPROXY: ${GOPROXY:-https://goproxy.cn,direct}
GOSUMDB: ${GOSUMDB:-sum.golang.google.cn}
image: ocdp-backend:latest
container_name: ocdp-backend
restart: unless-stopped
env_file:
- path: ./.env
required: false
format: raw
environment:
ADAPTER_MODE: ${ADAPTER_MODE:-production}
PORT: 8080
JWT_SECRET: ${JWT_SECRET:-change-me-in-production}
ENCRYPTION_KEY: ${ENCRYPTION_KEY:-change-me-32-bytes-long-key-here}
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-ocdp}?sslmode=disable
ports:
- "${BACKEND_PORT:-18081}:8080"
volumes:
- ./config:/app/config:ro
- ./data:/app/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
depends_on:
postgres:
condition: service_healthy
networks:
- ocdp-network
# --------------------------------------------------
# 构建前端静态资源 (一次性 Job)
# --------------------------------------------------
frontend-build:
image: node:20-alpine
container_name: ocdp-frontend-build
init: true
working_dir: /app
restart: "no"
environment:
NODE_ENV: production
NPM_CONFIG_PRODUCTION: "false" # ensure devDependencies (tsc, vite) are installed for build
# 默认通过 Nginx 代理到 backend -> /api/v1
VITE_API_BASE_URL: ${VITE_API_BASE_URL:-/api/v1}
FILE_OWNER_UID: ${FILE_OWNER_UID:-1000}
FILE_OWNER_GID: ${FILE_OWNER_GID:-1000}
command: >
sh -c "
set -eux;
npm ci;
rm -rf node_modules/.tmp;
npm run build;
mkdir -p /build;
rm -rf /build/*;
cp -R dist/. /build/;
if [ -d dist ]; then chown -R "$$FILE_OWNER_UID:$$FILE_OWNER_GID" dist; fi;
if [ -d /build ]; then chown -R "$$FILE_OWNER_UID:$$FILE_OWNER_GID" /build; fi
"
volumes:
- ./frontend:/app
- frontend_node_modules:/app/node_modules
- frontend_dist:/build
networks:
- ocdp-network
# --------------------------------------------------
# Nginx - 静态文件 + /api 反向代理统一入口
# --------------------------------------------------
nginx:
image: nginx:1.27-alpine
container_name: ocdp-nginx
restart: unless-stopped
depends_on:
frontend-build:
condition: service_completed_successfully
backend:
condition: service_healthy
ports:
- "${WEB_HTTP_PORT:-18080}:80"
- "${WEB_HTTPS_PORT:-18443}:443"
volumes:
- frontend_dist:/usr/share/nginx/html:ro
- ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
- ./infra/nginx/certs:/etc/nginx/certs:ro
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1/healthz || exit 1"]
interval: 30s
timeout: 5s
retries: 5
networks:
- ocdp-network
# ==================================================
# Networks
# ==================================================
networks:
ocdp-network:
driver: bridge
name: ocdp-network
# ==================================================
# Volumes
# ==================================================
volumes:
postgres_data:
name: ocdp-postgres-data
frontend_dist:
driver: local
frontend_node_modules:
driver: local