Docker und TypeScript: Containerisierung von Anwendungen von A bis Z

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Docker und TypeScript: Containerisierung von Anwendungen von A bis Z



Die Containerisierung ist zum Standard der modernen Softwareentwicklung geworden. Docker ermöglicht es, eine TypeScript-Anwendung zusammen mit allen Abhängigkeiten und der Umgebung zu verpacken und so einen stabilen Betrieb auf jeder Plattform zu gewährleisten – vom lokalen Entwicklungsrechner bis zum Produktionsserver. In diesem Artikel betrachten wir den gesamten Zyklus: vom grundlegenden Dockerfile bis zum optimierten Production-Build.



1. Grundlagen von Docker für TypeScript-Entwickler



Docker ist eine Plattform zum Erstellen, Bereitstellen und Ausführen von Anwendungen in isolierten Umgebungen (Containern). Für TypeScript-Anwendungen, die in JavaScript kompiliert werden und auf Node.js laufen, löst Docker drei zentrale Aufgaben:



  • Reproduzierbarkeit der Umgebung: Vergessen Sie den Satz "bei mir funktioniert es". Die Versionen von Node.js, npm und Systempaketen sind im Image festgelegt.
  • Isolation: Jede Anwendung läuft in ihrem eigenen Container, ohne andere Dienste zu beeinflussen.
  • Skalierung: Container lassen sich leicht replizieren und orchestrieren.


Stellen Sie vor Beginn der Arbeit sicher, dass Docker und Docker Compose installiert sind. Überprüfen können Sie dies mit den Befehlen:



docker --versiondocker-compose --version


2. Erstellen eines Dockerfile für eine TypeScript-Anwendung



Beginnen wir mit einer einfachen TypeScript-Anwendung. Angenommen, wir haben eine Datei src/index.ts:



import express from 'express';

const app = express();const port = process.env.PORT || 3000;

app.get('/', (req, res) => { res.send('Hello from Docker + TypeScript!');});

app.listen(port, () => { console.log(`Server started on port ${port}`);});


Jetzt erstellen wir ein Dockerfile im Projektstammverzeichnis:



# ---- Basis-Image für die Entwicklung ----FROM node:18-alpine AS baseWORKDIR /appCOPY package*.json ./RUN npm ci --only=production

# ---- TypeScript-Build ----FROM base AS buildCOPY tsconfig.json ./COPY src/ ./src/RUN npm ci && npm run build

# ---- Production-Image ----FROM node:18-alpine AS productionWORKDIR /appCOPY --from=build /app/dist ./distCOPY --from=base /app/node_modules ./node_modulesEXPOSE 3000CMD ["node", "dist/index.js"]


Dies ist ein Multi-Stage-Build. Er ermöglicht:

  • Alle Abhängigkeiten (einschließlich devDependencies) nur in der Build-Phase zu installieren
  • Nur den kompilierten JavaScript-Code und die Production-Abhängigkeiten in das endgültige Image zu übernehmen
  • Die Image-Größe um das 2- bis 3-fache zu reduzieren


Erstellen Sie das Image und starten Sie den Container:



docker build -t my-typescript-app .docker run -p 3000:3000 my-typescript-app


3. Einrichtung von docker-compose für Entwicklung und Produktion



Docker Compose vereinfacht die Arbeit mit Multi-Container-Anwendungen. Erstellen wir eine docker-compose.yml:



version: '3.8'

services: app: build: context: . target: development ports: - "3000:3000" volumes: - .:/app - /app/node_modules environment: - NODE_ENV=development command: npm run dev

# Produktionsversion app-prod: build: context: . target: production ports: - "80:3000" environment: - NODE_ENV=production


Fügen wir der Einfachheit halber ein separates Dockerfile für die Entwicklung hinzu (das Basis-Image kann erweitert werden):



# Dockerfile.devFROM node:18-alpineWORKDIR /appCOPY package*.json ./RUN npm installCOPY . .EXPOSE 3000CMD ["npm", "run", "dev"]


Starten im Entwicklungsmodus:



docker-compose up app


Dank volumes werden Änderungen im Code sofort übernommen (Hot-Reload), und /app/node_modules wird ausgeschlossen, um die Abhängigkeiten aus dem Container nicht zu überschreiben.

Blogs

Buchempfehlungen