部署

Docker Compose(本地开发)

使用 Docker Compose 在本地运行完整的 Makeugcads 服务栈

本指南介绍如何在本地机器上使用 Docker Compose 验证完整的 Makeugcads 服务栈。无需云账号或付费 License。

本地验证与生产部署路径不同:本地通常用 docker compose -f compose.yml -f compose.local.yml --profile legacy-postgres up --build 从源码构建并启用内置 PostgreSQL;生产 compose.yml 拉取 GHCR 预构建镜像,并通过 Dokploy Databases 注入 DATABASE_URL / LANGGRAPH_DATABASE_URL。不要把包含真实密钥或本地专用配置的 override 提交到仓库。

本地验证与生产 GHCR 的区别

场景镜像来源推荐命令说明
本地开发 / 验证本机从源码构建docker compose -f compose.yml -f compose.local.yml --profile legacy-postgres up --build用本地 override 把 web / agents 改成 build:,并显式启用内置 PostgreSQL
生产 DokployGHCR 预构建镜像Dokploy Redeploy拉取 webagentsmigrationsrbac-init,并连接 Dokploy Databases PostgreSQL

生产 compose.yml 使用以下镜像变量:

GHCR_IMAGE_PREFIX=ghcr.io/chenhaonan-eth/ugcad
IMAGE_TAG=latest

对应镜像为:

${GHCR_IMAGE_PREFIX}-web:${IMAGE_TAG}
${GHCR_IMAGE_PREFIX}-agents:${IMAGE_TAG}
${GHCR_IMAGE_PREFIX}-migrations:${IMAGE_TAG}
${GHCR_IMAGE_PREFIX}-rbac-init:${IMAGE_TAG}

前置要求

  • Docker Desktop(Windows / macOS)或 Docker Engine + Compose(Linux)
  • Git
  • LLM API 密钥(OpenAI 或兼容接口)

Step 1 — 克隆仓库

git clone https://github.com/chenhaonan-eth/ugcad.git
cd ugcad

Step 2 — 创建 .env 文件

创建 .env 文件并填入密钥。不要提交 .env,也不要把真实密钥写入文档、Compose 文件或 override 文件:

# ── 镜像选择(生产拉 GHCR 时使用;本地 build override 可忽略) ─────────
GHCR_IMAGE_PREFIX=ghcr.io/chenhaonan-eth/ugcad
IMAGE_TAG=latest

# ── 基础设施 ──────────────────────────────────────────
POSTGRES_PASSWORD=your_strong_password_here
DATABASE_URL=postgresql://ugcad:your_strong_password_here@postgres:5432/ugcad
LANGGRAPH_DATABASE_URL=postgresql://ugcad:your_strong_password_here@postgres:5432/langgraph
REDIS_PASSWORD=your_strong_redis_password

# ── Web ───────────────────────────────────────────────
AUTH_SECRET=your_32_char_secret_here_generate_with_openssl
NEXT_PUBLIC_APP_URL=http://localhost:3000

# ── 内部服务认证 ────────────────────────────────────────
AGENTS_SHARED_SECRET=random_shared_secret

# ── LLM ───────────────────────────────────────────────
OPENAI_API_KEY=sk-your-key-here
# 如果使用第三方 OpenAI 兼容接口:
# OPENAI_BASE_URL=https://your-provider.com/v1
# OPENAI_MODEL=gpt-4o

生成强密钥:

openssl rand -base64 32   # AUTH_SECRET
openssl rand -hex 20      # 各类密码

Step 3 — 本地源码构建 override

生产 compose.yml 默认拉取 GHCR 镜像。如果要在本地从当前源码构建,请创建本地专用 compose.local.yml(不要提交真实密钥;如需长期使用可加入本机忽略规则):

services:
  agents:
    build:
      context: .
      dockerfile: docker/Dockerfile.agents-dev
    image: ugcad-agents:local
    ports:
      - "2024:8000"

  web:
    build:
      context: .
      dockerfile: apps/web/Dockerfile
      args:
        NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-http://localhost:3000}
        NEXT_PUBLIC_APP_NAME: ${NEXT_PUBLIC_APP_NAME:-Makeugcads}
        NEXT_PUBLIC_THEME: ${NEXT_PUBLIC_THEME:-huxibo}
        NEXT_PUBLIC_APPEARANCE: ${NEXT_PUBLIC_APPEARANCE:-system}
        NEXT_PUBLIC_DEFAULT_LOCALE: ${NEXT_PUBLIC_DEFAULT_LOCALE:-en}
    image: ugcad-web:local
    ports:
      - "3000:3000"

Step 4 — 启动所有服务

本地源码构建并启用内置 PostgreSQL:

docker compose -f compose.yml -f compose.local.yml --profile legacy-postgres up --build

如果只想验证生产 GHCR 镜像是否可拉取,也可以直接运行:

docker compose up

首次源码构建会构建 web(Next.js)和 agents(LangGraph dev 服务器)镜像,视网速需要 5–15 分钟。

agents 本地 override 使用 docker/Dockerfile.agents-dev,即 langgraph dev 模式,无需付费 LangSmith License。

Step 5 — 应用数据库迁移

web 容器使用 Next.js standalone 构建,不含 drizzle-kit。本地内置 PostgreSQL 场景也复用仓库迁移脚本,确保写入 public.__ugcad_migrations,与生产 migrations 镜像的记录机制一致:

POSTGRES_PASSWORD=your_strong_password_here bash scripts/migrate-postgres.sh --compose

首次空库启动后执行一次即可。迁移脚本会按 apps/web/src/config/db/migrations/meta/_journal.json 顺序执行 SQL;重复运行时,已记录的 migration 会显示 skipped,新 migration 会显示 applied。不要再用手动 for f in ... psql 循环绕过 public.__ugcad_migrations

Step 6 — 验证并访问

检查服务状态:

docker compose ps

使用 compose.local.yml override 时,确认端口绑定正确,应看到 0.0.0.0:3000->3000/tcp0.0.0.0:2024->8000/tcp

NAME                  SERVICE    STATUS    PORTS
<project>-web-1       web        running   0.0.0.0:3000->3000/tcp
<project>-agents-1    agents     running   0.0.0.0:2024->8000/tcp
<project>-postgres-1  postgres   running   5432/tcp
<project>-redis-1     redis      running   6379/tcp

使用 compose.local.yml override 时,浏览器访问 **http://localhost:3000**。

使用 compose.local.yml override 时,可通过本机端口测试 agents API:

curl http://localhost:2024/ok
# → {"ok":true}

常见问题

端口显示 3000/tcp 而非 0.0.0.0:3000->3000/tcp

Docker Desktop on Windows 偶发性问题,端口绑定未生效。修复:

docker compose restart web

agents 容器报 "License verification failed"

你使用了付费版 langchain/langgraphjs-api 镜像。切换到 dev Dockerfile。本地 override 应使用 docker/Dockerfile.agents-devlanggraph dev 模式,无需 License)。

web 调用 agents 时 Connection refused

agents 容器可能绑定到 IPv6 loopback(::1)而非 0.0.0.0。检查 Dockerfile CMD 是否包含 --host 0.0.0.0

CMD ["npx", "@langchain/langgraph-cli", "dev",
     "--port", "8000", "--host", "0.0.0.0", "--config", "langgraph.json"]

登录后出现 schema 错误(column does not exist)

如果这是空库初始化,重新创建测试库或测试 volume 后再执行迁移步骤:

POSTGRES_PASSWORD=your_strong_password_here bash scripts/migrate-postgres.sh --compose

如果数据库已经有表但 public.__ugcad_migrations 为空或与 journal 不一致,先阅读 apps/web/src/config/db/migrations/README.md 的 baseline 说明,不要直接把本地 baseline 问题当成生产 schema 缺失。

更新

本地验证新代码时拉取并重新构建:

git pull
docker compose -f compose.yml -f compose.local.yml --profile legacy-postgres up --build -d
POSTGRES_PASSWORD=your_strong_password_here bash scripts/migrate-postgres.sh --compose

生产更新不在服务器上 build。由 GitHub Actions 推送新的 GHCR webagentsmigrationsrbac-init 四个镜像后,让 Dokploy 重新拉取 GHCR_IMAGE_PREFIX + IMAGE_TAG 指向的镜像,并通过一次性 migrations / rbac-init 服务完成部署任务。