fix: Docker 构建改用 npm 替代 pnpm + 补全 OAuth/Redis 环境变量
- Dockerfile 全部改为 npm install + 全局 tsc,解决 pnpm 符号链接问题 - docker-compose 添加 Redis 服务、OAuth 环境变量透传、web 端口改为可配置 - MCP URL 改用 window.location.origin 适配反向代理 - tsconfig 添加 paths 映射解决 Docker 内模块引用 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,36 +1,35 @@
|
||||
FROM node:20-alpine AS base
|
||||
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
FROM node:20-alpine AS build
|
||||
RUN npm install -g typescript@5
|
||||
WORKDIR /app
|
||||
|
||||
FROM base AS deps
|
||||
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json tsconfig.base.json ./
|
||||
COPY packages/shared/package.json packages/shared/
|
||||
COPY packages/shared/tsconfig.json packages/shared/
|
||||
COPY packages/mcp/package.json packages/mcp/
|
||||
COPY packages/mcp/tsconfig.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
|
||||
COPY prisma/ prisma/
|
||||
|
||||
# shared: 安装依赖 + prisma generate
|
||||
COPY packages/shared/package.json packages/shared/tsconfig.json packages/shared/
|
||||
RUN cd packages/shared && npm install && npx prisma generate --schema=../../prisma/schema.prisma
|
||||
|
||||
# mcp: 安装依赖(workspace:* → file: 引用)
|
||||
COPY packages/mcp/package.json packages/mcp/tsconfig.json packages/mcp/
|
||||
RUN cd packages/mcp && sed -i 's|"workspace:\*"|"file:../shared"|g' package.json && npm install
|
||||
|
||||
# 拷贝源码 + 编译
|
||||
COPY packages/shared/src/ packages/shared/src/
|
||||
COPY packages/mcp/src/ packages/mcp/src/
|
||||
|
||||
RUN tsc -p packages/shared/tsconfig.json
|
||||
RUN tsc -p packages/mcp/tsconfig.json
|
||||
|
||||
# --- 精简运行时镜像 ---
|
||||
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/shared/node_modules ./packages/shared/node_modules
|
||||
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
|
||||
COPY --from=build /app/packages/mcp/node_modules ./packages/mcp/node_modules
|
||||
|
||||
WORKDIR /app/packages/mcp
|
||||
EXPOSE 3001
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
"rootDir": "src",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@agent-fox/shared": ["../shared/dist"]
|
||||
}
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
@@ -1,40 +1,39 @@
|
||||
FROM node:20-alpine AS base
|
||||
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
FROM node:20-alpine AS build
|
||||
RUN npm install -g typescript@5
|
||||
WORKDIR /app
|
||||
|
||||
FROM base AS deps
|
||||
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json tsconfig.base.json ./
|
||||
COPY packages/shared/package.json packages/shared/
|
||||
COPY packages/shared/tsconfig.json packages/shared/
|
||||
COPY packages/server/package.json packages/server/
|
||||
COPY packages/server/tsconfig.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
|
||||
COPY prisma/ prisma/
|
||||
|
||||
# shared: 安装依赖 + prisma generate
|
||||
COPY packages/shared/package.json packages/shared/tsconfig.json packages/shared/
|
||||
RUN cd packages/shared && npm install && npx prisma generate --schema=../../prisma/schema.prisma
|
||||
|
||||
# server: 安装依赖(workspace:* → file: 引用)
|
||||
COPY packages/server/package.json packages/server/tsconfig.json packages/server/
|
||||
RUN cd packages/server && sed -i 's|"workspace:\*"|"file:../shared"|g' package.json && npm install
|
||||
|
||||
# 拷贝源码 + 编译
|
||||
COPY packages/shared/src/ packages/shared/src/
|
||||
COPY packages/server/src/ packages/server/src/
|
||||
|
||||
RUN tsc -p packages/shared/tsconfig.json
|
||||
RUN tsc -p packages/server/tsconfig.json
|
||||
|
||||
# --- 精简运行时镜像 ---
|
||||
FROM node:20-alpine AS runtime
|
||||
RUN npm install -g prisma@6
|
||||
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/shared/node_modules ./packages/shared/node_modules
|
||||
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/packages/server/node_modules ./packages/server/node_modules
|
||||
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"]
|
||||
|
||||
@@ -122,7 +122,7 @@ export async function parseOpenApiDocument(input: string | object): Promise<Pars
|
||||
if (typeof input === 'string' && input.startsWith('http')) {
|
||||
const res = await fetch(input);
|
||||
if (!res.ok) throw new Error(`Failed to fetch spec from URL: ${res.status} ${res.statusText}`);
|
||||
specInput = await res.json();
|
||||
specInput = await res.json() as object;
|
||||
}
|
||||
|
||||
// Bundle resolves all $refs into a single document, then dereference inlines them
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
"rootDir": "src",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@agent-fox/shared": ["../shared/dist"]
|
||||
}
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
FROM node:20-alpine AS build
|
||||
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
WORKDIR /app
|
||||
WORKDIR /app/packages/web
|
||||
|
||||
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/package.json ./
|
||||
RUN npm install
|
||||
|
||||
COPY packages/web/ packages/web/
|
||||
COPY tsconfig.base.json ./
|
||||
RUN pnpm --filter @agent-fox/web build
|
||||
COPY packages/web/src/ ./src/
|
||||
COPY packages/web/index.html ./
|
||||
COPY packages/web/vite.config.ts ./
|
||||
COPY packages/web/tsconfig.json ./
|
||||
COPY tsconfig.base.json /app/
|
||||
|
||||
RUN npx vite build
|
||||
|
||||
FROM nginx:alpine
|
||||
COPY --from=build /app/packages/web/dist /usr/share/nginx/html
|
||||
|
||||
@@ -10,8 +10,7 @@ export default function McpIntegration({ project }: { project: Project }) {
|
||||
const [copied, setCopied] = useState<string | null>(null);
|
||||
const { onOpenSettings } = useLayoutContext();
|
||||
const { t } = useI18n();
|
||||
const mcpHost = window.location.hostname;
|
||||
const mcpUrl = `http://${mcpHost}:3001/mcp/${project.id}`;
|
||||
const mcpUrl = `${window.location.origin}/mcp/${project.id}`;
|
||||
|
||||
const { data: keyStatus } = useQuery({
|
||||
queryKey: ['api-key-status'],
|
||||
|
||||
Reference in New Issue
Block a user