Dockerfile 使用多阶段构建(build 阶段 → release 阶段)前端配置
错误配置:
FROM node:18-alpine AS base# 设置代理环境变量(让 curl / npm / git 等自动走代理)
ENV HTTP_PROXY=http://172.17.0.1:7890
ENV HTTPS_PROXY=http://172.17.0.1:7890
ENV http_proxy=http://172.17.0.1:7890
ENV https_proxy=http://172.17.0.1:7890FROM base AS depsRUN apk add --no-cache libc6-compat
WORKDIR /appCOPY package.json ./# 配置 npm 使用代理
RUN npm config set proxy http://172.17.0.1:7890 && \npm config set https-proxy http://172.17.0.1:7890 && \npm install# If you want yarn update and install uncomment the bellow# RUN yarn install && yarn upgradeFROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .RUN npm run buildFROM base AS runner
WORKDIR /appENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjsCOPY --from=builder /app/public ./publicRUN mkdir .next
RUN chown nextjs:nodejs .nextCOPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/staticUSER nextjsEXPOSE 3000ENV PORT 3000CMD ["node", "server.js"]
frontend
Dockerfile 同样存在“运行阶段继承了构建阶段代理”的问题,解决思路和 Python 后端一样:
✅ 目标
- 构建阶段使用代理(加速
npm install
等) - 运行阶段彻底移除代理环境变量,避免请求出错(比如
502
)
✅ 推荐的修改版 Dockerfile
# ================== 构建阶段 base:带代理 ==================
FROM node:18-alpine AS base# 支持构建参数(build args)
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG http_proxy
ARG https_proxy# 设置环境变量,用于构建阶段
ENV HTTP_PROXY=${HTTP_PROXY}
ENV HTTPS_PROXY=${HTTPS_PROXY}
ENV http_proxy=${http_proxy}
ENV https_proxy=${https_proxy}# ================== deps 阶段:安装依赖 ==================
FROM base AS depsRUN apk add --no-cache libc6-compat
WORKDIR /appCOPY package.json ./# 显式设置 npm 代理
RUN npm config set proxy ${http_proxy} && \npm config set https-proxy ${https_proxy} && \npm install# ================== builder 阶段:构建项目 ==================
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .RUN npm run build# ================== runner 阶段:纯净运行,无代理 ==================
FROM node:18-alpine AS runner
WORKDIR /app# 设置运行环境
ENV NODE_ENV=production
ENV PORT=3000# ❌ 清除任何构建阶段的代理环境变量
ENV HTTP_PROXY=""
ENV HTTPS_PROXY=""
ENV http_proxy=""
ENV https_proxy=""# 创建运行用户
RUN addgroup --system --gid 1001 nodejs && \adduser --system --uid 1001 nextjs# 复制构建产物
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/staticRUN mkdir .next && chown nextjs:nodejs .next
USER nextjsEXPOSE 3000CMD ["node", "server.js"]
✅ docker-compose.yml 配套写法
services:frontend:build:context: ./frontenddockerfile: Dockerfileargs:HTTP_PROXY: http://172.17.0.1:7890HTTPS_PROXY: http://172.17.0.1:7890http_proxy: http://172.17.0.1:7890https_proxy: http://172.17.0.1:7890ports:- "3000:3000"
✅ 运行阶段验证代理是否已禁用
docker-compose exec frontend sh
printenv | grep -i proxy
输出应为空或如下:
http_proxy=
https_proxy=
🔍 为什么有必要这样做?
因为:
- 构建阶段需要代理:访问
npm
、GitHub
、PyPI
等; - 运行阶段不需要代理:请求外部 API 时若走代理,会因为代理拒绝连接导致 502、504、403 等错误;
- Docker 多阶段构建 会自动继承环境变量,所以必须手动清除;
前端目录中的Dockerfile
完整配置:
# ================== 构建阶段 base:带代理 ==================
FROM node:18-alpine AS base# 支持构建参数(build args)
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG http_proxy
ARG https_proxy# 设置环境变量,用于构建阶段
ENV HTTP_PROXY=${HTTP_PROXY}
ENV HTTPS_PROXY=${HTTPS_PROXY}
ENV http_proxy=${http_proxy}
ENV https_proxy=${https_proxy}# ================== deps 阶段:安装依赖 ==================
FROM base AS depsRUN apk add --no-cache libc6-compat
WORKDIR /appCOPY package.json ./# 显式设置 npm 代理
RUN npm config set proxy ${http_proxy} && \npm config set https-proxy ${https_proxy} && \npm install# If you want yarn update and install uncomment the bellow# RUN yarn install && yarn upgrade# ================== builder 阶段:构建项目 ==================
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .RUN npm run build# ================== runner 阶段:纯净运行,无代理 ==================
FROM base AS runner
WORKDIR /appENV NODE_ENV production# ❌ 清除任何构建阶段的代理环境变量
ENV HTTP_PROXY=""
ENV HTTPS_PROXY=""
ENV http_proxy=""
ENV https_proxy=""# 创建运行用户
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjsCOPY --from=builder /app/public ./publicRUN mkdir .next
RUN chown nextjs:nodejs .nextCOPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/staticUSER nextjsEXPOSE 3000ENV PORT 3000CMD ["node", "server.js"]
docker-compose.yaml
完整配置:
version: '3.8'services:qdrant:image: qdrant/qdrant:latestcontainer_name: qdrantports:- 6333:6333- 6334:6334networks:- ragsaas-networkmongodb:image: mongo:latestcontainer_name: mongodbports:- 27017:27017environment:MONGO_INITDB_ROOT_USERNAME: adminMONGO_INITDB_ROOT_PASSWORD: passwordnetworks:- ragsaas-networkvolumes:- mongodb_data:/data/dbarizephoenix:image: arizephoenix/phoenix:latestcontainer_name: arizephoenixports:- '6006:6006'- '4317:4317'networks:- ragsaas-networkbackend:build:context: ./backenddockerfile: Dockerfileargs:http_proxy: http://172.17.0.1:7890https_proxy: http://172.17.0.1:7890image: ragsaas/backend:latestcontainer_name: backendports:- '8000:8000'environment:# MongoDB ConfigurationMONGODB_NAME: RAGSAASMONGODB_URI: mongodb://admin:password@mongodb:27017/# Qdrant ConfigurationQDRANT_COLLECTION: defaultQDRANT_URL: http://qdrant:6333# QDRANT_API_KEY:OPENAI_API_KEY:# Backend Application ConfigurationMODEL_PROVIDER: openaiMODEL: gpt-4o-miniEMBEDDING_MODEL: text-embedding-3-smallEMBEDDING_DIM: 1536# FILESERVER_URL_PREFIX: http://backend:8000/api/filesFILESERVER_URL_PREFIX: http://159.75.85.9:8000/api/filesSYSTEM_PROMPT: 'You are a helpful assistant who helps users with their questions.'APP_HOST: 0.0.0.0APP_PORT: 8000ADMIN_EMAIL: admin@ragsaas.comADMIN_PASSWORD: ragsaasJWT_SECRET_KEY: secret123JWT_REFRESH_SECRET_KEY: secret123ARIZE_PHOENIX_ENDPOINT: http://arizephoenix:6006depends_on:- qdrant- mongodb- arizephoenixnetworks:- ragsaas-networkfrontend:build:context: ./frontenddockerfile: Dockerfileargs:HTTP_PROXY: http://172.17.0.1:7890HTTPS_PROXY: http://172.17.0.1:7890http_proxy: http://172.17.0.1:7890https_proxy: http://172.17.0.1:7890image: ragsaas/frontend:latestcontainer_name: frontendports:- '3000:3000'environment:# NEXT_PUBLIC_SERVER_URL: http://backend:8000# NEXT_PUBLIC_CHAT_API: http://backend:8000/api/chatNEXT_PUBLIC_SERVER_URL: http://159.75.85.9:8000NEXT_PUBLIC_CHAT_API: http://159.75.85.9:8000/api/chatHOST: 0.0.0.0 # 👈 关键配置,告诉 nextjs 启动时监听所有地址depends_on:- backendnetworks:- ragsaas-networknetworks:ragsaas-network:name: ragsaas-networkdriver: bridgevolumes:mongodb_data: