# Kommunizieren mit Docker-Dienstcontainern

Hier erfährst du, wie du Docker-Dienstcontainer verwendest, um Datenbanken, Webdienste, Speichercaches und andere Tools mit deinem Workflow zu verbinden.

## Kommunizieren mit Docker-Dienstcontainern

Service-Container sind Docker-Container, die Dir eine einfache und portable Möglichkeit bieten, Dienste zu hosten, um Deine Anwendung in einem Workflow zu testen oder zu betreiben. Beispielsweise muss Dein Workflow möglicherweise Integrationstests ausführen, die Zugriff auf eine Datenbank und einen Speicher-Cache erfordern.

Du kannst Service-Container für jeden Job in einem Workflow konfigurieren.
GitHub erstellt einen neuen Docker-Container für jeden im Workflow konfigurierten Dienst und zerstört den Dienstcontainer, wenn der Auftrag abgeschlossen ist. Steps (Schritte) in einem Job können mit allen Service-Containern kommunizieren, die Teil des gleichen Jobs sind. Du kannst jedoch keine Service-Container innerhalb einer zusammengesetzten Aktion erstellen und verwenden.

> \[!NOTE]
> Wenn bei deinen Workflows Docker-Containeraktionen, Auftragscontainer oder Dienstcontainer verwendet werden, musst du einen Linux-Runner nutzen:
>
> * Wenn du GitHub-gehostete Runner verwendest, musst du einen Ubuntu-Runner verwenden.
> * Wenn du selbst gehostete Läufer verwendest, musst du einen Linux-Rechner als deinen Läufer verwenden und Docker muss installiert sein.

Du kannst Jobs in einem Workflow so konfigurieren, dass sie direkt auf einer Runner-Maschine oder in einem Docker-Container laufen. Die Kommunikation zwischen einem Job und seinen Service-Containern ist unterschiedlich, je nachdem, ob ein Job direkt auf der Runner-Maschine oder in einem Container läuft.

### Jobs in einem Container ausführen

Wenn Sie Aufträge in einem Container ausführen, GitHub verbinden Dienstcontainer sich mit dem Auftrag mithilfe der benutzerdefinierten Brückennetzwerke von Docker. Weitere Informationen findest du in der Docker-Dokumentation unter [Bridge-Netzwerktreiber](https://docs.docker.com/engine/network/drivers/bridge/).

Das Ausführen von Jobs und Diensten in einem Container vereinfacht den Netzwerkzugriff. Du kannst auf einen Service-Container mittels des Labels (Bezeichnung) zugreifen, den Du im Workflow konfigurierst. Der Hostname des Service-Containers wird automatisch dem Labelnamen zugeordnet. Wenn du z. B. einen Service-Container mit der Bezeichnung `redis` erstellst, ist auch der Hostname des Service-Containers `redis`.

Du brauchst für Service-Container keine Ports zu konfigurieren. Standardmäßig machen alle Container, die Teil desselben Docker-Netzwerks sind, alle Ports füreinander verfügbar, und außerhalb des Docker-Netzwerks werden keine Ports verfügbar gemacht.

### Jobs auf der Runner-Maschine ausführen

Wenn du Aufträge direkt auf dem Runnercomputer ausführst, kannst du mit `localhost:<port>` oder `127.0.0.1:<port>` auf Service-Container zugreifen.
GitHub konfiguriert das Containernetzwerk, um die Kommunikation vom Dienstcontainer an den Docker-Host zu ermöglichen.

Wenn ein Job direkt auf einer Runner-Maschine läuft, macht der im Docker-Container laufende Dienst seine Ports nicht standardmäßig dem Job auf dem Runner verfügbar. Du musst Ports auf dem Service-Container dem Docker Host zuordnen. Weitere Informationen finden Sie unter [Kommunizieren mit Docker-Dienstcontainern](/de/actions/tutorials/use-containerized-services/use-docker-service-containers#mapping-docker-host-and-service-container-ports).

## Service-Container erstellen

Du kannst das Schlüsselwort `services` verwenden, um Service-Container zu erstellen, die Teil eines Jobs in deinem Workflow sind. Weitere Informationen findest du unter [`jobs.<job_id>.services`](/de/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idservices).

In diesem Beispiel wird ein Dienst namens `redis` in einem Auftrag namens `container-job` erstellt. Der Docker-Host ist in diesem Beispiel der `node:16-bullseye`-Container.

```yaml copy
name: Redis container example
on: push

jobs:
  # Label of the container job
  container-job:
    # Containers must run in Linux based operating systems
    runs-on: ubuntu-latest
    # Docker Hub image that `container-job` executes in
    container: node:16-bullseye

    # Service containers to run with `container-job`
    services:
      # Label used to access the service container
      redis:
        # Docker Hub image
        image: redis
```

## Zuordnung der Ports zwischen Docker-Host und Service-Container.

Wenn Dein Job in einem Docker-Container läuft, brauchst Du keine Ports auf dem Host oder dem Service-Container zuzuordnen. Wenn Dein Job direkt auf der Runner-Maschine läuft, musst Du alle benötigten Service-Container-Ports zu Ports der Host-Runner-Maschine zuordnen.

Du kannst Service-Container-Ports mit Hilfe des Schlüsseworts `ports` dem Docker-Host zuordnen. Weitere Informationen findest du unter [`jobs.<job_id>.services`](/de/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idservices).

| Wert von `ports` | BESCHREIBUNG                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------- |
| `8080:80`        | Ordnet TCP-Port 80 im Container dem Port 8080 auf dem Docker-Host zu.                       |
| `8080:80/udp`    | Ordnet UDP-Port 80 im Container dem Port 8080 auf dem Docker-Host zu.                       |
| `8080/udp`       | Ordnet einen zufällig gewählten Port auf dem Docker-Host dem UDP-Port 8080 im Container zu. |

Wenn Sie Ports mithilfe des `ports` Schlüsselworts zuordnen, verwendet GitHub den `--publish` Befehl, um die Ports des Containers auf dem Docker-Host zu veröffentlichen. Weitere Informationen findest du in der Docker-Dokumentation unter [Docker-Containernetzwerke](https://docs.docker.com/config/containers/container-networking/).

Wenn Du den Port des Containers angibst, aber nicht den des Docker-Hosts, dann wird der Container-Port zufällig einem freien Port zugewiesen.
GitHub legt den zugewiesenen Containerport im Dienstcontainerkontext fest. Wenn du beispielsweise den Port 5432 für den Docker-Host konfiguriert hast, kannst Du für einen Service-Container `redis` mit dem Kontext `job.services.redis.ports[5432]` auf den entsprechenden Port des Containers zugreifen. Weitere Informationen finden Sie unter [Kontextreferenz](/de/actions/reference/workflows-and-actions/contexts#job-context).

### Beispiel zur Zuordnung von Redis-Ports

Dieses Beispiel ordnet den Port 6379 des Service-Containers `redis` dem Port 6379 des Docker-Hosts zu.

```yaml copy
name: Redis Service Example
on: push

jobs:
  # Label of the container job
  runner-job:
    # You must use a Linux environment when using service containers or container jobs
    runs-on: ubuntu-latest

    # Service containers to run with `runner-job`
    services:
      # Label used to access the service container
      redis:
        # Docker Hub image
        image: redis
        #
        ports:
          # Opens tcp port 6379 on the host and service container
          - 6379:6379
```

## Authentifizieren mit Bildregistrierungen

Du kannst Anmeldeinformationen für deine Dienstcontainer angeben, falls du dich bei einer Bildregistrierung authentifizieren musst. So kannst du Bilder aus privaten Registrierungen verwenden oder [deine DockerHub-Ratenbegrenzung](https://www.docker.com/increase-rate-limits/) erhöhen.

Hier ist ein Beispiel für die Authentifizierung mit Docker Hub und der GitHubContainer registry:

```yaml copy
jobs:
  build:
    services:
      redis:
        # Docker Hub image
        image: redis
        ports:
          - 6379:6379
        credentials:
          username: ${{ secrets.dockerhub_username }}
          password: ${{ secrets.dockerhub_password }}
      db:
        # Private registry image
        image: ghcr.io/octocat/testdb:latest
        credentials:
          username: ${{ github.repository_owner }}
          password: ${{ secrets.ghcr_password }}
```

## Anpassen von Dienstcontainereintragspunkten und -befehlen

Standardmäßig werden Dienstcontainer mit dem Entrypoint und Befehl ausgeführt, der im Docker-Image definiert ist. Sie können diese überschreiben, indem Sie die Tasten `entrypoint` und `command` verwenden. Dies ist nützlich, wenn Sie Flags an einen Dienst (z. B. eine Datenbank) übergeben oder den Bildeintragspunkt vollständig austauschen müssen, ohne ein benutzerdefiniertes Wrapperimage zu erstellen.

Der `command` Schlüssel setzt den Standardbefehl (`CMD`) des Bilds außer Kraft. Die meisten Szenarien benötigen nur `command` – das Bild verfügt bereits über den richtigen Einstiegspunkt, Sie müssen nur Flags übergeben:

```yaml copy
services:
  mysql:
    image: mysql:8
    command: --sql_mode=STRICT_TRANS_TABLES --max_allowed_packet=512M
    env:
      MYSQL_ROOT_PASSWORD: test
    ports:
      - 3306:3306
```

Der `entrypoint`-Key setzt das `ENTRYPOINT` des Bildes außer Kraft. Sie können es mit `command` kombinieren, um Argumente an den benutzerdefinierten Einstiegspunkt zu übergeben.

```yaml copy
services:
  etcd:
    image: quay.io/coreos/etcd:v3.5.17
    entrypoint: etcd
    command: >-
      --listen-client-urls http://0.0.0.0:2379
      --advertise-client-urls http://0.0.0.0:2379
    ports:
      - 2379:2379
```

Die Benennung und das Verhalten stimmen mit Docker Compose überein. Weitere Informationen finden Sie unter [`jobs.<job_id>.services.<service_id>.command`](/de/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idservicesservice_idcommand) und [`jobs.<job_id>.services.<service_id>.entrypoint`](/de/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idservicesservice_identrypoint).

## Weiterführende Lektüre

* [Redis-Service-Container erstellen](/de/actions/tutorials/use-containerized-services/create-redis-service-containers)
* [PostgreSQL-Service-Container erstellen](/de/actions/tutorials/use-containerized-services/create-postgresql-service-containers)