DevOps35-55 min
Dockerize a Node.js API
Build a small container image, install production dependencies, run as a non-root user, and expose the API port.
DockerNode.jsExpress
Prerequisites
- A Node.js API with a build or start script.
- A `.dockerignore` file.
- Docker installed locally or in CI.
1
Plan the implementation
Start by choosing the exact page, route, API, or deployment surface you want to improve. A narrow target makes the implementation measurable and easier to verify.
- Write down the current behavior and the user-facing problem it creates.
- Pick one measurable success signal such as bundle size, latency, error rate, security coverage, or UI responsiveness.
- Identify the files, routes, providers, and environment variables involved.
- Create a rollback note before changing production-sensitive configuration.
2
Set up the required tools
Install or configure only the tools needed for this implementation. Keep config close to the feature so future developers can find the moving parts quickly.
Implementation snippet
docker --version
npm run buildChecklist
- Dependencies are added to the correct workspace package.
- Environment variables are documented in `.env.example` when needed.
- Local development still starts without production-only secrets.
- The change is small enough to review in one pull request.
3
Implement the core pattern
- Create `.dockerignore` to exclude node_modules, logs, local env files, and build cache.
- Copy package files before source files so dependency layers cache well.
- Install dependencies with `npm ci` for repeatable builds.
- Run the container as a non-root user.
- Pass secrets at runtime through environment variables.
Implementation snippet
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=deps /app/node_modules ./node_modules
COPY . .
USER node
EXPOSE 3000
CMD ["npm", "start"]4
Handle edge cases
Checklist
- The image does not include `.env` or local secrets.
- The API starts with `docker run` locally.
- Health checks or logs make startup failures visible.
- Production dependencies match the lockfile.
5
Verify before production
- Run the app locally and test the normal success path.
- Test one failure path, one empty state, and one slow-network or retry path.
- Run the project build and any related unit or integration tests.
- Check browser console, server logs, and network responses for hidden warnings.
- Document the final behavior, commands used, and any follow-up work.