Updated August 2026 — full tutorial restored for this URL.
In this tutorial we Dockerize a typical stack: Angular SPA served by Nginx, and a Node.js API — wired together with Compose.
1. Project layout
repo/
api/ # Express (or Nest) app
web/ # Angular app
docker-compose.yml
2. Node API Dockerfile
FROM node:20-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
3. Angular multi-stage + Nginx
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build -- --configuration=production
FROM nginx:1.27-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist/web/browser /usr/share/nginx/html
EXPOSE 80
Example nginx.conf proxying API calls:
server {
listen 80;
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://api:3000/;
}
}
4. docker-compose
services:
api:
build: ./api
environment:
PORT: 3000
web:
build: ./web
ports: ["8080:80"]
depends_on: [api]
5. API URL and CORS
Prefer same-origin /api via Nginx so the browser never needs CORS for local Compose. If the SPA calls the API directly, set CORS on Express and use an environment-specific environment.prod.ts API base URL.
Related: Connect Node.js to PostgreSQL.