example: restore .next handling for with-docker examples (#90651)

- Remove BuildKit cache mount on `.next/cache` that trapped fetch cache
in a volume unreachable by the runner stage
- Restore `mkdir .next && chown` in runner stage for writable prerender
cache
- Add commented-out `COPY .next/cache` line as opt-in for persisting
build-time fetch cache
- Apply same fixes to `Dockerfile.bun` (only needed the `mkdir`/`chown`,
it never had the BuildKit mount)

Closes #90648
This commit is contained in:
Joseph
2026-02-27 15:23:45 +01:00
committed by GitHub
parent 15fcfb9ce4
commit 7643fc9483
4 changed files with 55 additions and 26 deletions
+14 -15
View File
@@ -4,14 +4,14 @@ A production-ready example demonstrating how to Dockerize Next.js applications u
## Features
- ✅ Multi-stage Docker build for optimal image size
- ✅ Static export: Fully static HTML/CSS/JavaScript site
- ✅ Two serving options: Nginx (production-grade) and serve (simple Node.js server)
- ✅ Security best practices (non-root user)
- ✅ Slim/Alpine Linux base images for optimal compatibility and smaller size
- ✅ BuildKit cache mounts for faster builds
- ✅ Production-ready configuration with optimized Nginx settings
- ✅ Docker Compose support for easy deployment
- Multi-stage Docker build for optimal image size
- Static export: Fully static HTML/CSS/JavaScript site
- Two serving options: Nginx (production-grade) and serve (simple Node.js server)
- Security best practices (non-root user)
- Slim/Alpine Linux base images for optimal compatibility and smaller size
- BuildKit cache mounts for faster builds
- Production-ready configuration with optimized Nginx settings
- Docker Compose support for easy deployment
## Prerequisites
@@ -165,13 +165,12 @@ Learn more about [Next.js static export](https://nextjs.org/docs/app/api-referen
To switch to Alpine, simply change the `NODE_VERSION` ARG in the Dockerfile to `24.11.1-alpine`.
**⚠️ Important - Version Maintenance**:
- **Node.js**: This Dockerfile uses Node.js 24.13.0-slim, which was the latest LTS version at the time of writing. To ensure security and stay up-to-date, regularly check and update the `NODE_VERSION` ARG in the Dockerfile to the latest Node.js LTS version. Check the latest version at [Node.js official website](https://nodejs.org/) and browse available Node.js images on [Docker Hub](https://hub.docker.com/_/node).
- **Nginx**: The Nginx Dockerfile uses `nginxinc/nginx-unprivileged:alpine3.22`. Regularly check and update the `NGINXINC_IMAGE_TAG` ARG to the latest version. Browse available Nginx images on [Docker Hub](https://hub.docker.com/r/nginxinc/nginx-unprivileged).
- **serve package**: The serve Dockerfile uses `[email protected]`. Update to the latest version as needed for bug fixes and features.
> [!IMPORTANT]
> **Version Maintenance**:
>
> - **Node.js**: This Dockerfile uses Node.js 24.13.0-slim, which was the latest LTS version at the time of writing. To ensure security and stay up-to-date, regularly check and update the `NODE_VERSION` ARG in the Dockerfile to the latest Node.js LTS version. Check the latest version at [Node.js official website](https://nodejs.org/) and browse available Node.js images on [Docker Hub](https://hub.docker.com/_/node).
> - **Nginx**: The Nginx Dockerfile uses `nginxinc/nginx-unprivileged:alpine3.22`. Regularly check and update the `NGINXINC_IMAGE_TAG` ARG to the latest version. Browse available Nginx images on [Docker Hub](https://hub.docker.com/r/nginxinc/nginx-unprivileged).
> - **serve package**: The serve Dockerfile uses `[email protected]`. Update to the latest version as needed for bug fixes and features.
### Package Manager Support
+17 -2
View File
@@ -52,8 +52,12 @@ ENV NODE_ENV=production
# ENV NEXT_TELEMETRY_DISABLED=1
# Build Next.js application
RUN --mount=type=cache,target=/app/.next/cache \
if [ -f package-lock.json ]; then \
# If you want to speed up Docker rebuilds, you can cache the build artifacts
# by adding: --mount=type=cache,target=/app/.next/cache
# This caches the .next/cache directory across builds, but it also prevents
# .next/cache/fetch-cache from being included in the final image, meaning
# cached fetch responses from the build won't be available at runtime.
RUN if [ -f package-lock.json ]; then \
npm run build; \
elif [ -f yarn.lock ]; then \
corepack enable yarn && yarn build; \
@@ -84,9 +88,20 @@ ENV HOSTNAME="0.0.0.0"
# Copy production assets
COPY --from=builder --chown=node:node /app/public ./public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown node:node .next
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=node:node /app/.next/standalone ./
COPY --from=builder --chown=node:node /app/.next/static ./.next/static
# If you want to persist the fetch cache generated during the build so that
# cached responses are available immediately on startup, uncomment this line:
# COPY --from=builder --chown=node:node /app/.next/cache ./.next/cache
# Switch to non-root user for security best practices
USER node
+11
View File
@@ -63,9 +63,20 @@ ENV HOSTNAME="0.0.0.0"
# Copy production assets
COPY --from=builder --chown=bun:bun /app/public ./public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown bun:bun .next
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=bun:bun /app/.next/standalone ./
COPY --from=builder --chown=bun:bun /app/.next/static ./.next/static
# If you want to persist the fetch cache generated during the build so that
# cached responses are available immediately on startup, uncomment this line:
# COPY --from=builder --chown=bun:bun /app/.next/cache ./.next/cache
# Switch to non-root user for security best practices
USER bun
+13 -9
View File
@@ -4,12 +4,12 @@ A production-ready example demonstrating how to Dockerize Next.js applications u
## Features
- ✅ Multi-stage Docker build for optimal image size
- ✅ Next.js standalone mode for minimal production builds
- ✅ Security best practices (non-root user)
- ✅ Slim Linux base image for optimal compatibility and smaller size
- ✅ BuildKit cache mounts for faster builds
- ✅ Production-ready configuration
- Multi-stage Docker build for optimal image size
- Next.js standalone mode for minimal production builds
- Security best practices (non-root user)
- Slim Linux base image for optimal compatibility and smaller size
- BuildKit cache mounts for faster builds
- Production-ready configuration
## Prerequisites
@@ -127,10 +127,11 @@ Learn more about [Next.js standalone output](https://nextjs.org/docs/pages/api-r
- **Multi-stage build**: Separates dependency installation (`dependencies`), build (`builder`), and runtime (`runner`) stages
- **Slim Linux**: Uses `slim` image tag for optimal compatibility and smaller image size
- **BuildKit cache mounts**: Speeds up builds by caching package manager stores (`/root/.npm`, `/usr/local/share/.cache/yarn`, `/root/.local/share/pnpm/store`) and Next.js build cache (`/app/.next/cache`)
- **BuildKit cache mounts**: Speeds up builds by caching package manager stores (`/root/.npm`, `/usr/local/share/.cache/yarn`, `/root/.local/share/pnpm/store`). See the Dockerfile for an optional `.next/cache` mount to speed up rebuilds.
- **Non-root user**: Runs as `node` user for security
- **Optimized layers**: Leverages Docker layer caching effectively
- **Standalone output**: Copies only the necessary files from `.next/standalone` and `.next/static`
- **Writable `.next` directory**: The `.next` directory is created and owned by the `node` user so the server can write prerender cache and optimized images at runtime
- **Node.js version maintenance**: Uses Node.js 24.13.0-slim (latest LTS at time of writing). Update the `NODE_VERSION` ARG to the latest LTS version for security updates.
### Dockerfile.bun Highlights (Bun)
@@ -139,7 +140,7 @@ Learn more about [Next.js standalone output](https://nextjs.org/docs/pages/api-r
- **Official Bun image**: Uses `oven/bun:1` for optimal Bun performance
- **Non-root user**: Runs as built-in `bun` user for security
- **Frozen lockfile**: Uses `bun.lock` for reproducible builds
- **Standalone output**: Same optimized output as the Node.js version
- **Standalone output**: Same optimized output as the Node.js version, with writable `.next` directory for runtime cache
**Why Node.js slim image tag?**: The slim variant provides optimal compatibility with npm packages and native dependencies while maintaining a smaller image size (~226MB). Slim uses glibc (standard Linux), ensuring better compatibility than Alpine's musl libc, which can cause issues with some npm packages. This makes it ideal for public examples where reliability and compatibility are priorities.
@@ -152,7 +153,8 @@ Learn more about [Next.js standalone output](https://nextjs.org/docs/pages/api-r
To switch to Alpine, simply change the `NODE_VERSION` ARG in the Dockerfile to `24.11.1-alpine`.
**⚠️ Important - Node.js Version Maintenance**: This Dockerfile uses Node.js 24.13.0-slim, which was the latest LTS version at the time of writing. To ensure security and stay up-to-date, regularly check and update the `NODE_VERSION` ARG in the Dockerfile to the latest Node.js LTS version. Check the latest version at [Nodejs official website](https://nodejs.org/) and browse available Node.js images on [Docker Hub](https://hub.docker.com/_/node).
> [!IMPORTANT]
> **Node.js Version Maintenance**: This Dockerfile uses Node.js 24.13.0-slim, which was the latest LTS version at the time of writing. To ensure security and stay up-to-date, regularly check and update the `NODE_VERSION` ARG in the Dockerfile to the latest Node.js LTS version. Check the latest version at [Nodejs official website](https://nodejs.org/) and browse available Node.js images on [Docker Hub](https://hub.docker.com/_/node).
## Deployment
@@ -175,9 +177,11 @@ This example can be deployed to any container-based platform:
```
This will also enable Cloud Build for your project.
5. Deploy to Cloud Run:
```bash
gcloud run deploy --image gcr.io/PROJECT-ID/nextjs-docker --project PROJECT-ID --platform managed --allow-unauthenticated
```
- You will be prompted for the service name: press Enter to accept the default name, `nextjs-docker`.
- You will be prompted for [region](https://cloud.google.com/run/docs/quickstarts/build-and-deploy#follow-cloud-run): select the region of your choice, for example `us-central1`.