-
-
Notifications
You must be signed in to change notification settings - Fork 8
Update Dockerfile #401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Dockerfile #401
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,69 +1,66 @@ | ||
| # Multi-stage Dockerfile for QCX - Optimized for Google Cloud Build | ||
| # Stage 1: Dependencies installation | ||
| FROM oven/bun:1.1.3-alpine AS deps | ||
| # Multi-stage Dockerfile for QCX - Optimized for Google Cloud Build and Production | ||
| # Uses pinned Bun v1.3.5-alpine for reproducible builds (January 2026) | ||
|
|
||
| # Stage 1: Install dependencies | ||
| FROM oven/bun:1.3.5-alpine AS deps | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy package files | ||
| COPY package.json bun.lock* ./ | ||
|
|
||
| # Install dependencies | ||
| # Install dependencies (frozen lockfile for reproducibility) | ||
| RUN bun install --frozen-lockfile | ||
|
|
||
| # Stage 2: Build stage | ||
| FROM oven/bun:1.1.3-alpine AS builder | ||
| # Stage 2: Build the Next.js application | ||
| FROM oven/bun:1.3.5-alpine AS builder | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy dependencies from deps stage | ||
| # Copy node_modules from deps stage | ||
| COPY --from=deps /app/node_modules ./node_modules | ||
|
|
||
| # Copy application source | ||
| # Copy source code | ||
| COPY . . | ||
|
|
||
| # Set build-time environment variables | ||
| # Disable telemetry during build | ||
| ENV NEXT_TELEMETRY_DISABLED=1 | ||
| ENV NODE_ENV=production | ||
|
|
||
| # Build the Next.js application | ||
| # Build the application (standalone output) | ||
| RUN bun run build | ||
|
|
||
| # Stage 3: Production runtime | ||
| FROM oven/bun:1.1.3-alpine AS runner | ||
| # Stage 3: Production runtime (minimal image running with Bun) | ||
| FROM oven/bun:1.3.5-alpine AS runner | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Install only necessary runtime dependencies | ||
| RUN apk add --no-cache \ | ||
| nodejs \ | ||
| tini \ | ||
| curl \ | ||
| && addgroup -g 1001 -S nodejs \ | ||
| && adduser -S nextjs -u 1001 | ||
| # Create non-root group and user, with nextjs belonging to nodejs group | ||
| RUN addgroup -g 1001 -S nodejs \ | ||
| && adduser -S -u 1001 -G nodejs nextjs | ||
|
|
||
| # Set production environment | ||
| # Environment variables | ||
| ENV NODE_ENV=production | ||
| ENV NEXT_TELEMETRY_DISABLED=1 | ||
| ENV PORT=3000 | ||
| ENV HOSTNAME="0.0.0.0" | ||
|
|
||
| # Copy built application from builder | ||
| # Copy standalone build output (optimized for minimal size) | ||
| COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ | ||
| # Copy static assets | ||
| COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static | ||
| # Copy public folder | ||
| COPY --from=builder --chown=nextjs:nodejs /app/public ./public | ||
|
|
||
| # Switch to non-root user for security | ||
| # Switch to non-root user | ||
| USER nextjs | ||
|
|
||
| # Expose the application port | ||
| # Expose port | ||
| EXPOSE 3000 | ||
|
|
||
| # Health check for container orchestration | ||
| # Health check (uses Bun to fetch; adjust /api/health if your endpoint differs) | ||
| HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ | ||
| CMD curl -f http://localhost:3000/api/health || exit 1 | ||
|
|
||
| # Use tini as init system to handle signals properly | ||
| ENTRYPOINT ["/sbin/tini", "--"] | ||
| CMD ["bun", "--eval", "fetch('http://localhost:3000/api/health').then(r => r.ok ? process.exit(0) : process.exit(1)).catch(() => process.exit(1))"] | ||
|
|
||
| # Start the application | ||
| CMD ["node", "server.js"] | ||
| # Run the standalone server with Bun (fully compatible in Bun 1.3+) | ||
| CMD ["bun", "server.js"] | ||
|
Comment on lines
+33
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The runtime stage removed SuggestionReintroduce an init process. Simplest is Docker's built-in init at runtime ( RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["bun", "server.js"]Alternatively, if you deliberately don’t want Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this suggestion.
Comment on lines
+1
to
+66
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Operational: Test Bun compatibility with Next.js standalone. This migration from Node.js to Bun as the runtime for Next.js standalone is significant. While Bun 1.3+ advertises Node.js compatibility, thoroughly test:
Consider running parallel deployments initially to compare Node.js vs. Bun behavior before fully switching. #!/bin/bash
# Description: Check for potential Node.js-specific dependencies that might have compatibility issues
# Look for dependencies that use native Node modules or might have Bun compatibility concerns
echo "Checking package.json for potentially problematic dependencies..."
# Check for native modules
jq -r '.dependencies // {} | to_entries[] | select(.key | test("^(node-|@node/)")) | .key' package.json 2>/dev/null || echo "No package.json found"
# Check for C++ addons or native dependencies
jq -r '.dependencies // {} | to_entries[] | select(.key | test("(bindings|nan|node-gyp|ffi)")) | .key' package.json 2>/dev/null
echo ""
echo "Review these dependencies for Bun compatibility at: https://bun.sh/docs/runtime/nodejs-apis"
Comment on lines
+65
to
+66
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Find and inspect the Dockerfile to understand the full context
git ls-files | grep -i dockerfileRepository: QueueLab/QCX Length of output: 66 🏁 Script executed: # Check the full Dockerfile to understand setup around lines 65-66
fd -t f -e Dockerfile -e dockerfile | head -20Repository: QueueLab/QCX Length of output: 38 🌐 Web query:
💡 Result: Short answer: When Bun is PID 1 inside a container it will not be terminated by SIGINT/SIGTERM unless you explicitly handle those signals in your Bun app or run an init that forwards signals (tini/dumb-init / Docker --init). See Bun docs for registering handlers and use --init or an init binary if you don’t want to add handlers in-process. [1][2][3] What to do (options):
References:
🌐 Web query:
💡 Result: Short summary — Bun 1.3+ supports process signals the same way Node does (process.on('SIGINT' / 'SIGTERM')), and Bun.Server exposes server.stop() which by default performs a graceful shutdown (waits for in‑flight requests & websockets). Typical pattern: listen for SIGINT/SIGTERM, perform cleanup (close DB, etc.), await server.stop(), then exit. [1][2][3] Minimal example: const server = Bun.serve({ fetch(req) { return new Response("ok"); } }); process.on("SIGTERM", async () => { Key docs:
Sources: 🏁 Script executed: cat -n DockerfileRepository: QueueLab/QCX Length of output: 2418 🌐 Web query:
💡 Result: Short answer
What to do (practical options)
Concrete references
If you want, I can:
Add signal handlers for graceful shutdown—Bun as PID 1 requires explicit handling. Next.js standalone servers (like Choose one approach:
Without one of these, the container will not shut down gracefully and may lose data on redeploy or restart. 🤖 Prompt for AI Agents |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarify version pinning strategy.
The PR summary states the goal is to use
oven/bun:alpine(latest stable), but the implementation pins1.3.5-alpine. Pinning provides reproducibility, but conflicts with the stated objective of using "latest stable."Please clarify:
oven/bun:alpinewithout a version pin (though pinning is generally recommended for production).🤖 Prompt for AI Agents