AWS · Production

Deploying Node.js APIs

This lesson takes an Express API from your laptop to a production-style AWS deployment on ECS Fargate.

Advanced 5 min Lesson 28 of 30
Before you start:ECSNode.js: Deployment
0/30 in AWS
On this page · 5 min · Advanced

Learning objectives#

  • Containerise an Express API
  • Push the image to ECR
  • Run it on Fargate behind an ALB
  • Wire up secrets, health checks and logs

Explanation#

Add a /health route and read configuration from environment variables. Listen on the port given by process.env.PORT.

A small multi-stage Dockerfile installs only production dependencies and runs as a non-root user.

The ECS service runs at least two tasks in private subnets; the ALB in public subnets terminates HTTPS and health-checks /health.

Database credentials come from Secrets Manager through the task definition’s secrets field. Logs go to CloudWatch.

Code example: Production Dockerfile for Express#

DockerfileDockerfile Illustrative
FROM node:22-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev


FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production PORT=3000
COPY --from=deps /app/node_modules ./node_modules
COPY . .
USER node
EXPOSE 3000
HEALTHCHECK CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "server.js"]


# docker build -t $REG/shop-api:1.0.0 . && docker push $REG/shop-api:1.0.0
# aws ecs update-service --cluster shop --service shop-api --task-definition shop-api:2
Expected output
GET https://api.shop.example.com/health
{"status":"ok"}

This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.

Step-by-step explanation#

  1. The first stage installs production dependencies only.
  2. The final image copies them and the source, and runs as the unprivileged node user.
  3. The image is pushed to ECR with a version tag.
  4. Updating the service with a new task definition performs a rolling deployment.

Real-world use case#

The REST API from the Node.js API track serving a React front end on CloudFront, with RDS MySQL in private subnets.

Common mistakes#

Hard-coded port or config

Read PORT, DB host and other settings from environment variables.

Copying node_modules and .env into the image

Add a .dockerignore with node_modules, .env and .git.

Best practices#

  • Health endpoint for ALB checks
  • Non-root container user
  • Secrets via Secrets Manager
  • Deployment circuit breaker with automatic rollback

Remember this#

Dockerfile → ECR → ECS Fargate → ALB.

/health or the ALB marks you unhealthy.

Config from env vars, secrets from Secrets Manager.

Practice exercise#

Your task: Write the .dockerignore for this project.

Show solution
Text Illustrative
node_modules
.env
.git
npm-debug.log
coverage

Mini quiz#

Deploying Node.js APIs quizMultiple choice Question 1 of 1

Where should the ECS tasks run in a production VPC?

Score so far: 0/0

Want more? Practise all AWS MCQs · AWS interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.