dev-ops

Examen Blog

Full stack met NodeJS, Postgres, en beveiligde Admin via Traefik.

Stap 1: Traefik Setup

mkdir ~/traefik && cd ~/traefik
Maak de map voor de proxy
docker network create traefik
Maak het publieke netwerk
nano docker-compose.yml
Maak de config (zie Files sectie)
docker compose up -d
Start de proxy server

Stap 2: Dockerfiles

cd ~/examen-blog/backend
Ga naar de backend map
nano Dockerfile
Maak de API Dockerfile (zie Files: API Dockerfile)
cd ../frontend
Ga naar de frontend map
nano Dockerfile
Maak de Frontend Dockerfile (zie Files: Frontend Dockerfile)

Stap 3: Authenticatie & Config

sudo apt-get install apache2-utils
Installeer htpasswd tool (indien niet aanwezig)
htpasswd -nb bloemkool SuperLekkerEten!
Genereer de hash voor Traefik labels
nano .env
Maak het environment bestand aan

Stap 4: Starten

docker compose up -d --build
Bouw images en start alles op
docker compose logs -f api
Debug: Check database connectie

Bestanden & Configuraties

api/Dockerfile
dockerfile
FROM node:20-bullseye
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8000
CMD ["node", "index.js"]
Backend luistert op poort 8000
frontend/Dockerfile
dockerfile
FROM node:20-bullseye
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 4000
CMD ["node", "index.js"]
Frontend luistert op poort 4000
~/traefik/docker-compose.yml
yaml
services:
traefik:
image: traefik:v3.6.7
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`{{domain-2}}`)"
- "traefik.http.routers.dashboard.service=api@internal"
networks:
traefik:
external: true
De infrastructuur layer (Traefik v3)
~/examen-blog/docker-compose.yml
yaml
services:
# --- Backend API ---
backend:
build: ./backend
networks:
- traefik
- backend
env_file: .env
labels:
- "traefik.enable=true"
- "traefik.http.routers.backend.rule=Host(`{{domain-1}}`) && PathPrefix(`/api`)"
- "traefik.http.services.backend.loadbalancer.server.port=8000"
- "traefik.docker.network=traefik"
# --- Frontend (Node EJS) ---
frontend:
build: ./frontend
networks:
- traefik
- backend
environment:
- API_URL=http://backend:8000
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`{{domain-1}}`)"
- "traefik.http.services.frontend.loadbalancer.server.port=4000"
- "traefik.docker.network=traefik"
# --- Admin (Static Nginx) ---
admin:
image: nginx:1.25
volumes:
# Mount ./admin naar /usr/share/nginx/html/admin
# Hierdoor werkt de URL /admin vanzelf zonder StripPrefix problemen
- ./admin:/usr/share/nginx/html/admin
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.admin.rule=Host(`{{domain-1}}`) && PathPrefix(`/admin`)"
# Pas aan met output van: htpasswd -nb bloemkool SuperLekkerEten!
- "traefik.http.middlewares.admin-auth.basicauth.users=bloemkool:$$apr1$$..."
- "traefik.http.routers.admin.middlewares=admin-auth"
# --- Database ---
db:
image: postgres:12.22
volumes:
- postgres-data:/var/lib/postgresql/data
- ./postgres-init.sql:/docker-entrypoint-initdb.d/postgres-init.sql
networks:
- backend
env_file: .env
volumes:
postgres-data:
networks:
traefik:
external: true
backend:
De applicatie configuratie. Let op: postgres-init.sql moet actief zijn.
~/examen-blog/.env
properties
STORAGE=postgres
POSTGRES_HOST=db
POSTGRES_USER=postgres
POSTGRES_PWD=mysecret
POSTGRES_DB=blog
Environment variabelen.