From f5907892bf0b6b39cd90c0a7b152cf1bd280c2e1 Mon Sep 17 00:00:00 2001 From: YANG JIANKUAN Date: Thu, 2 Apr 2026 13:39:21 +0800 Subject: [PATCH] feat: add Docker Compose setup with Dockerfiles for all services Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 3 ++ docker-compose.dev.yml | 45 ++++++++++++++++++++++++++++ docker-compose.yml | 57 ++++++++++++++++++++++++++++++++++++ packages/mcp/Dockerfile | 35 ++++++++++++++++++++++ packages/server/Dockerfile | 38 ++++++++++++++++++++++++ packages/web/Dockerfile | 17 +++++++++++ packages/web/nginx.conf | 25 ++++++++++++++++ scripts/migrate-and-start.sh | 9 ++++++ 8 files changed, 229 insertions(+) create mode 100644 docker-compose.dev.yml create mode 100644 docker-compose.yml create mode 100644 packages/mcp/Dockerfile create mode 100644 packages/server/Dockerfile create mode 100644 packages/web/Dockerfile create mode 100644 packages/web/nginx.conf create mode 100755 scripts/migrate-and-start.sh diff --git a/.gitignore b/.gitignore index 4274b51..e52f9d5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ dist/ .env *.log .DS_Store + +# Docker +docker-compose.override.yml diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..0ed952d --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,45 @@ +services: + postgres: + ports: + - "5432:5432" + + server: + build: + target: deps + command: sh -c "npx prisma generate --schema=prisma/schema.prisma && pnpm --filter @agent-fox/server dev" + volumes: + - ./packages/shared/src:/app/packages/shared/src + - ./packages/server/src:/app/packages/server/src + - ./prisma:/app/prisma + - ./tsconfig.base.json:/app/tsconfig.base.json + environment: + DATABASE_URL: postgresql://agentfox:agentfox@postgres:5432/agentfox + JWT_SECRET: dev-secret + JWT_REFRESH_SECRET: dev-refresh-secret + SERVER_PORT: "3000" + NODE_ENV: development + + mcp: + build: + target: deps + command: sh -c "npx prisma generate --schema=prisma/schema.prisma && pnpm --filter @agent-fox/mcp dev" + volumes: + - ./packages/shared/src:/app/packages/shared/src + - ./packages/mcp/src:/app/packages/mcp/src + - ./prisma:/app/prisma + - ./tsconfig.base.json:/app/tsconfig.base.json + environment: + DATABASE_URL: postgresql://agentfox:agentfox@postgres:5432/agentfox + MCP_PORT: "3001" + NODE_ENV: development + + web: + image: node:20-alpine + working_dir: /app + command: sh -c "corepack enable && corepack prepare pnpm@latest --activate && pnpm install && pnpm --filter @agent-fox/web dev -- --host 0.0.0.0" + volumes: + - .:/app + ports: + - "5173:5173" + environment: + NODE_ENV: development diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..254180f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,57 @@ +services: + postgres: + image: postgres:16-alpine + environment: + POSTGRES_USER: agentfox + POSTGRES_PASSWORD: agentfox + POSTGRES_DB: agentfox + volumes: + - pgdata:/var/lib/postgresql/data + ports: + - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U agentfox"] + interval: 5s + timeout: 5s + retries: 5 + + server: + build: + context: . + dockerfile: packages/server/Dockerfile + environment: + DATABASE_URL: postgresql://agentfox:agentfox@postgres:5432/agentfox + JWT_SECRET: ${JWT_SECRET:-change-me-in-production} + JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET:-change-me-refresh-in-production} + SERVER_PORT: "3000" + ports: + - "3000:3000" + depends_on: + postgres: + condition: service_healthy + + mcp: + build: + context: . + dockerfile: packages/mcp/Dockerfile + environment: + DATABASE_URL: postgresql://agentfox:agentfox@postgres:5432/agentfox + MCP_PORT: "3001" + ports: + - "3001:3001" + depends_on: + postgres: + condition: service_healthy + + web: + build: + context: . + dockerfile: packages/web/Dockerfile + ports: + - "80:80" + depends_on: + - server + - mcp + +volumes: + pgdata: diff --git a/packages/mcp/Dockerfile b/packages/mcp/Dockerfile new file mode 100644 index 0000000..93a12b9 --- /dev/null +++ b/packages/mcp/Dockerfile @@ -0,0 +1,35 @@ +FROM node:20-alpine AS base +RUN corepack enable && corepack prepare pnpm@latest --activate +WORKDIR /app + +FROM base AS deps +COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./ +COPY packages/shared/package.json packages/shared/ +COPY packages/mcp/package.json packages/mcp/ +COPY prisma/ prisma/ +RUN pnpm install --frozen-lockfile + +FROM base AS build +COPY --from=deps /app/ ./ +COPY packages/shared/ packages/shared/ +COPY packages/mcp/ packages/mcp/ +COPY prisma/ prisma/ +COPY tsconfig.base.json ./ +RUN npx prisma generate --schema=prisma/schema.prisma +RUN pnpm --filter @agent-fox/shared build +RUN pnpm --filter @agent-fox/mcp build + +FROM node:20-alpine AS runtime +WORKDIR /app +COPY --from=build /app/node_modules ./node_modules +COPY --from=build /app/packages/shared/dist ./packages/shared/dist +COPY --from=build /app/packages/shared/node_modules ./packages/shared/node_modules +COPY --from=build /app/packages/shared/package.json ./packages/shared/ +COPY --from=build /app/packages/mcp/dist ./packages/mcp/dist +COPY --from=build /app/packages/mcp/node_modules ./packages/mcp/node_modules +COPY --from=build /app/packages/mcp/package.json ./packages/mcp/ +COPY --from=build /app/prisma ./prisma + +WORKDIR /app/packages/mcp +EXPOSE 3001 +CMD ["node", "dist/index.js"] diff --git a/packages/server/Dockerfile b/packages/server/Dockerfile new file mode 100644 index 0000000..aa4c0b2 --- /dev/null +++ b/packages/server/Dockerfile @@ -0,0 +1,38 @@ +FROM node:20-alpine AS base +RUN corepack enable && corepack prepare pnpm@latest --activate +WORKDIR /app + +FROM base AS deps +COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./ +COPY packages/shared/package.json packages/shared/ +COPY packages/server/package.json packages/server/ +COPY prisma/ prisma/ +RUN pnpm install --frozen-lockfile + +FROM base AS build +COPY --from=deps /app/ ./ +COPY packages/shared/ packages/shared/ +COPY packages/server/ packages/server/ +COPY prisma/ prisma/ +COPY tsconfig.base.json ./ +RUN npx prisma generate --schema=prisma/schema.prisma +RUN pnpm --filter @agent-fox/shared build +RUN pnpm --filter @agent-fox/server build + +FROM node:20-alpine AS runtime +WORKDIR /app +COPY --from=build /app/node_modules ./node_modules +COPY --from=build /app/packages/shared/dist ./packages/shared/dist +COPY --from=build /app/packages/shared/node_modules ./packages/shared/node_modules +COPY --from=build /app/packages/shared/package.json ./packages/shared/ +COPY --from=build /app/packages/server/dist ./packages/server/dist +COPY --from=build /app/packages/server/node_modules ./packages/server/node_modules +COPY --from=build /app/packages/server/package.json ./packages/server/ +COPY --from=build /app/prisma ./prisma +COPY scripts/migrate-and-start.sh ./scripts/ + +RUN chmod +x scripts/migrate-and-start.sh +RUN npm install -g prisma@6 + +EXPOSE 3000 +CMD ["sh", "scripts/migrate-and-start.sh"] diff --git a/packages/web/Dockerfile b/packages/web/Dockerfile new file mode 100644 index 0000000..05bc42a --- /dev/null +++ b/packages/web/Dockerfile @@ -0,0 +1,17 @@ +FROM node:20-alpine AS build +RUN corepack enable && corepack prepare pnpm@latest --activate +WORKDIR /app + +COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./ +COPY packages/web/package.json packages/web/ +RUN pnpm install --frozen-lockfile --filter @agent-fox/web... + +COPY packages/web/ packages/web/ +COPY tsconfig.base.json ./ +RUN pnpm --filter @agent-fox/web build + +FROM nginx:alpine +COPY --from=build /app/packages/web/dist /usr/share/nginx/html +COPY packages/web/nginx.conf /etc/nginx/conf.d/default.conf +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/packages/web/nginx.conf b/packages/web/nginx.conf new file mode 100644 index 0000000..66104fa --- /dev/null +++ b/packages/web/nginx.conf @@ -0,0 +1,25 @@ +server { + listen 80; + root /usr/share/nginx/html; + index index.html; + + location /api/ { + proxy_pass http://server:3000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + + location /mcp/ { + proxy_pass http://mcp:3001; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_http_version 1.1; + proxy_set_header Connection ''; + proxy_buffering off; + proxy_cache off; + } + + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/scripts/migrate-and-start.sh b/scripts/migrate-and-start.sh new file mode 100755 index 0000000..d6c86ff --- /dev/null +++ b/scripts/migrate-and-start.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -e + +echo "Running database migrations..." +npx prisma migrate deploy --schema=prisma/schema.prisma + +echo "Starting server..." +cd /app/packages/server +exec node dist/index.js