In diesem Beitrag zeige ich, wie man production-ready Docker Images für eine Web Anwendung mit Angular, NestJS, MySQL und Redis erstellt und anschließend auf Docker Hub veröffentlicht. Voraussetzung ist eine installierte Docker Umgebung.
Das könnte dich ebenfalls interessieren: NestJS auf Vercel hosten
Erstellung der Docker Compose Yml
Mit Docker Compose können alle Komponenten einer Anwendung über eine einzige Konfigurationsdatei definiert und gemeinsam gebuildet bzw. gestartet werden.
version: '3.8' services: frontend: build: ./frontend ports: - "80:80" depends_on: - backend backend: build: ./backend ports: - "3000:3000" depends_on: - mysql - redis environment: - DATABASE_URL=mysql://user:password@mysql:3306/db - SESSION_STORE=redis://redis:6379 mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: db ports: - "3306:3306" redis: image: redis:latest ports: - "6379:6379"
Erstellung der Env Datei
Um Umgebungsvariablen zentral zu verwalten, erstellen wir eine .env
Datei:
DATABASE_URL=mysql://user:password@mysql:3306/db SESSION_STORE=redis://redis:6379
Wichtig: Alle ENV-Variablen, die im Code verwendet werden, müssen auch in docker-compose.yml
vorkommen!
Docker-Image für das Frontend
Das Angular-Frontend muss für die Produktion gebaut werden. Hier ein Beispiel-Dockerfile
:
FROM node:20 AS build WORKDIR /app COPY package.json package-lock.json ./ RUN npm install COPY . . RUN npm run build --prod FROM nginx:alpine COPY --from=build /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/nginx.conf
Da wir für den Build auf nginx angewiesen sind brauchen wir auch eine entsprechende Config Datei:
server { listen 80; server_name _; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } }
Docker-Image für das Backend
Auch das NestJS-Backend muss gebaut werden. Hier ein optimiertes Dockerfile
# Build stage FROM node:20 AS build WORKDIR /app COPY package.json package-lock.json ./ RUN npm install COPY . . RUN npm run build # Production stage FROM node:20-alpine WORKDIR /app COPY --from=build /app/dist ./dist COPY package.json package-lock.json ./ RUN npm install --only=production CMD ["node", "dist/main.js"]
Builden der App mit Docker Compose
Nachdem alle Dockerfiles konfiguriert wurden können jetzt die Images gebuildet werden. Mit Docker compose ist das ganze wirklich einfach.
docker compose up -d --build
Anschließend sind die Images fertig, die Container gebaut und die App kann lokal direkt ausgetestet werden! Als letzer Schritt müssen die Images noch auf DockerHub hochgeladen werden, damit sie später leichter für das Deployment auf einem Server genutzt werden können.
Hochladen auf Docker Hub
Das Hochladen wird nachfolgend Schritt für Schritt erklärt:
- Erstelle einen Account bei Docker Hub.
- Erstelle ein Repository für das Frontend und Backend (1 privates Repo ist aktuell kostenlos).
- Baue die Images und tagge sie:
docker tag <image-id> dockerAccountName/frontend:latest docker tag <image-id> dockerAccountName/backend:latest
- Melde dich an und pushe die Images:
docker login docker push dockerAccountName/frontend:latest docker push dockerAccountName/backend:latest
Ausblick: Deployment mit Kubernetes
Da die Images nun auf Docker Hub sind, steht dem Deployment nichts mehr im Wege. Ich habe mich für ein Kubernetes-Cluster auf einem Hetzner-VPS entschieden. Mehr Infos dazu hier.