# ============================================================================== # Stage 1: Build Frontend (Next.js) # ============================================================================== FROM node:20-slim AS frontend-builder WORKDIR /app/frontend # Install dependencies COPY frontend/package*.json ./ RUN npm ci # Copy source and build COPY frontend/ . # Disable telemetry during build ENV NEXT_TELEMETRY_DISABLED=1 RUN npm run build # ============================================================================== # Stage 2: Final Image (Python + Node.js Runtime) # ============================================================================== FROM python:3.11-slim # Build Arguments for Tunnel ARG BASTION_URL="https://bastion.3prism.ai" ARG HOST_ARCH="amd64" # 1. Install System Dependencies & Node.js 20 (for runtime) # We need Node.js 20 to run the Next.js production server (npm start) # curl is needed for health check # WeasyPrint dependencies for PDF export # First install ca-certificates and curl (needed for NodeSource setup) RUN apt-get update && apt-get install -y \ ca-certificates \ curl \ && rm -rf /var/lib/apt/lists/* # Then install Node.js from NodeSource RUN install -m 0755 -d /etc/apt/keyrings && \ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key -o /etc/apt/keyrings/nodesource.gpg && \ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" > /etc/apt/sources.list.d/nodesource.list && \ apt-get update && \ apt-get install -y nodejs && \ rm -rf /var/lib/apt/lists/* # Finally install WeasyPrint dependencies and Chinese fonts RUN apt-get update && apt-get install -y \ libpango-1.0-0 \ libharfbuzz0b \ libpangoft2-1.0-0 \ libpangocairo-1.0-0 \ fonts-noto-cjk \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # 2. Create Python Virtual Environment and Install Dependencies COPY requirements.txt . RUN python -m venv /app/.venv && \ /app/.venv/bin/pip install --no-cache-dir -r requirements.txt # 3. Bake in Portwarden Client (The "Tunnel") # This runs during build time to download the binary into the image # 使用 p12 证书进行身份验证,-k 跳过服务器证书验证 COPY bastian/lyman.p12 /tmp/lyman.p12 COPY bastian/key.md /tmp/key.md RUN openssl pkcs12 -in /tmp/lyman.p12 -out /tmp/client.pem -nodes -passin pass:$(cat /tmp/key.md) && \ echo "Downloading Portwarden Client from: ${BASTION_URL}/releases/portwardenc-${HOST_ARCH}" && \ curl -fsSLk --cert /tmp/client.pem "${BASTION_URL}/releases/portwardenc-${HOST_ARCH}" -o /usr/local/bin/portwardenc && \ chmod +x /usr/local/bin/portwardenc && \ rm -f /tmp/lyman.p12 /tmp/key.md /tmp/client.pem # 4. Copy Frontend Build Artifacts # We need package.json to run 'npm start' COPY frontend/package*.json ./frontend/ # Copy the built .next folder and public assets COPY --from=frontend-builder /app/frontend/.next ./frontend/.next COPY --from=frontend-builder /app/frontend/public ./frontend/public # Install production dependencies only (reduces image size) WORKDIR /app/frontend RUN npm ci --only=production WORKDIR /app # 5. Copy Backend & Application Code WORKDIR /app COPY backend/ ./backend/ COPY *.py ./ # 6. Copy Scripts COPY entrypoint.sh /usr/local/bin/entrypoint.sh COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh # Make scripts executable RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/docker-entrypoint.sh # Environment Variables Defaults ENV PW_LOCAL_PORT=3001 # Disable Next.js Telemetry ENV NEXT_TELEMETRY_DISABLED=1 # Expose ports (for local debugging) EXPOSE 3001 8000 # Health Check # 检查后端和前端健康状态 HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f http://localhost:8000/health && curl -f http://localhost:3001 || exit 1 # Entrypoint: Portwarden tunnel client ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] # Command: Start backend and frontend with process management CMD ["/usr/local/bin/docker-entrypoint.sh"]