Dockerfile 使用多阶段构建(build 阶段 → release 阶段)前端配置

发布于:2025-06-06 ⋅ 阅读:(20) ⋅ 点赞:(0)

错误配置:

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:7890

FROM base AS deps

RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY 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 upgrade



FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

RUN npm run build

FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public

RUN mkdir .next
RUN chown nextjs:nodejs .next

COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000

CMD ["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 deps

RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY 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/static

RUN mkdir .next && chown nextjs:nodejs .next
USER nextjs

EXPOSE 3000

CMD ["node", "server.js"]

✅ docker-compose.yml 配套写法

services:
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
      args:
        HTTP_PROXY: http://172.17.0.1:7890
        HTTPS_PROXY: http://172.17.0.1:7890
        http_proxy: http://172.17.0.1:7890
        https_proxy: http://172.17.0.1:7890
    ports:
      - "3000:3000"

✅ 运行阶段验证代理是否已禁用

docker-compose exec frontend sh
printenv | grep -i proxy

输出应为空或如下:

http_proxy=
https_proxy=

🔍 为什么有必要这样做?

因为:

  • 构建阶段需要代理:访问 npmGitHubPyPI 等;
  • 运行阶段不需要代理:请求外部 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 deps

RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY 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 /app

ENV 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 nextjs

COPY --from=builder /app/public ./public

RUN mkdir .next
RUN chown nextjs:nodejs .next

COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000

CMD ["node", "server.js"]

docker-compose.yaml完整配置:

version: '3.8'

services:
  qdrant:
    image: qdrant/qdrant:latest
    container_name: qdrant
    ports:
      - 6333:6333
      - 6334:6334
    networks:
      - ragsaas-network

  mongodb:
    image: mongo:latest
    container_name: mongodb
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: password
    networks:
      - ragsaas-network
    volumes:
      - mongodb_data:/data/db

  arizephoenix:
    image: arizephoenix/phoenix:latest
    container_name: arizephoenix
    ports:
      - '6006:6006'
      - '4317:4317'
    networks:
      - ragsaas-network

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
      args:
        http_proxy: http://172.17.0.1:7890
        https_proxy: http://172.17.0.1:7890
    image: ragsaas/backend:latest
    container_name: backend
    ports:
      - '8000:8000'
    environment:
      # MongoDB Configuration
      MONGODB_NAME: RAGSAAS
      MONGODB_URI: mongodb://admin:password@mongodb:27017/
      # Qdrant Configuration
      QDRANT_COLLECTION: default
      QDRANT_URL: http://qdrant:6333
      # QDRANT_API_KEY:
      OPENAI_API_KEY:
      # Backend Application Configuration
      MODEL_PROVIDER: openai
      MODEL: gpt-4o-mini
      EMBEDDING_MODEL: text-embedding-3-small
      EMBEDDING_DIM: 1536
      # FILESERVER_URL_PREFIX: http://backend:8000/api/files
      FILESERVER_URL_PREFIX: http://159.75.85.9:8000/api/files
      SYSTEM_PROMPT: 'You are a helpful assistant who helps users with their questions.'
      APP_HOST: 0.0.0.0
      APP_PORT: 8000
      ADMIN_EMAIL: admin@ragsaas.com
      ADMIN_PASSWORD: ragsaas
      JWT_SECRET_KEY: secret123
      JWT_REFRESH_SECRET_KEY: secret123
      ARIZE_PHOENIX_ENDPOINT: http://arizephoenix:6006
    depends_on:
      - qdrant
      - mongodb
      - arizephoenix
    networks:
      - ragsaas-network

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
      args:
        HTTP_PROXY: http://172.17.0.1:7890
        HTTPS_PROXY: http://172.17.0.1:7890
        http_proxy: http://172.17.0.1:7890
        https_proxy: http://172.17.0.1:7890
    image: ragsaas/frontend:latest
    container_name: frontend
    ports:
      - '3000:3000'
    environment:
      # NEXT_PUBLIC_SERVER_URL: http://backend:8000
      # NEXT_PUBLIC_CHAT_API: http://backend:8000/api/chat
      NEXT_PUBLIC_SERVER_URL: http://159.75.85.9:8000
      NEXT_PUBLIC_CHAT_API: http://159.75.85.9:8000/api/chat
      HOST: 0.0.0.0  # 👈 关键配置,告诉 nextjs 启动时监听所有地址
    depends_on:
      - backend
    networks:
      - ragsaas-network

networks:
  ragsaas-network:
    name: ragsaas-network
    driver: bridge

volumes:
  mongodb_data:


网站公告

今日签到

点亮在社区的每一天
去签到