Description
To ensure consistent environments across development, staging, and production, the EquipChain backend must be containerized using Docker. This issue creates a production-grade Docker multi-stage build configuration along with a Docker Compose setup for local development that includes the API server plus any required services (Redis for caching, etc.).
The Dockerfile should use a multi-stage build approach: the builder stage installs all dependencies (including devDependencies), runs tests, and optionally lints the code; the production stage copies only the necessary artifacts (production dependencies, source files) to a minimal Node.js image (e.g., node:20-alpine). The production image should run as a non-root user for security and should have NODE_ENV=production set.
The Docker Compose configuration should define the api service (built from the Dockerfile) along with a redis service for the caching layer (Issue #12) and any other dependencies. Configuration should come from environment variables via an .env file or Compose environment section. Health checks should be defined for each service, and proper network isolation should be configured using named networks.
Technical Context & Impact
- Dependencies: Docker Engine 24+, Docker Compose v2+. No changes to application code required — just build configuration files.
- Architecture:
Dockerfile at project root, docker-compose.yml at project root, .dockerignore to exclude node_modules, .git, and log files.
- Impact: Containerization is essential for reproducible deployments. It eliminates "it works on my machine" issues and simplifies scaling. Docker Compose enables a one-command local development environment with all required services running.
Step-by-Step Implementation Guide
- Create Dockerfile: Write
Dockerfile with two stages. Builder: FROM node:20-alpine AS builder, copy package*.json, run npm ci, copy source code, run npm test. Production: FROM node:20-alpine, create node:node user, copy production node_modules and source from builder, expose port 3000, run USER node, CMD ["node", "src/index.js"].
- Create .dockerignore: Write
.dockerignore ignoring node_modules, .git, .env, *.md, coverage/, tests/, .github/.
- Create Docker Compose File: Write
docker-compose.yml with services: api (build context ., env_file: .env, ports: "3000:3000", depends_on: redis, healthcheck), redis (image: redis:7-alpine, ports: "6379:6379", healthcheck, volumes for persistence).
- Create Helper Scripts: Add
docker-compose.override.yml for development with volume mounts for hot-reloading. Add scripts/docker-build.sh and scripts/docker-run.sh for convenience.
- Update Documentation: Add Docker setup instructions to README or a new CONTRIBUTING.md — how to build, run, stop, and clean up containers.
Verification & Testing Steps
- Run
docker build -t equipchain-api . and verify the build completes successfully, showing both stages in the output.
- Run
docker run --rm -p 3000:3000 equipchain-api and verify GET http://localhost:3000/ returns the expected JSON response.
- Run
docker compose up -d and verify both api and redis containers start. Run docker compose ps to check status.
- Run
docker compose logs api to verify the API logs indicate successful startup and Redis connection.
- Run
docker compose down and verify all containers are stopped and networks removed. Run docker compose down -v to also remove volumes.
Description
To ensure consistent environments across development, staging, and production, the EquipChain backend must be containerized using Docker. This issue creates a production-grade Docker multi-stage build configuration along with a Docker Compose setup for local development that includes the API server plus any required services (Redis for caching, etc.).
The Dockerfile should use a multi-stage build approach: the builder stage installs all dependencies (including devDependencies), runs tests, and optionally lints the code; the production stage copies only the necessary artifacts (production dependencies, source files) to a minimal Node.js image (e.g.,
node:20-alpine). The production image should run as a non-root user for security and should haveNODE_ENV=productionset.The Docker Compose configuration should define the
apiservice (built from the Dockerfile) along with aredisservice for the caching layer (Issue #12) and any other dependencies. Configuration should come from environment variables via an.envfile or Compose environment section. Health checks should be defined for each service, and proper network isolation should be configured using named networks.Technical Context & Impact
Dockerfileat project root,docker-compose.ymlat project root,.dockerignoreto excludenode_modules,.git, and log files.Step-by-Step Implementation Guide
Dockerfilewith two stages. Builder:FROM node:20-alpine AS builder, copypackage*.json, runnpm ci, copy source code, runnpm test. Production:FROM node:20-alpine, createnode:nodeuser, copy production node_modules and source from builder, expose port 3000, runUSER node,CMD ["node", "src/index.js"]..dockerignoreignoringnode_modules,.git,.env,*.md,coverage/,tests/,.github/.docker-compose.ymlwith services:api(build context ., env_file: .env, ports: "3000:3000", depends_on: redis, healthcheck),redis(image: redis:7-alpine, ports: "6379:6379", healthcheck, volumes for persistence).docker-compose.override.ymlfor development with volume mounts for hot-reloading. Addscripts/docker-build.shandscripts/docker-run.shfor convenience.Verification & Testing Steps
docker build -t equipchain-api .and verify the build completes successfully, showing both stages in the output.docker run --rm -p 3000:3000 equipchain-apiand verifyGET http://localhost:3000/returns the expected JSON response.docker compose up -dand verify bothapiandrediscontainers start. Rundocker compose psto check status.docker compose logs apito verify the API logs indicate successful startup and Redis connection.docker compose downand verify all containers are stopped and networks removed. Rundocker compose down -vto also remove volumes.