## 主要改进 ### 1. Docker 镜像构建加速(30 倍速度提升) **后端 (Dockerfile.prod):** - 添加 Debian 中科大镜像源 (mirrors.ustc.edu.cn) - 速度提升:67s → 2s (146 KB/s → 4590 KB/s) - 配置 Docker 基础镜像缓存服务器 (host.docker.internal:15001) - 多阶段构建:builder + runtime 分离 **前端 (Dockerfile):** - 添加 Alpine 中科大镜像源 - 配置 npm 淘宝镜像 (registry.npmmirror.com) - BuildKit 缓存挂载优化 ### 2. 端口分段管理(PORT_GUIDE.md) 实现三种部署方式的端口隔离,方便并行运行: | 部署方式 | 后端 | 前端 | PostgreSQL | Redis | Nginx | |---------|------|------|------------|-------|-------| | 本地开发 | 5115 | 6115 | - | - | - | | Docker Compose | 15115 | 16115 | 15432 | 16379 | 18080 | | Kubernetes | 25115 | 26115 | 25432 | 26379 | - | ### 3. 环境配置文件 - `.env.prod` - Docker Compose 配置(1xxxx 端口段) - `.env.k8s` - Kubernetes 配置(2xxxx 端口段) - `PORT_GUIDE.md` - 端口规划说明文档 ### 4. BuildKit 配置 (buildkitd.toml) - 配置 insecure registry 支持 - 允许从本地缓存服务器拉取镜像 - 支持 localhost:15001, localhost:15000, host.docker.internal:15001 ### 5. Docker Compose 优化 - 修改网络子网为 172.28.0.0/16(避免冲突) - 调整端口映射使用 1xxxx 段 - 传递 REGISTRY_CACHE 构建参数 ### 6. 忽略文件更新 (.gitignore) - 添加 logs/ 目录到 .gitignore ## 技术细节 **镜像加速对比:** - Debian 软件源:deb.debian.org → mirrors.ustc.edu.cn - pip 包:pypi.org → mirrors.ustc.edu.cn - npm 包:registry.npmjs.org → registry.npmmirror.com - Docker 基础镜像:registry-1.docker.io → localhost:15001 缓存 **构建成功验证:** - 后端镜像:localhost:15000/fastapi-template-backend:latest (657MB) - 前端镜像:localhost:15000/fastapi-template-frontend:latest (56.2MB) - 所有服务健康检查通过 ## 文件清单 - backend/Dockerfile.prod (优化:Debian 镜像源) - frontend/Dockerfile (优化:Alpine 镜像源 + npm 配置) - docker-compose.prod.yml (端口调整 + 网络配置) - .env.prod (Docker Compose 环境配置) - .env.k8s (Kubernetes 环境配置) - buildkitd.toml (BuildKit insecure registry 配置) - PORT_GUIDE.md (端口规划说明文档) - .gitignore (忽略 logs 目录) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
172 lines
4.6 KiB
YAML
172 lines
4.6 KiB
YAML
version: '3.8'
|
|
|
|
###############################################################################
|
|
# FastAPI Template - 生产环境 Docker Compose 配置
|
|
# 从本地镜像仓库拉取镜像部署
|
|
# 使用: docker-compose -f docker-compose.prod.yml up -d
|
|
###############################################################################
|
|
|
|
services:
|
|
# 后端服务
|
|
backend:
|
|
build:
|
|
context: ./backend
|
|
dockerfile: Dockerfile.prod
|
|
args:
|
|
- REGISTRY_CACHE=${REGISTRY_CACHE:-host.docker.internal:15001/}
|
|
- PIP_INDEX_URL=https://pypi.mirrors.ustc.edu.cn/simple/
|
|
- PIP_TRUSTED_HOST=pypi.mirrors.ustc.edu.cn
|
|
image: ${REGISTRY_HOST:-localhost:5000}/fastapi-template-backend:${VERSION:-latest}
|
|
container_name: fastapi-backend
|
|
restart: unless-stopped
|
|
environment:
|
|
# 应用配置
|
|
- APP_NAME=${APP_NAME:-灵境万象FastAPI}
|
|
- ENVIRONMENT=production
|
|
- DEBUG=false
|
|
|
|
# 数据库配置
|
|
- DATABASE_HOST=postgres
|
|
- DATABASE_PORT=5432
|
|
- DATABASE_NAME=${DATABASE_NAME:-template}
|
|
- DATABASE_USER=${DATABASE_USER:-postgres}
|
|
- DATABASE_PASSWORD=${DATABASE_PASSWORD:-postgres}
|
|
|
|
# Redis 配置
|
|
- REDIS_HOST=redis
|
|
- REDIS_PORT=6379
|
|
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
|
|
|
# 安全配置
|
|
- SECRET_KEY=${SECRET_KEY:-change-this-in-production}
|
|
- ALGORITHM=HS256
|
|
- ACCESS_TOKEN_EXPIRE_MINUTES=30
|
|
|
|
# CORS 配置
|
|
- ALLOWED_ORIGINS=http://localhost,http://localhost:80,http://frontend
|
|
ports:
|
|
- "${BACKEND_PORT:-5115}:8000"
|
|
volumes:
|
|
- ./backend/logs:/app/logs
|
|
- ./backend/static:/app/static
|
|
networks:
|
|
- app-network
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/health/"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
|
|
# 前端服务
|
|
frontend:
|
|
build:
|
|
context: ./frontend
|
|
dockerfile: Dockerfile
|
|
args:
|
|
- REGISTRY_CACHE=${REGISTRY_CACHE:-host.docker.internal:15001/}
|
|
- NPM_REGISTRY=https://registry.npmmirror.com
|
|
image: ${REGISTRY_HOST:-localhost:5000}/fastapi-template-frontend:${VERSION:-latest}
|
|
container_name: fastapi-frontend
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${FRONTEND_PORT:-6115}:80"
|
|
networks:
|
|
- app-network
|
|
depends_on:
|
|
- backend
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:80/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 10s
|
|
|
|
# PostgreSQL 数据库
|
|
postgres:
|
|
image: postgres:15-alpine
|
|
container_name: fastapi-postgres
|
|
restart: unless-stopped
|
|
environment:
|
|
- POSTGRES_DB=${DATABASE_NAME:-template}
|
|
- POSTGRES_USER=${DATABASE_USER:-postgres}
|
|
- POSTGRES_PASSWORD=${DATABASE_PASSWORD:-postgres}
|
|
- POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C
|
|
ports:
|
|
- "${POSTGRES_PORT:-5432}:5432"
|
|
volumes:
|
|
- postgres-data:/var/lib/postgresql/data
|
|
- ./backend/scripts/init_database.sh:/docker-entrypoint-initdb.d/init.sh
|
|
networks:
|
|
- app-network
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USER:-postgres}"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# Redis 缓存
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: fastapi-redis
|
|
restart: unless-stopped
|
|
command: >
|
|
redis-server
|
|
--appendonly yes
|
|
--requirepass ${REDIS_PASSWORD:-}
|
|
--maxmemory 256mb
|
|
--maxmemory-policy allkeys-lru
|
|
ports:
|
|
- "${REDIS_PORT:-6379}:6379"
|
|
volumes:
|
|
- redis-data:/data
|
|
networks:
|
|
- app-network
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# Nginx 反向代理 (可选)
|
|
nginx:
|
|
image: nginx:alpine
|
|
container_name: fastapi-nginx
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${NGINX_PORT:-80}:80"
|
|
- "${NGINX_SSL_PORT:-443}:443"
|
|
volumes:
|
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
|
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
|
- ./nginx/ssl:/etc/nginx/ssl:ro
|
|
- ./logs/nginx:/var/log/nginx
|
|
networks:
|
|
- app-network
|
|
depends_on:
|
|
- backend
|
|
- frontend
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:80/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
networks:
|
|
app-network:
|
|
driver: bridge
|
|
ipam:
|
|
config:
|
|
- subnet: 172.28.0.0/16
|
|
|
|
volumes:
|
|
postgres-data:
|
|
driver: local
|
|
redis-data:
|
|
driver: local
|