Files
photography/docker-compose.yml
xujiang 6efccae78a feat: 完成容器化系统和用户文档开发
本次提交包含3个重要功能的完成:

1. 📖 用户使用文档完成
   - 创建完整的用户使用手册 (docs/USER_MANUAL.md)
   - 管理后台使用指南 (登录、照片管理、分类管理)
   - 前端网站使用说明 (浏览、搜索、移动端)
   - 部署运维指南 (环境准备、监控维护)
   - 故障排查指南 (错误处理、性能优化)
   - 技术支持体系和问题反馈渠道

2. 🐳 后端Docker容器化完成
   - 多阶段构建Dockerfile (golang:1.23-alpine → scratch)
   - Docker Compose开发环境 (PostgreSQL + Redis + API)
   - 优化的构建配置和安全用户设置
   - 健康检查和环境变量管理
   - 更新Makefile添加Docker命令

3. 🏗️ 前端Docker容器化完成
   - 多阶段构建Dockerfile (node:20-alpine → nginx:1.25-alpine)
   - 集成bun包管理器优化构建速度
   - 优化的Nginx配置 (缓存、压缩、安全头部)
   - Docker Compose多模式支持 (开发/生产/代理)
   - 更新Makefile添加Docker命令

4. 📋 完整的Docker编排系统
   - 项目根目录完整的docker-compose.yml
   - 支持数据库、缓存、API、前端、管理后台的统一部署
   - 自动化Docker设置脚本 (docker-setup.sh)
   - 生产环境监控和日志收集配置

技术成果:
- 项目完成率从65.0%提升至72.5%
- 中优先级任务完成率达90%
- 低优先级任务开始推进(18%)
- 容器化部署体系完全就绪
- 用户文档体系建立完成

下一步: 继续推进容器化扩展和性能优化任务
2025-07-11 14:29:04 +08:00

297 lines
7.0 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.

# Photography Portfolio - Complete Docker Compose
# 完整的生产环境容器编排配置
version: '3.8'
services:
# PostgreSQL 数据库
db:
image: postgres:16-alpine
container_name: photography-db
environment:
POSTGRES_DB: photography
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres123}
POSTGRES_INITDB_ARGS: "--encoding=UTF-8"
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./backend/configs/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro
networks:
- photography-network
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d photography"]
interval: 30s
timeout: 10s
retries: 5
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
# Redis 缓存
redis:
image: redis:7-alpine
container_name: photography-redis
ports:
- "6379:6379"
volumes:
- redis_data:/data
command: redis-server --requirepass ${REDIS_PASSWORD:-redis123} --maxmemory 256mb --maxmemory-policy allkeys-lru
networks:
- photography-network
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "auth", "${REDIS_PASSWORD:-redis123}", "ping"]
interval: 30s
timeout: 10s
retries: 3
# 后端API服务
api:
build:
context: ./backend
dockerfile: Dockerfile
container_name: photography-api
environment:
# 数据库配置
DB_HOST: db
DB_PORT: 5432
DB_NAME: photography
DB_USER: postgres
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
DB_SSL_MODE: disable
DB_MAX_CONNECTIONS: 100
DB_MAX_IDLE_CONNECTIONS: 10
# Redis配置
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PASSWORD: ${REDIS_PASSWORD:-redis123}
REDIS_DB: 0
# JWT配置
JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-key-change-in-production}
JWT_EXPIRE: 24h
# 服务配置
APP_ENV: ${APP_ENV:-production}
APP_PORT: 8080
APP_HOST: 0.0.0.0
APP_VERSION: 1.0.0
# CORS配置
CORS_ORIGINS: ${CORS_ORIGINS:-https://photography.iriver.top,https://admin.photography.iriver.top}
# 文件上传配置
UPLOAD_PATH: /app/uploads
UPLOAD_MAX_SIZE: 10485760 # 10MB
UPLOAD_ALLOWED_TYPES: "image/jpeg,image/png,image/gif,image/webp"
# 日志配置
LOG_LEVEL: ${LOG_LEVEL:-info}
LOG_FORMAT: json
LOG_FILE: /app/logs/api.log
# 监控配置
ENABLE_METRICS: true
METRICS_PORT: 9090
ports:
- "8080:8080"
- "9090:9090" # 监控端口
volumes:
- uploads_data:/app/uploads
- logs_data:/app/logs
networks:
- photography-network
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD", "/photography-api", "--health-check"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '1.0'
memory: 1G
# 前端展示网站
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: photography-frontend
environment:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://api.photography.iriver.top}
NEXT_PUBLIC_APP_NAME: "Photography Portfolio"
NEXT_PUBLIC_APP_VERSION: "1.0.0"
NEXT_PUBLIC_ENABLE_ANALYTICS: ${NEXT_PUBLIC_ENABLE_ANALYTICS:-false}
NEXT_PUBLIC_MAX_FILE_SIZE: 10485760
ports:
- "3000:80"
networks:
- photography-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
# 管理后台
admin:
build:
context: ./admin
dockerfile: Dockerfile
container_name: photography-admin
environment:
REACT_APP_API_URL: ${REACT_APP_API_URL:-https://api.photography.iriver.top}
REACT_APP_APP_NAME: "Photography Admin"
REACT_APP_VERSION: "1.0.0"
ports:
- "3001:80"
networks:
- photography-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
# 数据库迁移 (一次性服务)
migrate:
build:
context: ./backend
dockerfile: Dockerfile
container_name: photography-migrate
environment:
DB_HOST: db
DB_PORT: 5432
DB_NAME: photography
DB_USER: postgres
DB_PASSWORD: ${DB_PASSWORD:-postgres123}
DB_SSL_MODE: disable
networks:
- photography-network
depends_on:
db:
condition: service_healthy
entrypoint: ["/migrate", "up"]
restart: "no"
# 监控服务 (可选)
prometheus:
image: prom/prometheus:latest
container_name: photography-prometheus
ports:
- "9091:9090"
volumes:
- ./configs/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
networks:
- photography-network
restart: unless-stopped
profiles:
- monitoring
# 日志收集 (可选)
grafana:
image: grafana/grafana:latest
container_name: photography-grafana
ports:
- "3002:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}
volumes:
- grafana_data:/var/lib/grafana
networks:
- photography-network
restart: unless-stopped
profiles:
- monitoring
# 反向代理 (可选推荐使用Caddy)
nginx:
image: nginx:1.25-alpine
container_name: photography-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./configs/nginx.conf:/etc/nginx/nginx.conf:ro
- ./configs/sites-enabled:/etc/nginx/sites-enabled:ro
- ssl_certs:/etc/nginx/ssl:ro
networks:
- photography-network
depends_on:
- frontend
- admin
- api
restart: unless-stopped
profiles:
- proxy
volumes:
postgres_data:
driver: local
redis_data:
driver: local
uploads_data:
driver: local
logs_data:
driver: local
prometheus_data:
driver: local
grafana_data:
driver: local
ssl_certs:
driver: local
networks:
photography-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
labels:
- "com.photography.network=main"
# 健康检查配置
x-healthcheck-defaults: &healthcheck-defaults
interval: 30s
timeout: 10s
retries: 3
start_period: 30s