- 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
## What?
Modernizes the existing `with-docker` example and adds a new
`with-docker-export-output` example demonstrating different Next.js
deployment strategies with Docker best practices:
1. **`with-docker` (updated)** - Modernized to use App Router,
TypeScript, Tailwind CSS v4, and comprehensive Docker best practices.
Now includes both Node.js and Bun Dockerfile options, Docker Compose
with profiles, BuildKit cache mounts, and extensive documentation.
2. **`with-docker-export-output` (new)** - Demonstrates Next.js static
export mode deployment with Docker, offering two serving options:
**Nginx** (production-grade) and **serve** package (Node.js-based,
simpler setup). Includes optimized Nginx configuration, BuildKit cache
mounts, and comprehensive documentation.
Both examples include detailed documentation explaining Docker best
practices, implementation decisions, and deployment guidance.
## Why?
The existing `with-docker` example was using the Pages Router and
lacked:
- Modern Next.js patterns (App Router, TypeScript)
- Detailed documentation explaining Docker best practices and
implementation decisions
- BuildKit cache mounts for optimized build performance
- Bun runtime support as an alternative to Node.js
- Docker Compose configurations for easier local development
- Clear documentation about Node.js image variant choices (slim vs
Alpine)
- Examples demonstrating static export mode
These updates serve as comprehensive references for developers who want
to understand:
- How to Dockerize Next.js applications for different deployment
scenarios
- Why certain choices are made and how to optimize Docker setups for
production
- When to use standalone mode vs static export mode
- How to choose between Node.js and Bun runtimes
- How to choose between different web servers (Nginx vs serve) for
static sites
## How?
### `with-docker` example (updated)
- **Migrated to App Router** with TypeScript and Tailwind CSS v4
- **Multi-stage Dockerfile** with three stages: dependencies
installation, build, and runtime
- **Bun support** via `Dockerfile.bun` with optimized configuration
- **BuildKit cache mounts** for package manager stores (`npm`, `yarn`,
`pnpm`, `bun`) and Next.js build cache
- **Security best practices** with non-root user execution (built-in
`node` and `bun` users)
- **Docker Compose configuration** with profiles for Node.js (default)
and Bun
- **Comprehensive `.dockerignore`** to minimize build context size
- **Detailed README** explaining standalone mode benefits, Node.js image
choices, and deployment guidance
- **Deleted** `with-docker-standalone-output` (merged into this example)
### `with-docker-export-output` example (new)
- **Two Dockerfile options:**
- `Dockerfile` - Nginx-based serving with `nginxinc/nginx-unprivileged`
for security
- `Dockerfile.serve` - Node.js serve package-based serving for simpler
deployments
- **Multi-stage builds** for both options with separate dependency,
build, and runtime stages
- **BuildKit cache mounts** for package manager stores and Next.js build
cache
- **Production Nginx configuration** (`nginx.conf`) with gzip
compression, caching headers, and security best practices
- **Docker Compose configuration** supporting both serving options via
profiles
- **Comprehensive README** explaining static export mode, trade-offs
between Nginx and serve
### Docker best practices implemented (both examples)
| Practice | Description |
|----------|-------------|
| Multi-stage builds | Optimal image size reduction |
| Layer caching | Package files copied first |
| Minimal build context | Comprehensive `.dockerignore` files |
| BuildKit cache mounts | Faster subsequent builds |
| Security hardening | Non-root user execution |
| Corepack | yarn/pnpm version management |
| Package manager auto-detection | npm, yarn, pnpm support |
| Node.js 24.13.0-slim | Clear upgrade guidance |
## Breaking Changes
> **Warning**
> - `with-docker` now uses App Router instead of Pages Router
> - `with-docker-standalone-output` has been removed (merged into
`with-docker`)
---
**Note:** After this PR is approved and merged, I plan to open a
follow-up PR to update the Next.js documentation with proper links to
these Docker examples.
---------
Co-authored-by: Wyatt Johnson <accounts+github@wyattjoh.ca>
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
Co-authored-by: kristiyan.velkov <kristiyan.velkov@ffw.com>
This PR updates all example Dockerfiles that were using `node:18-alpine`
to `node:20-alpine`
to align with current LTS and address known issues in Node 18 images.
- examples/with-docker/Dockerfile
- examples/with-docker-compose/next-app/prod.Dockerfile
- examples/with-docker-compose/next-app/dev.Dockerfile
- examples/with-docker-multi-env/docker/development/Dockerfile
- examples/with-docker-multi-env/docker/production/Dockerfile
- examples/with-docker-multi-env/docker/staging/Dockerfile
I verified local builds for each example. No behavior changes;
docs/examples only.
https://github.com/vercel/next.js/issues/78465
---------
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
### Description:
This PR updates the Dockerfile in the `examples/with-docker` folder to
include the `.npmrc` file in the dependency copy command.
### Original Command:
```dockerfile
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
```
### Updated Command:
```dockerfile
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc ./
```
### Reason for Change:
Including `.npmrc` allows for custom npm configurations, such as
`legacy-peer-deps=true`. Without this option, some installations can
fail due to unresolved peer dependencies, particularly for projects with
older dependencies.
This update ensures that any additional configurations specified in
`.npmrc` are applied during installation, improving Docker build
consistency and stability for projects with custom npm requirements.
### Diff:
```diff
- COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
+ COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc ./
```
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>
### What?
Update docker examples to correctly set HOSTNAME env variable for
standalone output
Related to PR:
https://github.com/vercel/next.js/pull/52804
### Why?
### TL;DR
The dockerfiile examples need to modified as that contains HOSTNAME
setting that apparently is not working as expected.
Related to Issue:
https://github.com/vercel/next.js/issues/58657
Affected examples:
https://github.com/vercel/next.js/tree/canary/examples/with-dockerhttps://github.com/vercel/next.js/tree/canary/examples/with-docker-multi-env
### Longer explanations
Based on [Docker
document](https://docs.docker.com/engine/reference/builder/#environment-replacement):
> You can also use environment variables with RUN, CMD, and ENTRYPOINT
instructions, but in those cases the variable substitution is handled by
the command shell, not the builder.
It means that when executing the last CMD ( `node server.js` ) in
Dockerfile samples, the HOSTNAME defined by prior `ENV` instruction is
simply ignored.
This causes problems typically when the host process sets HOSTNAME -
e.g. for instance when using AWS Fargate for deployment [we can't have
control over HOSTNAME](https://stackoverflow.com/a/52871552) set by the
host process. (also refer to the issue #58657 above)
### How?
Updated Dockerfilie samples, by setting HOSTNAME directly in CMD
instruction that launches nextjs server, not in the builder process.
Used this setting at my end (with AWS Fargate) to confirm that it fixes
the network problem.
Closes NEXT-
Fixes#58657
Co-authored-by: Sam Ko <sam@vercel.com>
<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:
## For Contributors
### Improving Documentation
- Run `pnpm prettier-fix` to fix formatting issues before opening the
PR.
- Read the Docs Contribution Guide to ensure your contribution follows
the docs guidelines:
https://nextjs.org/docs/community/contribution-guide
### Adding or Updating Examples
- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md
### Fixing a bug
- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md
### Adding a feature
- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md
## For Maintainers
- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change
### What?
### Why?
### How?
Closes NEXT-
Fixes #
-->
### What
This pr addresses an issue in Docker where the cache and the creation of
its contents throw the following error:
```
[Error: EACCES: permission denied, mkdir '/app/.next/cache'] {
errno: -13,
code: 'EACCES',
syscall: 'mkdir',
path: '/app/.next/cache'
```
Co-authored-by: Sam Ko <sam@vercel.com>
### Adding or Updating Examples
- Example:
[with-docker](https://github.com/vercel/next.js/tree/canary/examples/with-docker)
- Update: The latest change introduced in #61466 on the building process
of NextJS when the package manager is PNPM is currently throwing an
error (it works for npm though).
**To replicate the error:**
1. Checkout on the **with-docker** example
2. Install with PNPM so that it generates the pnpm-lock.yaml
3. Build the Docker image -> This will fail on the _builder stage_ step
that runs `pnpm run build`.
**Possible Solution:**
- Run `corepack enable pnpm` before building with pnpm
It seems the app router attempts to write its cache to both `.next/cache` and `.next/server` in docker.
This fix should fix standalone output server's error `Failed to update prerender cache... [Error: EACCES: permission denied...` when deployed in a docker container with the example Dockerfile.
Related discussion: https://github.com/vercel/next.js/discussions/51164
When I try to deploy to Google Cloud Run it fails after some
investigation I saw this line in
.next/standalone/server.js
```javascript
const hostname = process.env.HOSTNAME || 'localhost'
```
This some how make this log when i run docker
```shell
- ready started server on 172.17.0.2:3000, url: http://172.17.0.2:3000
```
I don't know why it's logging this address even if the server running on
localhost.
So this my fix
Set hostname to 0.0.0.0 to avoid deployment failing on Google cloud run.
### What?
In the Dockerfile example:
* Moves the `USER` command above the `COPY`s
* Removes the `--chown` on the `COPY`s
> **Note**
> I don't know for 100% sure this won't have unintended side effects. Part of my motivation for opening this PR is to sense check whether we will be causing a regression by making this change in our own projects.
>
> Please let me know if there's any concerns with this!
### Why?
Sonar security scanner flags this Dockerfile as having "security hotspots" due to the use of `--chown`
https://rules.sonarsource.com/docker/RSPEC-6504/
### How?
Make the `--chown`s redundant by setting the current user before doing the `COPY` commands.
the directory `/app/.next/standalone` already contains a copy of the package.json so we can skip copying it before we copy the standalone dir
## Documentation / Examples
- [x] Make sure the linting passes by running `pnpm lint`
- [x] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)
Co-authored-by: JJ Kasper <jj@jjsweb.site>
There was an `npm` equivalent for `yarn install` (`npm ci`) but not one for `yarn build`. I've added `npm run build` as a commented out option.
## Documentation / Examples
- [x] Make sure the linting passes by running `yarn lint`
This fixes the comment about disabling telemetry. For now it doesn't disable telemetry for `next build` if you uncomment it.
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes
* Fix ambiguous flags in Dockerfile example
At least with Docker xx this Dockerfile fails to both `adduser` and `addgroup` commands due to ambiguous flags. The error message for example for `addgroup` is:
```
#5 0.292 Option g is ambiguous (gecos, gid, group)
#5 0.292 Option s is ambiguous (shell, system)
```
This PR switches both commands to use the long-format flags. I think they are also more understandable for the readers of the Dockerfile.
* Apply suggestions from code review
Co-authored-by: Balázs Orbán <info@balazsorban.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: Balázs Orbán <info@balazsorban.com>
Fixed `dockerfile` in `with-docker` example
## Bug
- error when executing `docker build -t nextjs-docker .` - `yarn.lock` file is missing
## Documentation / Examples
- edited to not fail when `package-lock.json` or `yarn.lock` are not found
- example: use `with-docker` example
- [x] Make sure the linting passes by running yarn lint
Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
Update to remove the second `yarn install` step from the docker example as it is no longer needed since we only include necessary files from the output file traces now.
Closes: https://github.com/vercel/next.js/pull/29360
## Documentation / Examples
- [x] Make sure the linting passes by running `yarn lint`
Fixes#29023
## Bug
- [x] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [x] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [x] Make sure the linting passes
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [x] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
## Documentation / Examples
- [x] Make sure the linting passes
* Fix missing yarn.lock
* Add --frozen-lockfile flag to speed up install deps
* Make sure node_modules do not contains devDependencies
* Add --targe stage docker build