主要变更: - 添加完整的项目结构和模块(admin、articles、comments、users、session、oauth2、email、moderation、analytics、jobs 等) - 实现系统初始化 API(/init/status 和 /init/run) - 重写部署流程:迁移到 package.json scripts,删除 Makefile - 优化部署脚本:deploy.sh、healthcheck.sh、backup.sh、restore.sh、verify-env.sh - 更新 README.md:简化文档,整合部署指南 - 优化 AGENTS.md:精简到约 150 行,包含完整的代码规范和命令速查 - 配置 Docker Compose 自动化部署(prisma migrate deploy + seed) - 生成 OAuth2 RSA 密钥对支持 - 添加环境变量验证和数据库备份恢复功能
121 lines
2.9 KiB
YAML
121 lines
2.9 KiB
YAML
version: '3.8'
|
|
|
|
services:
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
container_name: blog-postgres
|
|
restart: always
|
|
environment:
|
|
POSTGRES_USER: blog
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-blog}
|
|
POSTGRES_DB: linkshare
|
|
POSTGRES_INITDB_ARGS: '--encoding=UTF-8'
|
|
volumes:
|
|
- ./volumes/postgres:/var/lib/postgresql/data
|
|
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init.sql:ro
|
|
ports:
|
|
- '${POSTGRES_PORT:-5432}:5432'
|
|
healthcheck:
|
|
test: ['CMD-SHELL', 'pg_isready -U blog -d linkshare']
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 40s
|
|
networks:
|
|
- blog-network
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: blog-redis
|
|
restart: always
|
|
ports:
|
|
- '${REDIS_PORT:-6379}:6379'
|
|
volumes:
|
|
- ./volumes/redis:/data
|
|
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
|
|
healthcheck:
|
|
test: ['CMD', 'redis-cli', 'ping']
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 40s
|
|
networks:
|
|
- blog-network
|
|
|
|
api:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile.api
|
|
args:
|
|
NODE_ENV: production
|
|
container_name: blog-api
|
|
restart: always
|
|
ports:
|
|
- '${API_PORT:-3001}:3001'
|
|
environment:
|
|
NODE_ENV: production
|
|
DATABASE_URL: postgresql://blog:${POSTGRES_PASSWORD:-blog}@postgres:5432/linkshare?schema=public
|
|
REDIS_HOST: redis
|
|
REDIS_PORT: 6379
|
|
SESSION_COOKIE_SECURE: ${SESSION_COOKIE_SECURE:-true}
|
|
APP_BASE_URL: ${APP_BASE_URL:-https://api.yourdomain.com}
|
|
env_file:
|
|
- .env
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
command: >
|
|
sh -c "
|
|
echo '⏳ Waiting for database...' &&
|
|
sleep 15 &&
|
|
echo '🔧 Running database migrations...' &&
|
|
bunx prisma migrate deploy &&
|
|
echo '🌱 Seeding database...' &&
|
|
bunx prisma db seed ||
|
|
echo '⚠️ Seed skipped (data may already exist)' &&
|
|
echo '🚀 Starting application...' &&
|
|
node dist/main
|
|
"
|
|
healthcheck:
|
|
test:
|
|
[
|
|
'CMD',
|
|
'node',
|
|
'-e',
|
|
"require('http').get('http://localhost:3001/health', (r) => {if(r.statusCode!==200)process.exit(1)})",
|
|
]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 60s
|
|
networks:
|
|
- blog-network
|
|
# 资源限制
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '2'
|
|
memory: 2G
|
|
reservations:
|
|
cpus: '0.5'
|
|
memory: 512M
|
|
# 日志配置
|
|
logging:
|
|
driver: 'json-file'
|
|
options:
|
|
max-size: '10m'
|
|
max-file: '3'
|
|
compress: 'true'
|
|
|
|
volumes:
|
|
postgres:
|
|
driver: local
|
|
redis:
|
|
driver: local
|
|
|
|
networks:
|
|
blog-network:
|
|
driver: bridge
|