Online zetten: alles in één bestand
Je container uit les 20 draait nog, en hij startte met een lange regel:
docker run -d --name gastenboek -p 8000:8000 -v gastenboek-data:/app/data gastenboek
Elke keer moet je die precies goed typen, en één tikfout geeft een leeg volume (les 20). Met Docker Compose zet je wat er in die regel staat in een bestand, en start je alles met één kort commando.
compose.yaml
Maak naast de Dockerfile een bestand compose.yaml:
services:
gastenboek:
build: .
ports:
- "127.0.0.1:8000:8000"
volumes:
- data:/app/data
restart: unless-stopped
volumes:
data:
Het is YAML: een bestand van namen en waarden, waarin de inspringing zegt wat bij wat hoort. Gebruik spaties, nooit een tab, en steeds twee per niveau.
| Regel | Betekenis |
|---|---|
services: | de containers van dit project; hier één, gastenboek |
build: . | bouw het image met de Dockerfile in deze map |
ports: | wat -p deed, maar alleen voor deze computer: 127.0.0.1 ervoor |
volumes: (bij de service) | wat -v deed: het volume data in /app/data |
restart: unless-stopped | start de container opnieuw na een crash of een herstart, tenzij jij hem stopte |
volumes: (onderaan) | de volumes die dit project gebruikt |
Starten en stoppen
Gooi eerst de container uit de vorige les weg, want die heeft poort 8000. Start daarna alles:
docker rm -f gastenboek
docker compose up -d --build
up maakt en start wat er in compose.yaml staat, -d zet het op de achtergrond, en --build bouwt het image eerst opnieuw. Kijk wat er draait:
docker compose ps
Compose verzint de namen zelf, met de naam van je map ervoor: de container heet gastenboek-gastenboek-1, het image gastenboek-gastenboek, en het volume gastenboek_data. Je hoeft die namen niet te typen. Elk docker compose-commando in deze map gaat over dit project:
| Commando | Wat er gebeurt |
|---|---|
docker compose up -d --build | bouwen en starten, of bijwerken als het al draait |
docker compose ps | wat er draait |
docker compose logs -f | meekijken in de logboeken, tot Ctrl+C |
docker compose down | containers stoppen en weggooien; het volume blijft |
Zet compose.yaml in git:
git add compose.yaml
git commit -m "Compose"
git push
Opruimen
Het image gastenboek van je losse container heb je niet meer nodig: Compose bouwt zijn eigen image. Ook de containers van hello-world en die uit les 16 staan nog in docker ps -a, gestopt. Ruim ze op:
docker container prune
docker image rm gastenboek
docker container prune vraagt Are you sure you want to continue? [y/N]. Typ y: hij gooit elke gestopte container weg, en laat je site, die draait, staan. Daarna gebruikt geen container het image gastenboek meer, en mag het weg. Het image van hello-world gooi je op dezelfde manier weg: docker image rm hello-world.
Er gaat iets mis
De berichten uit les 20 zijn weg
Oorzaak: Compose maakte een nieuw volume, gastenboek_data. Je berichten staan nog in gastenboek-data, het volume uit de vorige les.
Oplossing: op je laptop is dat geen ramp: het waren testberichten. Met docker volume ls zie je ze allebei, en het oude gooi je weg met docker volume rm gastenboek-data. Op de server begin je meteen met Compose.
additional properties not allowed
validating /home/sam/gastenboek/compose.yaml: services.gastenboek additional properties 'volume' not allowed
Oorzaak: een tikfout in een naam: hier volume in plaats van volumes. Compose kent die naam niet.
Oplossing: verbeter de naam die in de melding staat. Met docker compose config controleer je het bestand zonder iets te starten.
found a tab character
yaml: line 3: found a tab character that violates indentation
Oorzaak: er staat een tab in plaats van spaties. De fout staat op de regel die Compose noemt, of de regel erna.
Oplossing: vervang de tab door spaties. In VS Code zie je rechtsonder Spaces: 2 of Tab Size; klik erop en kies Indent Using Spaces.
unable to delete gastenboek:latest
Error response from daemon: conflict: unable to delete gastenboek:latest (must be forced) - container e71d0225ee86 is using its referenced image 00aedae74c12
Oorzaak: er bestaat nog een container van het image gastenboek, draaiend of gestopt.
Oplossing: gooi die container eerst weg, met docker rm -f en de naam uit de melding, of met docker container prune als hij gestopt is. Typ daarna opnieuw docker image rm gastenboek.
port is already allocated
Bind for 127.0.0.1:8000 failed: port is already allocated
Oorzaak: de container uit de vorige les draait nog, met poort 8000.
Oplossing: docker rm -f gastenboek, en daarna opnieuw docker compose up -d.
Speel zonder computer na wat er blijft bij stop, een nieuwe versie, down en down -v: Wat blijft er over?. Je docent kan de hand-out printen.
Opdrachten
Opdracht 1: Run - Je site met Compose
Maak compose.yaml, start je site met docker compose up -d --build, en schrijf een bericht. Typ daarna in PowerShell wsl --shutdown, zodat Linux helemaal uitgaat, en open Ubuntu opnieuw. Draait je site nog?
Antwoord
Ja. Bij het openen van Ubuntu start de dienst van Docker, en restart: unless-stopped start daarna je container. Je bericht staat er nog, want het volume bleef staan. Op een server werkt het net zo na een herstart, en dan hoeft niemand Ubuntu te openen.
Opdracht 2: Make - Je README bij
Schrijf in je README hoe je je site met Docker start. Commit compose.yaml en de README, en push.
Antwoord
Bijvoorbeeld een extra kop onder Starten:
## Starten met Docker
```
docker compose up -d --build
```
Open `http://127.0.0.1:8000`. Stoppen doe je met `docker compose down`.
Wie je repository ophaalt en Docker heeft, heeft nu geen virtual environment en geen packages meer nodig. Dat is ook wat de server straks doet.
Door naar les 22: een voordeur met Traefik.