186 lines
5.7 KiB
YAML
186 lines
5.7 KiB
YAML
version: '3.8'
|
|
|
|
services:
|
|
# ==================== 应用服务 ====================
|
|
app:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
image: carrotskin/backend:latest
|
|
container_name: carrotskin-backend
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${APP_PORT:-8080}:8080"
|
|
environment:
|
|
# 服务器配置
|
|
- SERVER_PORT=:8080
|
|
- SERVER_MODE=${SERVER_MODE:-release}
|
|
# 数据库配置
|
|
- DATABASE_DRIVER=postgres
|
|
- DATABASE_HOST=postgres
|
|
- DATABASE_PORT=5432
|
|
- DATABASE_USERNAME=carrotskin
|
|
- DATABASE_PASSWORD=${DATABASE_PASSWORD:-carrotskin123}
|
|
- DATABASE_NAME=carrotskin
|
|
- DATABASE_SSL_MODE=disable
|
|
- DATABASE_TIMEZONE=Asia/Shanghai
|
|
# Redis 配置
|
|
- REDIS_HOST=redis
|
|
- REDIS_PORT=6379
|
|
- REDIS_PASSWORD=${REDIS_PASSWORD:-}
|
|
- REDIS_DATABASE=0
|
|
# JWT 配置
|
|
- JWT_SECRET=${JWT_SECRET:-your-super-secret-jwt-key-change-in-production}
|
|
- JWT_EXPIRE_HOURS=168
|
|
# 存储配置 (RustFS S3兼容)
|
|
- RUSTFS_ENDPOINT=${RUSTFS_ENDPOINT:-rustfs:9000}
|
|
- RUSTFS_PUBLIC_URL=${RUSTFS_PUBLIC_URL:-http://localhost:9000}
|
|
- RUSTFS_ACCESS_KEY=${RUSTFS_ACCESS_KEY:-rustfsadmin}
|
|
- RUSTFS_SECRET_KEY=${RUSTFS_SECRET_KEY:-rustfsadmin123}
|
|
- RUSTFS_USE_SSL=${RUSTFS_USE_SSL:-false}
|
|
- RUSTFS_BUCKET_TEXTURES=${RUSTFS_BUCKET_TEXTURES:-carrot-skin-textures}
|
|
- RUSTFS_BUCKET_AVATARS=${RUSTFS_BUCKET_AVATARS:-carrot-skin-avatars}
|
|
# 安全配置
|
|
- SECURITY_ALLOWED_ORIGINS=${SECURITY_ALLOWED_ORIGINS:-*}
|
|
- SECURITY_ALLOWED_DOMAINS=${SECURITY_ALLOWED_DOMAINS:-localhost,127.0.0.1}
|
|
# 邮件配置
|
|
- EMAIL_ENABLED=${EMAIL_ENABLED:-false}
|
|
- EMAIL_SMTP_HOST=${EMAIL_SMTP_HOST:-}
|
|
- EMAIL_SMTP_PORT=${EMAIL_SMTP_PORT:-587}
|
|
- EMAIL_USERNAME=${EMAIL_USERNAME:-}
|
|
- EMAIL_PASSWORD=${EMAIL_PASSWORD:-}
|
|
- EMAIL_FROM_NAME=${EMAIL_FROM_NAME:-CarrotSkin}
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
networks:
|
|
- carrotskin-network
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/api/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 10s
|
|
|
|
# ==================== PostgreSQL 数据库 ====================
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
container_name: carrotskin-postgres
|
|
restart: unless-stopped
|
|
environment:
|
|
- POSTGRES_USER=carrotskin
|
|
- POSTGRES_PASSWORD=${DATABASE_PASSWORD:-carrotskin123}
|
|
- POSTGRES_DB=carrotskin
|
|
- PGDATA=/var/lib/postgresql/data/pgdata
|
|
volumes:
|
|
- postgres-data:/var/lib/postgresql/data
|
|
ports:
|
|
- "5432:5432"
|
|
networks:
|
|
- carrotskin-network
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U carrotskin -d carrotskin"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 10s
|
|
|
|
# ==================== Redis 缓存 ====================
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: carrotskin-redis
|
|
restart: unless-stopped
|
|
command: >
|
|
redis-server
|
|
--appendonly yes
|
|
--maxmemory 256mb
|
|
--maxmemory-policy allkeys-lru
|
|
${REDIS_PASSWORD:+--requirepass ${REDIS_PASSWORD}}
|
|
volumes:
|
|
- redis-data:/data
|
|
ports:
|
|
- "6379:6379"
|
|
networks:
|
|
- carrotskin-network
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 5s
|
|
|
|
# ==================== RustFS 对象存储====================
|
|
rustfs:
|
|
image: ghcr.io/rustfs/rustfs:latest
|
|
container_name: carrotskin-rustfs
|
|
restart: unless-stopped
|
|
command: >
|
|
server
|
|
--address 0.0.0.0:9000
|
|
--console-address 0.0.0.0:9001
|
|
--access-key ${RUSTFS_ACCESS_KEY:-rustfsadmin}
|
|
--secret-key ${RUSTFS_SECRET_KEY:-rustfsadmin123}
|
|
--data /data
|
|
volumes:
|
|
- rustfs-data:/data
|
|
ports:
|
|
- "9000:9000" # S3 API 端口
|
|
- "9001:9001" # 控制台端口
|
|
networks:
|
|
- carrotskin-network
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9000/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 10s
|
|
profiles:
|
|
- storage # 使用 --profile storage 启动
|
|
|
|
# RustFS 初始化服务 - 自动创建存储桶
|
|
rustfs-init:
|
|
image: minio/mc:latest
|
|
container_name: carrotskin-rustfs-init
|
|
depends_on:
|
|
rustfs:
|
|
condition: service_healthy
|
|
entrypoint: >
|
|
/bin/sh -c "
|
|
echo '等待 RustFS 启动...';
|
|
sleep 5;
|
|
mc alias set myrustfs http://rustfs:9000 $${RUSTFS_ACCESS_KEY} $${RUSTFS_SECRET_KEY};
|
|
echo '创建材质存储桶...';
|
|
mc mb myrustfs/$${RUSTFS_BUCKET_TEXTURES} --ignore-existing;
|
|
mc anonymous set download myrustfs/$${RUSTFS_BUCKET_TEXTURES};
|
|
echo '创建头像存储桶...';
|
|
mc mb myrustfs/$${RUSTFS_BUCKET_AVATARS} --ignore-existing;
|
|
mc anonymous set download myrustfs/$${RUSTFS_BUCKET_AVATARS};
|
|
echo '存储桶创建完成: $${RUSTFS_BUCKET_TEXTURES}, $${RUSTFS_BUCKET_AVATARS}';
|
|
"
|
|
environment:
|
|
- RUSTFS_ACCESS_KEY=${RUSTFS_ACCESS_KEY:-rustfsadmin}
|
|
- RUSTFS_SECRET_KEY=${RUSTFS_SECRET_KEY:-rustfsadmin123}
|
|
- RUSTFS_BUCKET_TEXTURES=${RUSTFS_BUCKET_TEXTURES:-carrot-skin-textures}
|
|
- RUSTFS_BUCKET_AVATARS=${RUSTFS_BUCKET_AVATARS:-carrot-skin-avatars}
|
|
networks:
|
|
- carrotskin-network
|
|
profiles:
|
|
- storage
|
|
|
|
# ==================== 数据卷 ====================
|
|
volumes:
|
|
postgres-data:
|
|
driver: local
|
|
redis-data:
|
|
driver: local
|
|
rustfs-data:
|
|
driver: local
|
|
|
|
# ==================== 网络 ====================
|
|
networks:
|
|
carrotskin-network:
|
|
driver: bridge
|
|
|