|
|
|
Docker ist ein Container Management System, mit dem man Code auf jeder Maschine unabhängig vom Betriebssystem ausführen kann. Mehr über Docker kannst du in der offiziellen [Docker Dokumentation](https://docs.docker.com/manuals/) finden
|
|
|
|
|
|
|
|
[TOC]
|
|
|
|
|
|
|
|
## Dockerfile
|
|
|
|
|
|
|
|
Dockerfiles beschreiben die Schritte, die für das erstellen eines Containers befolgt werden. In diesem Repository sind zwei Dockerfiles. Wie diese erweitert werden können, findet man in der [offiziellen Dockerfile Referenz](https://docs.docker.com/reference/dockerfile/).
|
|
|
|
|
|
|
|
### Datenbank
|
|
|
|
|
|
|
|
Diese Dockerfile startet eine [Postgres Datenbank](https://www.postgresql.org). Im moment wird das `postgres:16-alpine` image genommen. Beim start wird das Password auf `password` gesetzt und der Standardport `5432` erreichbar gemacht. Solltest du diesen Container öffentlich zugänglich machen, änder **unbedingt** das Password. Als letzten Schritt kopiert die Dockerfile die `schema.sql` Datei in `/docker-entrypoint-initdb.d/`, wo beim Containerstart alle SQL Befehle ausgeführt werden.
|
|
|
|
|
|
|
|
### API
|
|
|
|
|
|
|
|
Die Dockerfile für die API benutzt das neuste `node` image, kopier `package.json` und `package-lock.json` in den Container und installiert damit dann die dependencies. Danach wird jede Datei, die nicht von der `.dockerignore` ingoriert wird in den Container kopiert um ihn dann mit `node . ` zu starten. Standardmäßig macht die Dockerfile den Port `3000` zugänglich, solltest du das ändern wollen, musst du das dann auch in der `index.js` tun.
|
|
|
|
|
|
|
|
## docker-compose.yaml
|
|
|
|
|
|
|
|
Docker Compose Dateien haben feste Anweisungen, wie Container und ihre Umgebung erstellt werden sollen. Mit ihnen kann man Container in geteilte Netzwerke packen, ihnen namen geben, Ports öffnen und Healthchecks definieren.
|
|
|
|
|
|
|
|
### Netzwerk
|
|
|
|
|
|
|
|
Compose erstellt ein Netzwerk, welches die API mit der Datenbank für Kommunikation verknüpft, ohne sie öffentlich zugänglich zu machen
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
networks:
|
|
|
|
evaluation-network:
|
|
|
|
diver: bridge
|
|
|
|
```
|
|
|
|
|
|
|
|
### Bauen
|
|
|
|
|
|
|
|
Container werden mit dem `services:` Schlüssel erstellt
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
services:
|
|
|
|
database:
|
|
|
|
build:
|
|
|
|
context: ./
|
|
|
|
dockerfile: Dockerfile
|
|
|
|
api:
|
|
|
|
build:
|
|
|
|
context: ./api
|
|
|
|
dockerfile: Dockerfile
|
|
|
|
```
|
|
|
|
|
|
|
|
Der `context` Schlüssel gibt Docker den Path unter dem es die Dockerfile erwarten kann um das image zu bauen.
|
|
|
|
|
|
|
|
### Health check
|
|
|
|
|
|
|
|
Um sicherzugehen, dass die Datenbank vollständig funktioniert, wird ein Healthcheck erstellt. Dieser ruft alle 10 Sekunden `pg_isready` auf, bis die Abfrage erfolgreich war. `pg_isready` ist eine Funktion von Postgres selbst, welche nur erfolgreich endet, falls die Datenbank richtig gestartet wurde und Verbindungen akzeptiert.
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
healthcheck:
|
|
|
|
test: ["CMD", "pg_isready"]
|
|
|
|
interval: 10s
|
|
|
|
timeout: 1s
|
|
|
|
retries: 3
|
|
|
|
```
|
|
|
|
|
|
|
|
Der API container kann dann auf diesen Healthcheck warten, bevor er startet.
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
depends_on:
|
|
|
|
database:
|
|
|
|
condition: service_healthy
|
|
|
|
```
|
|
|
|
|
|
|
|
### Umgebungsvariablen
|
|
|
|
|
|
|
|
Wenn die API manuell gestartet wird, liest diese die `.env` Datei aus. Damit die API dasselbe in Docker kann, müssen die gleichen Umgebungsvariablen mit dem `environment` Schlüssel angegeben werden.
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
environment:
|
|
|
|
- DB_HOST=database
|
|
|
|
- DB_USER=postgres
|
|
|
|
- DB_PASS=password
|
|
|
|
- DB_DATABASE=evaluation
|
|
|
|
```
|
|
|
|
|
|
|
|
Solltest du diese Daten irgendwo beim erstellen des Datenbank Containers verändert haben, musst du diese auch hier ändern.
|
|
|
|
|
|
|
|
### Port
|
|
|
|
|
|
|
|
Da beide Container isoliert auf einem Netzwerk liegen, muss die API extra anfragbar gemacht werden. Dafür muss einfach nur der `ports` Schlüssel konfiguriert werden:
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
ports:
|
|
|
|
- "50000:3000"
|
|
|
|
```
|
|
|
|
|
|
|
|
Solltest du in der API Dockerfile den Port veränder haben, musst du die `3000` hier durch diesen ersetzten. Solltest du deine API auf einem anderen Port als `50000` erreichen wollen, musst du diese hier mit einer anderen Zahl ersetzen. Denk aber dran, dass nicht alle Ports verfügbar sind, wie auf [dieser Liste](https://de.wikipedia.org/wiki/Liste_der_Portnummern) zu finden ist. |
|
|
|
\ No newline at end of file |