Cours Vibe coding avec l'IA · Module 13: Clone de Twitch
Docker & conteneurs
Dans cette leçon2
Conteneuriser une application Next.js.
Dockerfile
1FROM node:20-alpine AS base
2
3FROM base AS deps
4WORKDIR /app
5COPY package*.json ./
6RUN npm ci
7
8FROM base AS builder
9WORKDIR /app
10COPY /app/node_modules ./node_modules
11COPY . .
12RUN npm run build
13
14FROM base AS runner
15WORKDIR /app
16ENV NODE_ENV=production
17COPY /app/.next/standalone ./
18COPY /app/.next/static ./.next/static
19COPY /app/public ./public
20
21EXPOSE 3000
22CMD ["node", "server.js"]Docker Compose
1version: '3.8'
2services:
3 app:
4 build: .
5 ports:
6 - "3000:3000"
7 environment:
8 - DATABASE_URL=postgresql://...À bientôt !
Code de cette leçon : App.tsx
1'use client';
2
3interface StreamCardProps {
4 title: string;
5 category: string;
6 viewerCount: number;
7 channelName: string;
8 thumbnail: string;
9}
10
11const mockStreams: StreamCardProps[] = [
12 {
13 title: 'On code un bateau pirate à partir de zéro !',
14 category: 'Software & Game Development',
15 viewerCount: 1247,
16 channelName: 'Capitaine Barbe-Rouge',
17 thumbnail: 'https://images.unsplash.com/photo-1544551763-46a013bb70d5?w=400&h=225&fit=crop'
18 },
19 {
20 title: 'Tuto JavaScript - Créer des applis React',
21 category: 'Software & Game Development',
22 viewerCount: 892,
23 channelName: 'Matelot Sam',
24 thumbnail: 'https://images.unsplash.com/photo-1517694712202-14dd9538aa97?w=400&h=225&fit=crop'
25 },
26 {
27 title: 'Patterns avancés en TypeScript',
28 category: 'Science & Technology',
29 viewerCount: 567,
30 channelName: 'Navigatrice Nancy',
31 thumbnail: 'https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=400&h=225&fit=crop'
32 }
33];
34
35function StreamCard({ stream }: { stream: StreamCardProps }) {
36 return (
37 <div className="bg-gray-900 rounded overflow-hidden hover:scale-105 transition cursor-pointer">
38 <div className="relative">
39 <img
40 src={stream.thumbnail}
41 alt={stream.title}
42 className="w-full aspect-video object-cover"
43 />
44 <div className="absolute top-2 left-2 px-2 py-1 bg-red-600 text-white text-xs font-bold rounded">
45 LIVE
46 </div>
47 <div className="absolute bottom-2 left-2 px-2 py-1 bg-black/70 text-white text-xs rounded">
48 {stream.viewerCount.toLocaleString()} viewers
49 </div>
50 </div>
51
52 <div className="p-3">
53 <h3 className="font-semibold mb-1 line-clamp-2">{stream.title}</h3>
54 <p className="text-sm text-gray-400 mb-1">{stream.channelName}</p>
55 <p className="text-xs text-gray-500">{stream.category}</p>
56 </div>
57 </div>
58 );
59}
60
61export default function StreamGrid() {
62 return (
63 <div className="min-h-screen bg-gray-950 text-white p-8">
64 <h1 className="text-3xl font-bold mb-6">Live Channels</h1>
65
66 <div className="grid grid-cols-3 gap-4">
67 {mockStreams.map((stream, i) => (
68 <StreamCard key={i} stream={stream} />
69 ))}
70 </div>
71 </div>
72 );
73}Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Pourquoi conteneurise-t-on une application Next.js avec Docker ?
2. Quelle image de base le Dockerfile de la leçon utilise-t-il ?
Tâches pratiques dans le jeu
- Tri vertical
Ordonne les étapes du Dockerfile depuis le début du fichier :
- Tri horizontal
Ordonne le mapping de port dans docker-compose (une ligne) : "3000:3000"