2025-10-30 18:35:30 +08:00
|
|
|
|
version: "3.9"
|
|
|
|
|
|
services:
|
2025-11-06 17:06:43 +08:00
|
|
|
|
# Backend API service (Go app)
|
2025-10-30 18:35:30 +08:00
|
|
|
|
todowindy:
|
|
|
|
|
|
build: .
|
|
|
|
|
|
image: todowindy:latest
|
|
|
|
|
|
container_name: todowindy
|
|
|
|
|
|
restart: unless-stopped
|
2025-11-06 17:06:43 +08:00
|
|
|
|
# Do not publish container port directly; expose to compose network only.
|
|
|
|
|
|
ports: ["8080:8080"]
|
|
|
|
|
|
expose:
|
|
|
|
|
|
- "8080"
|
2025-10-30 18:35:30 +08:00
|
|
|
|
env_file:
|
|
|
|
|
|
- .env
|
|
|
|
|
|
environment:
|
|
|
|
|
|
# Ensure server binds on all interfaces in container
|
|
|
|
|
|
- TW_ADDR=:8080
|
2025-11-06 17:06:43 +08:00
|
|
|
|
# Use external writable volume for SQLite (align with image default path)
|
|
|
|
|
|
- TW_DB_PATH=/app/data/todowindy.db
|
2025-10-30 18:35:30 +08:00
|
|
|
|
# Run in production mode by default
|
|
|
|
|
|
- GIN_MODE=release
|
|
|
|
|
|
# Optional timeouts (RFC3339 duration strings or seconds)
|
|
|
|
|
|
- TW_HTTP_WRITE_TIMEOUT=${TW_HTTP_WRITE_TIMEOUT:-240s}
|
|
|
|
|
|
- TW_HTTP_READ_TIMEOUT=${TW_HTTP_READ_TIMEOUT:-60s}
|
|
|
|
|
|
- TW_HTTP_IDLE_TIMEOUT=${TW_HTTP_IDLE_TIMEOUT:-90s}
|
|
|
|
|
|
# Optional timezone for tzdata
|
|
|
|
|
|
- TZ=${TZ:-UTC}
|
|
|
|
|
|
volumes:
|
2025-11-06 17:06:43 +08:00
|
|
|
|
# Persist DB to host; image user has write perms for /app/data
|
|
|
|
|
|
- ./data:/app/data
|
2025-10-30 18:35:30 +08:00
|
|
|
|
healthcheck:
|
|
|
|
|
|
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8080/healthz"]
|
|
|
|
|
|
interval: 30s
|
|
|
|
|
|
timeout: 5s
|
|
|
|
|
|
start_period: 10s
|
|
|
|
|
|
retries: 3
|
|
|
|
|
|
stop_grace_period: 10s
|
2025-11-06 17:06:43 +08:00
|
|
|
|
|
|
|
|
|
|
# Front proxy + static file server
|
|
|
|
|
|
nginx:
|
|
|
|
|
|
image: nginx:1.25-alpine
|
|
|
|
|
|
container_name: todowindy-nginx
|
|
|
|
|
|
depends_on:
|
|
|
|
|
|
- todowindy
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "8088:80" # 本机用 8088 访问;也可改为 "80:80"
|
|
|
|
|
|
# 不要先开 443:443(本地无证书)
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ./web:/usr/share/nginx/html:ro
|
|
|
|
|
|
- ./deploy/prod/nginx.http.conf:/etc/nginx/conf.d/default.conf:ro
|
|
|
|
|
|
# 本地开发不需要这些证书相关挂载,先删掉/注释掉
|
|
|
|
|
|
# - ./deploy/letsencrypt:/etc/letsencrypt
|
|
|
|
|
|
# - ./deploy/certbot/www:/var/www/certbot:ro
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
|
|
|
|
|
|
# Optional named volumes for persistence can be declared here if needed
|
|
|
|
|
|
# volumes:
|
|
|
|
|
|
# letsencrypt:
|
|
|
|
|
|
# certbot-www:
|
|
|
|
|
|
|
|
|
|
|
|
# Certbot helper service (run on-demand for issue/renew)
|
|
|
|
|
|
certbot:
|
|
|
|
|
|
image: certbot/certbot:latest
|
|
|
|
|
|
container_name: todowindy-certbot
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ./deploy/letsencrypt:/etc/letsencrypt
|
|
|
|
|
|
- ./deploy/certbot/www:/var/www/certbot
|
|
|
|
|
|
# No ports; invoke with `docker compose run --rm certbot ...`
|
|
|
|
|
|
restart: "no"
|