Docker
In many cases, we build our application with Docker to enable easy hosting on external servers.
One of the most efficient ways to do this is using a technique called Multi-stage builds, which consists of multiple stages that prepare the application and produce a final image containing only the production code. Here’s an example:
# Phase 1: Build the applicationFROM node:22-alpine AS builderWORKDIR /app
COPY package.json package-lock.json ./RUN npm ci
COPY . .RUN npm run build
# Phase 2: Prepare the production imageFROM node:22-alpine AS productionWORKDIR /app
ENV NODE_ENV=production
COPY package.json package-lock.json ./RUN npm ci --include=prod
## Output from build step on builder stageCOPY --from=builder /app/dist ./dist## Production serverCOPY server.js ./
EXPOSE 5173
CMD ["node", "server.js"]
This strategy produces a much leaner image that includes only production dependencies and the bundled files.
If you are already using this approach and add layerfig
, you may encounter an
error like this:
Error: File "/app/config/base.json" does not exist at ConfigBuilder.addSource (file:///app/node_modules/@layerfig/config/dist/index.js:78:46) at file:///app/dist/server/entry-server.js:6:48 at ModuleJob.run (node:internal/modules/esm/module_job:274:25) at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:644:26) at async file:///app/server.js:51:17
This error occurs because you need to include the configuration files in the final production stage:
# Phase 1: Build the applicationFROM node:22-alpine AS builderWORKDIR /app
COPY package.json package-lock.json ./RUN npm ci
COPY . .RUN npm run build
# Phase 2: Prepare the production imageFROM node:22-alpine AS productionWORKDIR /app
ENV NODE_ENV=production
COPY package.json package-lock.json ./RUN npm ci --include=prod
## Output from build step on builder stageCOPY --from=builder /app/dist ./dist## Production serverCOPY server.js .
## Include configuration filesCOPY ./config ./config
EXPOSE 5173
CMD ["node", "server.js"]
Now your application will include the configuration files and load them correctly.