Note
Dieses Feature befindet sich aktuell in der public preview und kann noch geändert werden.
Informationen zur Containeranpassung
GitHub Actions ermöglicht die Ausführung eines Auftrags in einem Container, wenn die Anweisung container:
in der Workflow-Datei verwendet wird. Weitere Informationen findest du unter Jobs in einem Container ausführen. Um containerbasierte Aufträge zu verarbeiten, erstellt der selbstgehostete Runner einen Container für jeden Auftrag.
GitHub Actions unterstützt Befehle, mit denen angepasst werden kann, wie Container vom selbstgehosteten Runner erstellt werden. Du kannst diese Befehle beispielsweise verwenden, um die Container über Kubernetes oder Podman zu verwalten. Außerdem kannst du die Befehle docker run
und docker create
anpassen, die zum Aufrufen des Containers verwendet werden. Die Anpassungsbefehle werden von einem Skript ausgeführt, das automatisch ausgelöst wird, wenn eine bestimmte Umgebungsvariable auf dem Runner festgelegt wird. Weitere Informationen findest du weiter unten unter Auslösen des Anpassungsskripts.
Diese Anpassung ist nur für Linux-basierte selbstgehostete Runner verfügbar. Es ist kein Root-Benutzer-Zugriff erforderlich.
Befehle für die Containeranpassung
GitHub Actions enthält die folgenden Befehle für die Containeranpassung:
prepare_job
: Wird aufgerufen, wenn ein Auftrag gestartet wirdcleanup_job
: Wird am Ende eines Auftrags aufgerufenrun_container_step
: Wird einmal für jede Containeraktion im Auftrag aufgerufenrun_script_step
: Führt jeden Schritt aus, der keine Containeraktion ist
Jede dieser Anpassungsbefehle muss in einer eigenen JSON-Datei definiert werden. Der Dateiname muss mit dem Befehlsname übereinstimmen und die Erweiterung .json
aufweisen. Der Befehl prepare_job
wird beispielsweise in prepare_job.json
definiert. Diese JSON-Dateien werden dann im selbstgehosteten Runner als Teil des index.js
-Hauptskripts zusammen ausgeführt. Dieser Prozess wird unter Generieren des Anpassungsskripts ausführlicher beschrieben.
Diese Befehle enthalten auch Konfigurationsargumente, die unten ausführlicher erläutert werden.
prepare_job
Der Befehl prepare_job
wird aufgerufen, wenn ein Auftrag gestartet wird. GitHub Actions übergibt alle Auftrags- oder Dienstcontainer, die im Auftrag enthalten sind. Dieser Befehl wird aufgerufen, wenn Dienst- oder Auftragscontainer im Auftrag vorhanden sind.
GitHub Actions geht davon aus, dass die folgenden Aufgaben mit dem Befehl prepare_job
erledigt werden:
- Bei Bedarf alle Inhalte aus vorherigen Aufträgen löschen
- Bei Bedarf ein Netzwerk erstellen
- Den Auftrag und die Dienstcontainer pullen
- Den Auftragscontainer starten
- Die Dienstcontainer starten
- Alle von GitHub Actions benötigten Informationen in die Antwortdatei schreiben:
- Erforderlich: Angabe, ob der Container ein
alpine
-Linux-Container ist (mit der booleschen VariablenisAlpine
) - Optional: Kontextfelder, die für den Auftragskontext festgelegt werden sollen – nur dann sind diese für Benutzer*innen verfügbar. Weitere Informationen findest du unter Zugreifen auf kontextbezogene Informationen zu Workflowausführungen.
- Erforderlich: Angabe, ob der Container ein
0
zurückgeben, wenn die Integritätsprüfungen bestanden und die Auftrags- und Dienstcontainer gestartet wurden
Argumente für prepare_job
jobContainer
: (optional) Ein Objekt mit Informationen zum angegebenen Auftragscontainerimage
: (erforderlich) Eine Zeichenfolge, die das Docker-Image enthältworkingDirectory
: (erforderlich) Eine Zeichenfolge, die den absoluten Pfad des Arbeitsverzeichnisses enthältcreateOptions
: (optional) Die optionalen Erstellungsoptionen, die in der YAML-Datei angegeben sind. Weitere Informationen findest du unter Jobs in einem Container ausführen.environmentVariables
: (optional) Legt eine Zuordnung der Schlüsselumgebungsvariablen festuserMountVolumes
: (optional) Ein Array der benutzerseitig eingebundenen Volumes, das in der YAML-Datei festgelegt wird. Weitere Informationen findest du unter Jobs in einem Container ausführen.sourceVolumePath
: (erforderlich) Der Quellpfad zum Volume, das im Docker-Container bereitgestellt wirdtargetVolumePath
: (erforderlich) Der Zielpfad zum Volume, das im Docker-Container bereitgestellt wirdreadOnly
: (erforderlich) Legt, ob das eingebundene Volume schreibgeschützt sein soll
systemMountVolumes
: (erforderlich) Ein Array der eingebundenen Volumes, die in den Container eingebunden werden sollen (mit den gleichen Feldern wie oben)sourceVolumePath
: (erforderlich) Der Quellpfad zum Volume, das im Docker-Container bereitgestellt wirdtargetVolumePath
: (erforderlich) Der Zielpfad zum Volume, das im Docker-Container bereitgestellt wirdreadOnly
: (erforderlich) Legt, ob das eingebundene Volume schreibgeschützt sein soll
registry
: (optional) Die Docker-Registrierungsanmeldeinformationen für eine private Containerregistrierungusername
: (optional) Der Benutzername des Registrierungskontospassword
: (optional) Das Kennwort für das RegistrierungskontoserverUrl
: (optional) Die Registrierungs-URL
portMappings
: (optional) Ein Schlüssel-Wert-Hash der source:target-Ports, die dem Container zugeordnet werden sollen
services
: (optional) Ein Array der Dienstcontainer, die gestartet werden sollencontextName
: (erforderlich) Der Name des Diensts im Auftragskontextimage
: (erforderlich) Eine Zeichenfolge, die das Docker-Image enthältcreateOptions
: (optional) Die optionalen Erstellungsoptionen, die in der YAML-Datei angegeben sind. Weitere Informationen findest du unter Jobs in einem Container ausführen.environmentVariables
: (optional) Legt eine Zuordnung der Schlüsselumgebungsvariablen festuserMountVolumes
: (optional) Ein Array der eingebundenen Volumes, die in den Container eingebunden werden sollen (mit den gleichen Feldern wie oben)sourceVolumePath
: (erforderlich) Der Quellpfad zum Volume, das im Docker-Container bereitgestellt wirdtargetVolumePath
: (erforderlich) Der Zielpfad zum Volume, das im Docker-Container bereitgestellt wirdreadOnly
: (erforderlich) Legt, ob das eingebundene Volume schreibgeschützt sein soll
registry
: (optional) Die Docker-Registrierungsanmeldeinformationen für die private Containerregistrierungusername
: (optional) Der Benutzername des Registrierungskontospassword
: (optional) Das Kennwort für das RegistrierungskontoserverUrl
: (optional) Die Registrierungs-URL
portMappings
: (optional) Ein Schlüssel-Wert-Hash der source:target-Ports, die dem Container zugeordnet werden sollen
Beispieleingabe für prepare_job
{ "command": "prepare_job", "responseFile": "/users/octocat/runner/_work/{guid}.json", "state": {}, "args": { "jobContainer": { "image": "node:18" "workingDirectory": "/__w/octocat-test2/octocat-test2", "createOptions": "--cpus 1", "environmentVariables": { "NODE_ENV": "development" }, "userMountVolumes": [ { "sourceVolumePath": "my_docker_volume", "targetVolumePath": "/volume_mount", "readOnly": false } ], "systemMountVolumes": [ { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work", "targetVolumePath": "/__w", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/externals", "targetVolumePath": "/__e", "readOnly": true }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp", "targetVolumePath": "/__w/_temp", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_actions", "targetVolumePath": "/__w/_actions", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_tool", "targetVolumePath": "/__w/_tool", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_home", "targetVolumePath": "/github/home", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_workflow", "targetVolumePath": "/github/workflow", "readOnly": false } ], "registry": { "username": "octocat", "password": "examplePassword", "serverUrl": "https://index.docker.io/v1" }, "portMappings": { "80": "801" } }, "services": [ { "contextName": "redis", "image": "redis", "createOptions": "--cpus 1", "environmentVariables": {}, "userMountVolumes": [], "portMappings": { "80": "801" }, "registry": { "username": "octocat", "password": "examplePassword", "serverUrl": "https://index.docker.io/v1" } } ] } }
{
"command": "prepare_job",
"responseFile": "/users/octocat/runner/_work/{guid}.json",
"state": {},
"args": {
"jobContainer": {
"image": "node:18"
"workingDirectory": "/__w/octocat-test2/octocat-test2",
"createOptions": "--cpus 1",
"environmentVariables": {
"NODE_ENV": "development"
},
"userMountVolumes": [
{
"sourceVolumePath": "my_docker_volume",
"targetVolumePath": "/volume_mount",
"readOnly": false
}
],
"systemMountVolumes": [
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work",
"targetVolumePath": "/__w",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/externals",
"targetVolumePath": "/__e",
"readOnly": true
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp",
"targetVolumePath": "/__w/_temp",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_actions",
"targetVolumePath": "/__w/_actions",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_tool",
"targetVolumePath": "/__w/_tool",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_home",
"targetVolumePath": "/github/home",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_workflow",
"targetVolumePath": "/github/workflow",
"readOnly": false
}
],
"registry": {
"username": "octocat",
"password": "examplePassword",
"serverUrl": "https://index.docker.io/v1"
},
"portMappings": { "80": "801" }
},
"services": [
{
"contextName": "redis",
"image": "redis",
"createOptions": "--cpus 1",
"environmentVariables": {},
"userMountVolumes": [],
"portMappings": { "80": "801" },
"registry": {
"username": "octocat",
"password": "examplePassword",
"serverUrl": "https://index.docker.io/v1"
}
}
]
}
}
Beispielausgabe für prepare_job
Diese Beispielausgabe entspricht dem Inhalt der in der obigen Eingabe definierten responseFile
-Datei.
{ "state": { "network": "example_network_53269bd575972817b43f7733536b200c", "jobContainer": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480", "serviceContainers": { "redis": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105" } }, "context": { "container": { "id": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480", "network": "example_network_53269bd575972817b43f7733536b200c" }, "services": { "redis": { "id": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105", "ports": { "8080": "8080" }, "network": "example_network_53269bd575972817b43f7733536b200c" } }, "isAlpine": true } }
{
"state": {
"network": "example_network_53269bd575972817b43f7733536b200c",
"jobContainer": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480",
"serviceContainers": {
"redis": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105"
}
},
"context": {
"container": {
"id": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480",
"network": "example_network_53269bd575972817b43f7733536b200c"
},
"services": {
"redis": {
"id": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105",
"ports": {
"8080": "8080"
},
"network": "example_network_53269bd575972817b43f7733536b200c"
}
},
"isAlpine": true
}
}
cleanup_job
Der Befehl cleanup_job
wird am Ende eines Auftrags aufgerufen. GitHub Actions geht davon aus, dass die folgenden Aufgaben mit dem Befehl cleanup_job
erledigt werden:
- Alle ausgeführten Dienst- oder Auftragscontainer (oder den entsprechenden Pod) beenden
- Netzwerk beenden (falls vorhanden)
- Alle Auftrags- oder Dienstcontainer (oder den entsprechenden Pod) löschen
- Netzwerk löschen (falls vorhanden)
- Alle Inhalte bereinigen, die für den Auftrag erstellt wurden
Argumente für cleanup_job
Es werden keine Argumente für cleanup_job
angegeben.
Beispieleingabe für cleanup_job
{ "command": "cleanup_job", "responseFile": null, "state": { "network": "example_network_53269bd575972817b43f7733536b200c", "jobContainer": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480", "serviceContainers": { "redis": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105" } }, "args": {} }
{
"command": "cleanup_job",
"responseFile": null,
"state": {
"network": "example_network_53269bd575972817b43f7733536b200c",
"jobContainer": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480",
"serviceContainers": {
"redis": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105"
}
},
"args": {}
}
Beispielausgabe für cleanup_job
Es wird keine Ausgabe für cleanup_job
erwartet.
run_container_step
Der Befehl run_container_step
wird einmal für jede Containeraktion im Auftrag aufgerufen. GitHub Actions geht davon aus, dass die folgenden Aufgaben mit dem Befehl run_container_step
erledigt werden:
- Den erforderlichen Container pullen oder erstellen (oder einen Fehler ausgeben, falls das nicht möglich ist)
- Die Containeraktion ausführen und den Exitcode für den Container zurückgeben
- Alle Schrittprotokollausgaben für stdout und stderr streamen
- Den Container nach der Ausführung bereinigen
Argumente für run_container_step
image
: (optional) Eine Zeichenfolge, die das Docker-Image enthält. Andernfalls muss ein Dockerfile bereitgestellt werden.dockerfile
: (optional) Eine Zeichenfolge, die den Pfad zum Dockerfile enthält, andernfalls muss ein Image bereitgestellt werden.entryPointArgs
: (optional) Eine Liste, die die Einstiegspunktargumente enthältentryPoint
: (optional) Der zu verwendende Containereinstiegspunkt, wenn der Standardeinstiegspunkt des Images überschrieben werden sollworkingDirectory
: (erforderlich) Eine Zeichenfolge, die den absoluten Pfad des Arbeitsverzeichnisses enthältcreateOptions
: (optional) Die optionalen Erstellungsoptionen, die in der YAML-Datei angegeben sind. Weitere Informationen findest du unter Jobs in einem Container ausführen.environmentVariables
: (optional) Legt eine Zuordnung der Schlüsselumgebungsvariablen festprependPath
: (optional) Ein Array zusätzlicher Pfade, die der Variablen$PATH
vorangestellt werden sollenuserMountVolumes
: (optional) Ein Array der benutzerseitig eingebundenen Volumes, das in der YAML-Datei festgelegt wird. Weitere Informationen findest du unter Jobs in einem Container ausführen.sourceVolumePath
: (erforderlich) Der Quellpfad zum Volume, das im Docker-Container bereitgestellt wirdtargetVolumePath
: (erforderlich) Der Zielpfad zum Volume, das im Docker-Container bereitgestellt wirdreadOnly
: (erforderlich) Legt, ob das eingebundene Volume schreibgeschützt sein soll
systemMountVolumes
: (erforderlich) Ein Array der eingebundenen Volumes, die in den Container eingebunden werden sollen (mithilfe der gleichen Felder wie oben)sourceVolumePath
: (erforderlich) Der Quellpfad zum Volume, das im Docker-Container bereitgestellt wirdtargetVolumePath
: (erforderlich) Der Zielpfad zum Volume, das im Docker-Container bereitgestellt wirdreadOnly
: (erforderlich) Legt, ob das eingebundene Volume schreibgeschützt sein soll
registry
: (optional) Die Docker-Registrierungsanmeldeinformationen für eine private Containerregistrierungusername
: (optional) Der Benutzername des Registrierungskontospassword
: (optional) Das Kennwort für das RegistrierungskontoserverUrl
: (optional) Die Registrierungs-URL
portMappings
: (optional) Ein Schlüssel-Wert-Hash der source:target-Ports, die dem Container zugeordnet werden sollen
Beispieleingabe für das Image
Wenn du ein Docker-Image verwendest, kannst du den Imagenamen im Parameter "image":
angeben.
{ "command": "run_container_step", "responseFile": null, "state": { "network": "example_network_53269bd575972817b43f7733536b200c", "jobContainer": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480", "serviceContainers": { "redis": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105" } }, "args": { "image": "node:18", "dockerfile": null, "entryPointArgs": ["-f", "/dev/null"], "entryPoint": "tail", "workingDirectory": "/__w/octocat-test2/octocat-test2", "createOptions": "--cpus 1", "environmentVariables": { "NODE_ENV": "development" }, "prependPath": ["/foo/bar", "bar/foo"], "userMountVolumes": [ { "sourceVolumePath": "my_docker_volume", "targetVolumePath": "/volume_mount", "readOnly": false } ], "systemMountVolumes": [ { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work", "targetVolumePath": "/__w", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/externals", "targetVolumePath": "/__e", "readOnly": true }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp", "targetVolumePath": "/__w/_temp", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_actions", "targetVolumePath": "/__w/_actions", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_tool", "targetVolumePath": "/__w/_tool", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_home", "targetVolumePath": "/github/home", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_workflow", "targetVolumePath": "/github/workflow", "readOnly": false } ], "registry": null, "portMappings": { "80": "801" } } }
{
"command": "run_container_step",
"responseFile": null,
"state": {
"network": "example_network_53269bd575972817b43f7733536b200c",
"jobContainer": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480",
"serviceContainers": {
"redis": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105"
}
},
"args": {
"image": "node:18",
"dockerfile": null,
"entryPointArgs": ["-f", "/dev/null"],
"entryPoint": "tail",
"workingDirectory": "/__w/octocat-test2/octocat-test2",
"createOptions": "--cpus 1",
"environmentVariables": {
"NODE_ENV": "development"
},
"prependPath": ["/foo/bar", "bar/foo"],
"userMountVolumes": [
{
"sourceVolumePath": "my_docker_volume",
"targetVolumePath": "/volume_mount",
"readOnly": false
}
],
"systemMountVolumes": [
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work",
"targetVolumePath": "/__w",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/externals",
"targetVolumePath": "/__e",
"readOnly": true
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp",
"targetVolumePath": "/__w/_temp",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_actions",
"targetVolumePath": "/__w/_actions",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_tool",
"targetVolumePath": "/__w/_tool",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_home",
"targetVolumePath": "/github/home",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_workflow",
"targetVolumePath": "/github/workflow",
"readOnly": false
}
],
"registry": null,
"portMappings": { "80": "801" }
}
}
Beispieleingabe für ein Dockerfile
Wenn dein Container über ein Dockerfile definiert wird, veranschaulicht dieses Beispiel, wie der Pfad zu einem Dockerfile
in der Eingabe mithilfe des Parameters "dockerfile":
angegeben wird.
{ "command": "run_container_step", "responseFile": null, "state": { "network": "example_network_53269bd575972817b43f7733536b200c", "jobContainer": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480", "services": { "redis": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105" } }, "args": { "image": null, "dockerfile": "/__w/_actions/foo/dockerfile", "entryPointArgs": ["hello world"], "entryPoint": "echo", "workingDirectory": "/__w/octocat-test2/octocat-test2", "createOptions": "--cpus 1", "environmentVariables": { "NODE_ENV": "development" }, "prependPath": ["/foo/bar", "bar/foo"], "userMountVolumes": [ { "sourceVolumePath": "my_docker_volume", "targetVolumePath": "/volume_mount", "readOnly": false } ], "systemMountVolumes": [ { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work", "targetVolumePath": "/__w", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/externals", "targetVolumePath": "/__e", "readOnly": true }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp", "targetVolumePath": "/__w/_temp", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_actions", "targetVolumePath": "/__w/_actions", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_tool", "targetVolumePath": "/__w/_tool", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_home", "targetVolumePath": "/github/home", "readOnly": false }, { "sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_workflow", "targetVolumePath": "/github/workflow", "readOnly": false } ], "registry": null, "portMappings": { "80": "801" } } }
{
"command": "run_container_step",
"responseFile": null,
"state": {
"network": "example_network_53269bd575972817b43f7733536b200c",
"jobContainer": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480",
"services": {
"redis": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105"
}
},
"args": {
"image": null,
"dockerfile": "/__w/_actions/foo/dockerfile",
"entryPointArgs": ["hello world"],
"entryPoint": "echo",
"workingDirectory": "/__w/octocat-test2/octocat-test2",
"createOptions": "--cpus 1",
"environmentVariables": {
"NODE_ENV": "development"
},
"prependPath": ["/foo/bar", "bar/foo"],
"userMountVolumes": [
{
"sourceVolumePath": "my_docker_volume",
"targetVolumePath": "/volume_mount",
"readOnly": false
}
],
"systemMountVolumes": [
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work",
"targetVolumePath": "/__w",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/externals",
"targetVolumePath": "/__e",
"readOnly": true
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp",
"targetVolumePath": "/__w/_temp",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_actions",
"targetVolumePath": "/__w/_actions",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_tool",
"targetVolumePath": "/__w/_tool",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_home",
"targetVolumePath": "/github/home",
"readOnly": false
},
{
"sourceVolumePath": "/home/octocat/git/runner/_layout/_work/_temp/_github_workflow",
"targetVolumePath": "/github/workflow",
"readOnly": false
}
],
"registry": null,
"portMappings": { "80": "801" }
}
}
Beispielausgabe für run_container_step
Es wird keine Ausgabe für run_container_step
erwartet.
run_script_step
GitHub Actions geht davon aus, dass die folgenden Aufgaben erledigt werden:
- Das angegebene Skript im Auftragscontainer aufrufen und den Exitcode zurückgeben
- Alle Schrittprotokollausgaben für stdout und stderr streamen
Argumente für run_script_step
entryPointArgs
: (optional) Eine Liste, die die Einstiegspunktargumente enthältentryPoint
: (optional) Der zu verwendende Containereinstiegspunkt, wenn der Standardeinstiegspunkt des Images überschrieben werden sollprependPath
: (optional) Ein Array zusätzlicher Pfade, die der Variablen$PATH
vorangestellt werden sollenworkingDirectory
: (erforderlich) Eine Zeichenfolge, die den absoluten Pfad des Arbeitsverzeichnisses enthältenvironmentVariables
: (optional) Legt eine Zuordnung der Schlüsselumgebungsvariablen fest
Beispieleingabe für run_script_step
{ "command": "run_script_step", "responseFile": null, "state": { "network": "example_network_53269bd575972817b43f7733536b200c", "jobContainer": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480", "serviceContainers": { "redis": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105" } }, "args": { "entryPointArgs": ["-e", "/runner/temp/example.sh"], "entryPoint": "bash", "environmentVariables": { "NODE_ENV": "development" }, "prependPath": ["/foo/bar", "bar/foo"], "workingDirectory": "/__w/octocat-test2/octocat-test2" } }
{
"command": "run_script_step",
"responseFile": null,
"state": {
"network": "example_network_53269bd575972817b43f7733536b200c",
"jobContainer": "82e8219701fe096a35941d869cf3d71af1d943b5d8bdd718857fb87ac3042480",
"serviceContainers": {
"redis": "60972d9aa486605e66b0dad4abb678dc3d9116f536579e418176eedb8abb9105"
}
},
"args": {
"entryPointArgs": ["-e", "/runner/temp/example.sh"],
"entryPoint": "bash",
"environmentVariables": {
"NODE_ENV": "development"
},
"prependPath": ["/foo/bar", "bar/foo"],
"workingDirectory": "/__w/octocat-test2/octocat-test2"
}
}
Beispielausgabe für run_script_step
Es wird keine Ausgabe für run_script_step
erwartet.
Generieren des Anpassungsskripts
GitHub hat ein Beispielrepository erstellt, das veranschaulicht, wie Anpassungsskripts für Docker und Kubernetes generiert werden.
Note
Die resultierenden Skripts stehen für Testzwecke zur Verfügung. Du musst selbst entscheiden, ob sie für deine Anforderungen geeignet sind.
-
Klone das Repository actions/runner-container-hooks in deinen selbstgehosteten Runner.
-
Das Verzeichnis
examples/
enthält einige vorhandene Anpassungsbefehle, für die jeweils eine eigene JSON-Datei verfügbar ist. Du kannst dir diese Beispiele ansehen und sie als Ausgangsbasis für deine eigenen Anpassungsbefehle verwenden.prepare_job.json
run_script_step.json
run_container_step.json
-
Erstelle die npm-Pakete. Diese Befehle generieren die
index.js
-Dateien inpackages/docker/dist
undpackages/k8s/dist
.npm install && npm run bootstrap && npm run build-all
Wenn die resultierende index.js
-Datei von GitHub Actions ausgelöst wird, werden die in den JSON-Dateien definierten Anpassungsbefehle ausgeführt. Um index.js
auszulösen, muss die Datei zur Umgebungsvariablen ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER
hinzugefügt werden. Dies wird im nächsten Abschnitt beschrieben.
Auslösen des Anpassungsskripts
Das benutzerdefinierte Skript muss sich auf dem Runner befinden, sollte jedoch nicht im selbstgehosteten Runner-Anwendungsverzeichnis gespeichert werden (d. h. dem Verzeichnis, in das Sie die Runner-Software heruntergeladen und entpackt haben). Die Skripts werden im Sicherheitskontext des Dienstkontos ausgeführt, das den Runnerdienst ausführt.
Note
Das ausgelöste Skript wird synchron verarbeitet. Während es ausgeführt wird, wird die Auftragsausführung daher blockiert.
Das Skript wird automatisch ausgeführt, wenn der Runner über die folgenden Umgebungsvariablen verfügt, die einen absoluten Pfad zum Skript enthalten:
ACTIONS_RUNNER_CONTAINER_HOOKS
: Das in dieser Umgebungsvariablen definierte Skript wird ausgelöst, wenn einem Runner ein Auftrag zugewiesen wurde, aber bevor die Ausführung des Auftrags gestartet wird.
Um diese Umgebungsvariable festzulegen, kannst du sie entweder dem Betriebssystem oder einer Datei mit der Endung .env
hinzufügen, die sich im Anwendungsverzeichnis des selbstgehosteten Runners befindet. Der folgende Eintrag in der .env
-Datei führt beispielsweise dazu, dass der Runner automatisch das Skript unter /Users/octocat/runner/index.js
ausführt, bevor die containerbasierten Aufträge ausgeführt werden:
ACTIONS_RUNNER_CONTAINER_HOOKS=/Users/octocat/runner/index.js
Wenn du sicherstellen möchtest, dass dein Auftrag immer in einem Container ausgeführt wird und anschließend deine Containeranpassungen anwendet, kannst du die Variable ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER
für den selbstgehosteten Runner auf true
festlegen. Dadurch werden Aufträge nicht ausgeführt, die keinen Auftragscontainer angeben.
Problembehandlung
Keine Timeouteinstellung
Es ist derzeit keine Timeouteinstellung für das Skript verfügbar, das von ACTIONS_RUNNER_CONTAINER_HOOKS
ausgeführt wird. Du könntest daher in Erwägung ziehen, deinem Skript Timeoutverarbeitung hinzuzufügen.
Überprüfen des Workflow-Ausführungsprotokolls
Um zu bestätigen, dass deine Skripts ausgeführt werden, kannst du die Protokolle für diesen Auftrag überprüfen. Weitere Informationen zum Überprüfen der Protokolle findest du unter Verwenden von Workflowausführungsprotokollen.