CLI & base image to deploy React applications with docker containers.
- Configuration
- Command-line arguments
- Configuration file
- Lightweight nginx docker container
- CLI
- Runtime environment variable injection & validation
- Javascript
- HTML
- Hash file for cache invalidation
- Application initialization (
init/check)index.htmlfile modificationDockerfilegeneration- Schema generation
- Types generation
- Runtime environment variable injection & validation
- Support for serving at a path
- Vite
- Zod
- Example projects
- Cookbook for proxying the container with cloudflare
- Cookbook for handling "in-the-wild" chunks
- Research plugin possibilities with the supported tooling
- Server side rendering
The quickest way to set up a consuming project is the init command, which performs
most of this setup for you, paired with check, which validates it (and is CI-friendly):
# Scaffold env.schema.js, inject the window.env.js script tag, generate the# Dockerfile + .dockerignore, and wire the npm scripts. Idempotent — safe to re-run.
npx docker-react init
# Validate that every setup step is complete (non-zero exit on any failure).
npx docker-react checkinit performs steps 2–6 below. Steps 1 (install dependencies) and 7 (replace env
references in your source) are advisory — init reports what's needed but never runs
npm or rewrites your code. check validates all seven steps. Pass --force to overwrite
files that have diverged, and --help to see the remaining flags.
The manual steps are documented below for reference and to show what init produces.
Install
docker-reactandzod(zod version should match the peer dependency version exactly)npm i -S docker-react zod@4.4.3
Create environment variable schema (
initscaffolds this for you; currently only Zod is supported, others may follow)The schema is loaded via dynamic
import(), so use whichever module syntax matches your project'spackage.json. CommonJS projects export withmodule.exports; ESM projects ("type": "module") useexport default. (initscaffolds the ESM form.)// env.schema.js (CommonJS)const{ z }=require('zod');module.exports=z.object({VITE_API_URL: z.url(),});
// env.schema.js (ESM — "type": "module")import{z}from'zod';exportdefaultz.object({VITE_API_URL: z.url(),});
Add env import to your
index.htmlhead (initinjects this for you, before</head>)<head> ... <scriptsrc="/window.env.js"></script></head>
Create
Dockerfile(initgenerates this for you). NOTE thedocker-reactimage version must match your installed npm version of docker-react —initpins theFROMtag to it automatically.FROM demery/docker-react:vX.X.X COPY env.schema.js ./env.schema.js COPY dist /usr/share/nginx/html
When generated by
init, the build directory is auto-detected from your Vite config'sbuild.outDir(falling back todist); override it with--build-dir.Create
.dockerignore(initgenerates this for you)node_modulesUpdate npm scripts (
initadds theinit-localscript and wires it intodev; pass--env-filefor thenode --env-filevariant){ "dev": "npm run init-local && vite", "init-local": "npx docker-react prep -s ./env.schema.js -d public" }Note if you are using a
.envfile the current recommended way is to use node directly.{ "init-local": "node --env-file=.env ./node_modules/.bin/docker-react prep -s ./env.schema.js -d public" }There is a pending feature request for npx commands to support loading .env files directly, once it's implemented these docs will be updated accordingly. npm/cli#7069
Replace all references to environment variables with
window.env, eg.process.env=>window.env(for create-react-app and others)import.meta.env=>window.env(for vite)
(Advisory:
initandcheckreport the locations of these references in yoursrc/but never rewrite your source — you make the replacements.)
Note: This instructions are to be performed in the consuming application.
# Perform a local production build (using whichever command)
npm run build
# Build a local image tagged with local
docker build -t my-app:local .# Run local build using the env file
docker run -p 3000:80 --env-file=.env --name=my-app my-app:localThe app should now be available at http://localhost:3000
# Cleanup
docker rm my-app && docker image rm my-app:local