A Dockerfile builder for static React sites that emits a multi-stage Dockerfile:
one stage builds your app with Node, and a second tiny stage serves the compiled output
with Nginx. It also generates a matching nginx.conf with sensible caching headers and
optional single-page-app routing.
How it works
The build stage uses node:<version>-alpine. It copies package.json and your
lockfile first and runs a clean install (npm ci, yarn install --frozen-lockfile, or
pnpm install --frozen-lockfile) so dependencies are cached independently of your source.
It then copies the rest of the project and runs your build script, producing static assets
in dist, build, or out.
The runtime stage starts from nginx:alpine, copies only the built assets into
/usr/share/nginx/html, and copies the generated nginx.conf over the default config.
That config sets a one-year immutable cache on hashed assets and, when SPA fallback is on,
uses try_files $uri $uri/ /index.html; so any unmatched route is handed to your
client-side router instead of returning a 404.
Tips and notes
- Add a
.dockerignorewithnode_modules,.git, anddistso the build context is small and the dependency cache is not invalidated by stale local builds. - If your app reads runtime configuration, remember the bundle is built at image build time — environment variables baked in then cannot change without rebuilding. Use a runtime config file or an entrypoint that templates one instead.
- The included
HEALTHCHECKdoes a simple HTTP GET of/; orchestrators use it to know the container is serving before sending traffic. - Hashed asset filenames (
app.4f3c1.js) are safe to cache for a year because a new build produces a new filename — never long-cacheindex.htmlitself.