Introduction : pourquoi TypeScript et Kubernetes forment un duo idéal
Le développement web moderne est impensable sans deux éléments : le typage statique et une infrastructure scalable. TypeScript apporte la fiabilité du code à l'étape de compilation, tandis que Kubernetes (K8s) assure la gestion automatique des conteneurs, l'équilibrage de charge et l'auto-réparation. Dans ce guide, nous parcourrons le chemin complet, d'une simple application TypeScript à son déploiement dans un cluster Kubernetes. Vous apprendrez à empaqueter le code dans une image Docker, à rédiger des manifestes et à déployer un service prêt pour la production.
Étape 1 : Préparation de l'application TypeScript pour la conteneurisation
Avant de penser à Kubernetes, il faut s'assurer que votre application est prête à être exécutée dans un conteneur. Créons une simple application Express en TypeScript. Assurez-vous qu'à la racine du projet se trouvent package.json, tsconfig.json et le point d'entrée src/index.ts.
// src/index.tsimport express, { Request, Response } from 'express';
const app = express();const PORT = process.env.PORT || 3000;
app.get('/health', (_req: Request, res: Response) => { res.json({ status: 'ok', timestamp: new Date().toISOString() });});
app.get('/', (_req: Request, res: Response) => { res.send('Hello from TypeScript on Kubernetes!');});
app.listen(PORT, () => { console.log(`Server running on port ${PORT}`);});Un point important : en production, nous n'utilisons pas ts-node. Ajoutez donc un script de build dans package.json :
"scripts": { "build": "tsc", "start": "node dist/index.js"}Après avoir exécuté npm run build, le dossier dist contiendra le JavaScript compilé. C'est ce dossier que nous allons copier dans l'image Docker.
Étape 2 : Création d'une image Docker de taille minimale
Pour un déploiement en production, la taille de l'image est cruciale. Utilisons une construction multi-étapes : d'abord, compilons TypeScript dans un conteneur avec le SDK complet, puis copions le résultat dans une image légère basée sur node:18-alpine.
# Dockerfile# Stage 1 : BuildFROM node:18-alpine AS builderWORKDIR /appCOPY package*.json ./RUN npm ci --only=productionCOPY tsconfig.json ./COPY src/ ./src/RUN npm run build
# Stage 2 : ProductionFROM node:18-alpineWORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesEXPOSE 3000CMD ["node", "dist/index.js"]Construisez l'image et testez-la localement :
docker build -t my-ts-app:latest .docker run -p 3000:3000 my-ts-app:latestOuvrez http://localhost:3000 — vous devriez voir le message de bienvenue.
Étape 3 : Manifestes Kubernetes — Deployment et Service
Transférons maintenant notre image dans le cluster. Pour cela, deux manifestes de base sont nécessaires : Deployment (gère les répliques et les mises à jour) et Service (assure l'accès réseau).
deployment.yaml
apiVersion: apps/v1kind: Deploymentmetadata: name: ts-app-deploymentspec: replicas: 2 selector: matchLabels: app: ts-app template: metadata: labels: app: ts-app spec: containers: - name: ts-app image: my-ts-app:latest imagePullPolicy: IfNotPresent ports: - containerPort: 3000 env: - name: PORT value: "3000" livenessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 3 periodSeconds: 5service.yaml
apiVersion: v1kind: Servicemetadata: name: ts-app-servicespec: selector: app