fix: Docker deployment optimization
- Replace postgres:15-alpine with pgvector/pgvector:pg15 (built-in vector extension) - Remove init-db.sh (pgvector image includes extension, SQL init script instead) - Add multi-stage Dockerfile for backend (development/runtime targets) - Add development stage to frontend Dockerfile - Update .env.example with correct passwords and Docker-internal URLs - Add POSTGRES_PASSWORD/REDIS_PASSWORD to .env for Docker Compose - Use named volume for frontend node_modules - Add backend healthcheck to docker-compose.yml
This commit is contained in:
parent
33aecc0cb1
commit
218ece564d
21
.env.example
21
.env.example
|
|
@ -4,14 +4,26 @@
|
|||
# =============================================================================
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 数据库(PostgreSQL)
|
||||
# 数据库密码(Docker Compose 引用此变量)
|
||||
# -----------------------------------------------------------------------------
|
||||
DATABASE_URL=postgresql+asyncpg://postgres:postgres123@db:5432/geo_platform
|
||||
POSTGRES_PASSWORD=geo_pg_dev_2026
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Redis 密码(Docker Compose 引用此变量)
|
||||
# -----------------------------------------------------------------------------
|
||||
REDIS_PASSWORD=geo_redis_dev_2026
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 数据库(PostgreSQL + pgvector)
|
||||
# Docker 内部使用 db:5432,本地直连使用 localhost:5433
|
||||
# -----------------------------------------------------------------------------
|
||||
DATABASE_URL=postgresql+asyncpg://postgres:geo_pg_dev_2026@db:5432/geo_platform
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Redis(缓存 / 任务队列)
|
||||
# Docker 内部使用 redis:6379,本地直连使用 localhost:6380
|
||||
# -----------------------------------------------------------------------------
|
||||
REDIS_URL=redis://redis:6379/0
|
||||
REDIS_URL=redis://:geo_redis_dev_2026@redis:6379/0
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# JWT 认证密钥
|
||||
|
|
@ -80,11 +92,10 @@ BAIDU_QIANFAN_API_KEY=your-baidu-qianfan-api-key-here
|
|||
BAIDU_QIANFAN_SECRET_KEY=your-baidu-qianfan-secret-key-here
|
||||
|
||||
# 豆包(字节跳动)
|
||||
DOUBAO_API_KEY=your-doubao-api-key-here
|
||||
DOUBAO_API_KEY=your-doubbo-api-key-here
|
||||
DOUBAO_ENDPOINT_ID=your-doubao-endpoint-id-here
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# API 调用频率限制
|
||||
# -----------------------------------------------------------------------------
|
||||
# 每分钟最大请求数(防止触发平台限速)
|
||||
API_RATE_LIMIT_RPM=10
|
||||
|
|
|
|||
|
|
@ -1,10 +1,26 @@
|
|||
FROM python:3.11-slim
|
||||
FROM python:3.11-slim AS base
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# 安装系统依赖(Playwright需要)
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY requirements.txt .
|
||||
|
||||
FROM base AS development
|
||||
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||
|
||||
FROM base AS runtime
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
wget \
|
||||
gnupg \
|
||||
libglib2.0-0 \
|
||||
|
|
@ -24,20 +40,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
libasound2 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 复制并安装Python依赖
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# 安装Playwright浏览器
|
||||
RUN playwright install chromium
|
||||
RUN playwright install-deps chromium
|
||||
|
||||
# 复制应用代码
|
||||
COPY . .
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
||||
CMD curl -f http://localhost:8000/health || exit 1
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== Installing pgvector extension for PostgreSQL ==="
|
||||
|
||||
echo "[1/5] Installing build dependencies..."
|
||||
apk add --no-cache build-base git clang llvm-dev postgresql-dev
|
||||
|
||||
echo "[2/5] Cloning pgvector v0.5.1..."
|
||||
cd /tmp
|
||||
rm -rf pgvector
|
||||
git clone --branch v0.5.1 --depth 1 https://github.com/pgvector/pgvector.git
|
||||
|
||||
echo "[3/5] Compiling and installing pgvector..."
|
||||
cd /tmp/pgvector
|
||||
make
|
||||
make install
|
||||
|
||||
echo "[4/5] Cleaning up build dependencies..."
|
||||
cd /
|
||||
rm -rf /tmp/pgvector
|
||||
apk del build-base git clang llvm-dev postgresql-dev
|
||||
|
||||
echo "[5/5] Creating vector extension in database..."
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||
CREATE EXTENSION IF NOT EXISTS vector;
|
||||
EOSQL
|
||||
|
||||
echo "=== pgvector installation complete ==="
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
services:
|
||||
db:
|
||||
image: postgres:15-alpine
|
||||
image: pgvector/pgvector:pg15
|
||||
container_name: geo_db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
|
|
@ -11,7 +11,7 @@ services:
|
|||
- "5433:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./backend/init-db.sh:/docker-entrypoint-initdb.d/01-install-pgvector.sh
|
||||
- ./docker/init-db:/docker-entrypoint-initdb.d
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres -d geo_platform"]
|
||||
interval: 5s
|
||||
|
|
@ -48,7 +48,10 @@ services:
|
|||
memory: 64m
|
||||
|
||||
backend:
|
||||
build: ./backend
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
target: ${BACKEND_TARGET:-runtime}
|
||||
container_name: geo_backend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
|
|
@ -66,6 +69,12 @@ services:
|
|||
redis:
|
||||
condition: service_healthy
|
||||
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
start_period: 30s
|
||||
retries: 3
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
|
|
@ -75,16 +84,21 @@ services:
|
|||
memory: 256m
|
||||
|
||||
frontend:
|
||||
build: ./frontend
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile
|
||||
target: ${FRONTEND_TARGET:-development}
|
||||
container_name: geo_frontend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3000:3000"
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
NEXT_PUBLIC_API_URL: http://localhost:8000
|
||||
volumes:
|
||||
- ./frontend:/app
|
||||
- /app/node_modules
|
||||
- frontend_node_modules:/app/node_modules
|
||||
depends_on:
|
||||
- backend
|
||||
command: npm run dev
|
||||
|
|
@ -99,3 +113,4 @@ services:
|
|||
volumes:
|
||||
postgres_data:
|
||||
redis_data:
|
||||
frontend_node_modules:
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
CREATE EXTENSION IF NOT EXISTS vector;
|
||||
|
|
@ -1,32 +1,35 @@
|
|||
# ============================================================
|
||||
# Stage 1: Builder — 构建 Next.js 生产产物
|
||||
# ============================================================
|
||||
FROM node:20-alpine AS development
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["npm", "run", "dev"]
|
||||
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# 安装依赖(利用缓存层)
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
# 复制源码并构建
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# ============================================================
|
||||
# Stage 2: Runner — 只保留运行时必要文件
|
||||
# ============================================================
|
||||
FROM node:20-alpine AS runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
# 创建非 root 用户运行应用
|
||||
RUN addgroup --system --gid 1001 nodejs \
|
||||
&& adduser --system --uid 1001 nextjs
|
||||
|
||||
# 复制 standalone 构建产物
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
|
||||
|
|
@ -38,7 +41,6 @@ EXPOSE 3000
|
|||
ENV PORT=3000
|
||||
ENV HOSTNAME="0.0.0.0"
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 \
|
||||
CMD wget -qO- http://localhost:3000/ || exit 1
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue