Geteilte Docker-Build-and-Push-Pipeline anlegen #2
No files matched your search
@@ -1,18 +1,43 @@
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
inputs:
|
||||||
|
# Die vier Versionsangaben dienen ausschliesslich der Tag-Liste. Ohne Push
|
||||||
|
# gibt es nichts zu taggen, deshalb sind sie nicht mehr Pflicht — ein
|
||||||
|
# reiner Prueflauf muesste sonst Platzhalter erfinden. Bestehende Aufrufer
|
||||||
|
# uebergeben sie unveraendert weiter; required von true auf false zu
|
||||||
|
# senken ist rueckwaertskompatibel.
|
||||||
|
#
|
||||||
|
# Die Vorgabe ist 0 bzw. 0.0.0 und nicht etwa leer: docker/build-push-action
|
||||||
|
# gibt die Tag-Liste auch ohne Push als --tag an den Build weiter. Ein
|
||||||
|
# leerer Wert ergaebe "<registry>/<owner>/<name>:" und liesse den Build an
|
||||||
|
# "invalid reference format" scheitern. 0.0.0 ist ein gueltiger, sichtbar
|
||||||
|
# unechter Wert.
|
||||||
version-number:
|
version-number:
|
||||||
required: true
|
required: false
|
||||||
|
default: 0.0.0
|
||||||
type: string
|
type: string
|
||||||
version-number-major:
|
version-number-major:
|
||||||
required: true
|
required: false
|
||||||
|
default: '0'
|
||||||
type: string
|
type: string
|
||||||
version-number-minor:
|
version-number-minor:
|
||||||
required: true
|
required: false
|
||||||
|
default: '0'
|
||||||
type: string
|
type: string
|
||||||
version-number-patch:
|
version-number-patch:
|
||||||
required: true
|
required: false
|
||||||
|
default: '0'
|
||||||
type: string
|
type: string
|
||||||
|
push:
|
||||||
|
jklein marked this conversation as resolved
Outdated
|
|||||||
|
description: >-
|
||||||
|
Whether the built image is pushed. With push: false no credentials are
|
||||||
|
fetched from 1Password and no registry login happens, so the workflow
|
||||||
|
doubles as a build check. Caveat: the checkout token comes from the
|
||||||
|
same 1Password step, so without push the checkout falls back to the
|
||||||
|
job token — which cannot clone private submodules.
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
type: boolean
|
||||||
container-name:
|
container-name:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
@@ -22,14 +47,25 @@ on:
|
|||||||
docker-context:
|
docker-context:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
# image-owner und registry bilden zusammen das Praefix des Images. Dass
|
||||||
|
# das eine Pflicht ist und das andere nicht, ist Absicht: der Eigentuemer
|
||||||
|
# ist je Projekt verschieden und soll nie stillschweigend geraten werden —
|
||||||
|
# genau das war der Fehler des frueheren, fest verdrahteten "suer", unter
|
||||||
|
# dem die Images aller Projekte landeten. Die Registry ist dagegen
|
||||||
|
# praktisch immer dieselbe und darf deshalb eine Vorgabe haben.
|
||||||
image-owner:
|
image-owner:
|
||||||
description: >-
|
description: >-
|
||||||
Owner segment of the pushed image, i.e. the middle part of
|
Owner segment of the pushed image, i.e. the middle part of
|
||||||
|
jklein marked this conversation as resolved
jklein
commented
soll konfigurierbar sein mit default auf git.jk-dev.de soll konfigurierbar sein mit default auf git.jk-dev.de
|
|||||||
<registry>/<owner>/<container-name>. Used to be hardcoded to "suer",
|
<registry>/<owner>/<container-name>. Used to be hardcoded to "suer",
|
||||||
which sent every image of every calling project to the same account.
|
which sent every image of every calling project to the same account.
|
||||||
Kept as the default so existing callers stay unchanged.
|
Deliberately has no default: every caller states its owner explicitly.
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
registry:
|
||||||
|
description: >-
|
||||||
|
Registry the image is tagged for and, when pushing, logged in to.
|
||||||
required: false
|
required: false
|
||||||
default: suer
|
default: git.jk-dev.de
|
||||||
type: string
|
type: string
|
||||||
timeout-minutes:
|
timeout-minutes:
|
||||||
description: 'Hard limit for the build job. Without one a wedged build runs into the 6h default.'
|
description: 'Hard limit for the build job. Without one a wedged build runs into the 6h default.'
|
||||||
@@ -54,8 +90,12 @@ on:
|
|||||||
|
|
||||||
name: build and push Docker Image
|
name: build and push Docker Image
|
||||||
|
|
||||||
env:
|
# Einen env-Block auf Workflow-Ebene gibt es nicht mehr: sein einziger Eintrag
|
||||||
REGISTRY: git.jk-dev.de
|
# war REGISTRY, und der ist jetzt eine Eingabe. Dort haette er auch nicht
|
||||||
|
# bleiben koennen — env auf Workflow-Ebene wird ausgewertet, bevor es einen
|
||||||
|
# inputs-Kontext gibt. Registry und Eigentuemer werden deshalb an den beiden
|
||||||
|
# Stellen gelesen, an denen der Kontext sicher vorhanden ist: im
|
||||||
|
# Login-Schritt und in der Tag-Liste.
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-image:
|
build-image:
|
||||||
@@ -80,8 +120,24 @@ jobs:
|
|||||||
# (container.Authenticate antwortet mit 401). Beides deckt je ein eigener
|
# (container.Authenticate antwortet mit 401). Beides deckt je ein eigener
|
||||||
# Zugang ab, gepflegt in 1Password und hier zur Laufzeit ueber den
|
# Zugang ab, gepflegt in 1Password und hier zur Laufzeit ueber den
|
||||||
# Connect-Server im Cluster geholt; in Gitea liegt nur dessen Zugang.
|
# Connect-Server im Cluster geholt; in Gitea liegt nur dessen Zugang.
|
||||||
|
#
|
||||||
|
# Ohne Push werden gar keine Zugangsdaten geholt. Das hat eine Folge, die
|
||||||
|
# man kennen muss: der Checkout-Token faellt damit ebenfalls weg, der
|
||||||
|
# Checkout nutzt dann den Standard-Token des Jobs — und der kann die
|
||||||
|
# privaten Submodul-Repositories nicht klonen. Projekte MIT privaten
|
||||||
|
# Submodulen koennen den Modus push: false daher nicht nutzen; ihr Klon
|
||||||
|
# scheitert an "Repository not found". Fuer Projekte ohne Submodule ist
|
||||||
|
# der Modus unproblematisch.
|
||||||
|
#
|
||||||
|
# Zur Bedingung: ein boolescher workflow_call-Input kann je nach
|
||||||
|
# Schreibweise des Aufrufers als echter Boolean oder als String ankommen.
|
||||||
|
# `inputs.push` allein waere bei dem String 'false' wahr (nichtleere
|
||||||
|
# Strings sind truthy), `inputs.push == 'true'` waere beim echten Boolean
|
||||||
|
# true falsch (ein Vergleich ueber Typgrenzen laeuft ueber Zahlen, 'true'
|
||||||
|
# wird dabei zu NaN). Die Kombination aus beidem deckt alle vier Faelle ab.
|
||||||
- name: Zugangsdaten aus 1Password laden
|
- name: Zugangsdaten aus 1Password laden
|
||||||
id: op-secrets
|
id: op-secrets
|
||||||
|
if: ${{ inputs.push && inputs.push != 'false' }}
|
||||||
uses: 1password/load-secrets-action@v2
|
uses: 1password/load-secrets-action@v2
|
||||||
with:
|
with:
|
||||||
# Die Werte sollen nur als Step-Outputs entstehen und nicht in die
|
# Die Werte sollen nur als Step-Outputs entstehen und nicht in die
|
||||||
@@ -104,7 +160,15 @@ jobs:
|
|||||||
submodules: true
|
submodules: true
|
||||||
# Die Action legt je Referenz einen Output an, benannt wie die
|
# Die Action legt je Referenz einen Output an, benannt wie die
|
||||||
# Umgebungsvariable, in der die op://-Referenz stand.
|
# Umgebungsvariable, in der die op://-Referenz stand.
|
||||||
token: ${{ steps.op-secrets.outputs.CHECKOUT_TOKEN }}
|
#
|
||||||
|
# Ist der 1Password-Schritt uebersprungen (push: false), sind seine
|
||||||
|
# Outputs leer. Ein leer uebergebenes token wuerde die Vorgabe der
|
||||||
|
# Action (github.token) ueberschreiben und den Checkout ohne jeden
|
||||||
|
# Zugang laufen lassen — er scheiterte schon am eigenen Repository.
|
||||||
|
# Der Fallback macht daraus den regulaeren Job-Token. Der genuegt
|
||||||
|
# fuer das ausfuehrende Repository, nicht fuer private Submodule
|
||||||
|
# (siehe Kommentar am 1Password-Schritt).
|
||||||
|
token: ${{ steps.op-secrets.outputs.CHECKOUT_TOKEN || github.token }}
|
||||||
# Schlaegt der Buildx-Start fehl, ist die erste Frage immer, welcher
|
# Schlaegt der Buildx-Start fehl, ist die erste Frage immer, welcher
|
||||||
# Socket im Job-Container ueberhaupt ankommt. Der Schritt beantwortet sie,
|
# Socket im Job-Container ueberhaupt ankommt. Der Schritt beantwortet sie,
|
||||||
# ohne den Job scheitern zu lassen.
|
# ohne den Job scheitern zu lassen.
|
||||||
@@ -118,10 +182,15 @@ jobs:
|
|||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: docker/setup-buildx-action@master
|
uses: docker/setup-buildx-action@master
|
||||||
|
# Ohne Push gibt es nichts anzumelden — und die Zugangsdaten waeren
|
||||||
|
# ohnehin leer, weil der 1Password-Schritt uebersprungen wurde. Ein
|
||||||
|
# Login-Versuch mit leerem Benutzer scheiterte mit einer nichtssagenden
|
||||||
|
# Meldung; dieselbe Bedingung wie oben verhindert das.
|
||||||
- name: Authenticate To Registry
|
- name: Authenticate To Registry
|
||||||
|
if: ${{ inputs.push && inputs.push != 'false' }}
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ inputs.registry }}
|
||||||
username: ${{ steps.op-secrets.outputs.REGISTRY_USER }}
|
username: ${{ steps.op-secrets.outputs.REGISTRY_USER }}
|
||||||
password: ${{ steps.op-secrets.outputs.REGISTRY_TOKEN }}
|
password: ${{ steps.op-secrets.outputs.REGISTRY_TOKEN }}
|
||||||
- name: Build
|
- name: Build
|
||||||
@@ -132,15 +201,22 @@ jobs:
|
|||||||
file: ${{ inputs.dockerfile }}
|
file: ${{ inputs.dockerfile }}
|
||||||
platforms: ${{ inputs.platforms }}
|
platforms: ${{ inputs.platforms }}
|
||||||
build-args: ${{ inputs.build-args }}
|
build-args: ${{ inputs.build-args }}
|
||||||
push: true
|
# Dieselbe Normalisierung wie bei den if:-Bedingungen. Das Ergebnis
|
||||||
|
# ist immer genau "true" oder "false" — die Action liest den Wert als
|
||||||
|
# Boolean und akzeptiert nichts dazwischen.
|
||||||
|
push: ${{ inputs.push && inputs.push != 'false' }}
|
||||||
# Der Eigentümer stand frueher als IMAGE_OWNER im env-Block des
|
# Der Eigentümer stand frueher als IMAGE_OWNER im env-Block des
|
||||||
# Workflows. Dort kann er nicht bleiben: env auf Workflow-Ebene wird
|
# Workflows. Dort kann er nicht bleiben: env auf Workflow-Ebene wird
|
||||||
# ausgewertet, bevor es einen inputs-Kontext gibt. Der Wert wird
|
# ausgewertet, bevor es einen inputs-Kontext gibt. Der Wert wird
|
||||||
# deshalb hier unmittelbar aus inputs gelesen — an dieser Stelle ist
|
# deshalb hier unmittelbar aus inputs gelesen — an dieser Stelle ist
|
||||||
# der Kontext sicher vorhanden, anders als in jedem env-Block.
|
# der Kontext sicher vorhanden, anders als in jedem env-Block.
|
||||||
|
#
|
||||||
|
# Ohne Push bleibt die Liste rein lokal: die Action gibt sie als --tag
|
||||||
|
# an den Build weiter, veroeffentlicht aber nichts. Die Versionen
|
||||||
|
# tragen dann ihre Vorgabe 0.0.0.
|
||||||
tags: |
|
tags: |
|
||||||
${{ env.REGISTRY }}/${{ inputs.image-owner }}/${{ inputs.container-name }}:latest
|
${{ inputs.registry }}/${{ inputs.image-owner }}/${{ inputs.container-name }}:latest
|
||||||
${{ env.REGISTRY }}/${{ inputs.image-owner }}/${{ inputs.container-name }}:${{ inputs.version-number }}
|
${{ inputs.registry }}/${{ inputs.image-owner }}/${{ inputs.container-name }}:${{ inputs.version-number }}
|
||||||
${{ env.REGISTRY }}/${{ inputs.image-owner }}/${{ inputs.container-name }}:${{ inputs.version-number-major }}
|
${{ inputs.registry }}/${{ inputs.image-owner }}/${{ inputs.container-name }}:${{ inputs.version-number-major }}
|
||||||
${{ env.REGISTRY }}/${{ inputs.image-owner }}/${{ inputs.container-name }}:${{ inputs.version-number-major }}.${{ inputs.version-number-minor }}
|
${{ inputs.registry }}/${{ inputs.image-owner }}/${{ inputs.container-name }}:${{ inputs.version-number-major }}.${{ inputs.version-number-minor }}
|
||||||
${{ env.REGISTRY }}/${{ inputs.image-owner }}/${{ inputs.container-name }}:${{ inputs.version-number-major }}.${{ inputs.version-number-minor }}.${{ inputs.version-number-patch }}
|
${{ inputs.registry }}/${{ inputs.image-owner }}/${{ inputs.container-name }}:${{ inputs.version-number-major }}.${{ inputs.version-number-minor }}.${{ inputs.version-number-patch }}
|
||||||
@@ -9,38 +9,55 @@ hier werden nicht selbst ausgelöst, sondern von anderen Repositories über
|
|||||||
### `.gitea/workflows/docker-build-push.yml`
|
### `.gitea/workflows/docker-build-push.yml`
|
||||||
|
|
||||||
Baut ein Docker-Image und schiebt es als Multi-Arch-Manifest
|
Baut ein Docker-Image und schiebt es als Multi-Arch-Manifest
|
||||||
(`linux/amd64,linux/arm64`) in die Registry `git.jk-dev.de`. Läuft auf einem
|
(`linux/amd64,linux/arm64`) in eine Registry, vorgabegemäß `git.jk-dev.de`.
|
||||||
Runner mit dem Label `ubuntu-docker`.
|
Läuft auf einem Runner mit dem Label `ubuntu-docker`.
|
||||||
|
|
||||||
Gepusht wird unter fünf Tags:
|
Gepusht wird unter fünf Tags:
|
||||||
|
|
||||||
```
|
```
|
||||||
git.jk-dev.de/<image-owner>/<container-name>:latest
|
<registry>/<image-owner>/<container-name>:latest
|
||||||
git.jk-dev.de/<image-owner>/<container-name>:<version-number>
|
<registry>/<image-owner>/<container-name>:<version-number>
|
||||||
git.jk-dev.de/<image-owner>/<container-name>:<major>
|
<registry>/<image-owner>/<container-name>:<major>
|
||||||
git.jk-dev.de/<image-owner>/<container-name>:<major>.<minor>
|
<registry>/<image-owner>/<container-name>:<major>.<minor>
|
||||||
git.jk-dev.de/<image-owner>/<container-name>:<major>.<minor>.<patch>
|
<registry>/<image-owner>/<container-name>:<major>.<minor>.<patch>
|
||||||
```
|
```
|
||||||
|
|
||||||
Der Checkout holt Submodule mit; die Zugangsdaten dafür und für die Registry
|
Der Checkout holt Submodule mit; die Zugangsdaten dafür und für die Registry
|
||||||
kommen zur Laufzeit aus 1Password Connect.
|
kommen zur Laufzeit aus 1Password Connect.
|
||||||
|
|
||||||
|
Mit `push: false` entfällt der Push — der Baustein baut dann nur. Damit nutzt
|
||||||
|
die CI eines Projekts dieselbe Bau-Logik wie das Deployment, statt sie zu
|
||||||
|
duplizieren. Siehe [Prüfmodus](#prüfmodus-ohne-push).
|
||||||
|
|
||||||
#### Eingaben
|
#### Eingaben
|
||||||
|
|
||||||
| Eingabe | Pflicht | Vorgabe | Bedeutung |
|
| Eingabe | Pflicht | Vorgabe | Bedeutung |
|
||||||
| ---------------------- | ------- | ------------------------- | --------- |
|
| ---------------------- | ------- | ------------------------- | --------- |
|
||||||
| `version-number` | ja | — | Vollständige Version, wird als Tag gesetzt |
|
|
||||||
| `version-number-major` | ja | — | Major-Anteil für die mitwandernden Tags |
|
|
||||||
| `version-number-minor` | ja | — | Minor-Anteil |
|
|
||||||
| `version-number-patch` | ja | — | Patch-Anteil |
|
|
||||||
| `container-name` | ja | — | Name des Images |
|
| `container-name` | ja | — | Name des Images |
|
||||||
| `dockerfile` | ja | — | Pfad zum Dockerfile |
|
| `dockerfile` | ja | — | Pfad zum Dockerfile |
|
||||||
| `docker-context` | ja | — | Build-Kontext |
|
| `docker-context` | ja | — | Build-Kontext |
|
||||||
| `image-owner` | nein | `suer` | Eigentümer-Segment des Images, also der mittlere Teil von `<registry>/<owner>/<name>` |
|
| `image-owner` | ja | — | Eigentümer-Segment des Images, also der mittlere Teil von `<registry>/<owner>/<name>` |
|
||||||
|
| `push` | nein | `true` | Ob das Image gepusht wird. Bei `false` werden keine Zugangsdaten aus 1Password geholt und es findet kein Registry-Login statt — siehe [Prüfmodus](#prüfmodus-ohne-push) |
|
||||||
|
| `registry` | nein | `git.jk-dev.de` | Registry, für die getaggt und — beim Push — bei der angemeldet wird |
|
||||||
|
| `version-number` | nein | `0.0.0` | Vollständige Version, wird als Tag gesetzt |
|
||||||
|
| `version-number-major` | nein | `0` | Major-Anteil für die mitwandernden Tags |
|
||||||
|
| `version-number-minor` | nein | `0` | Minor-Anteil |
|
||||||
|
| `version-number-patch` | nein | `0` | Patch-Anteil |
|
||||||
| `timeout-minutes` | nein | `45` | Harte Grenze für den Build-Job |
|
| `timeout-minutes` | nein | `45` | Harte Grenze für den Build-Job |
|
||||||
| `platforms` | nein | `linux/amd64,linux/arm64` | Zielplattformen der Manifest-Liste |
|
| `platforms` | nein | `linux/amd64,linux/arm64` | Zielplattformen der Manifest-Liste |
|
||||||
| `build-args` | nein | — | Zusätzliche Build-Argumente, ein `NAME=wert` je Zeile |
|
| `build-args` | nein | — | Zusätzliche Build-Argumente, ein `NAME=wert` je Zeile |
|
||||||
|
|
||||||
|
Dass `image-owner` Pflicht ist und `registry` nicht, ist Absicht: Der Eigentümer
|
||||||
|
ist je Projekt verschieden und soll nie stillschweigend geraten werden — genau
|
||||||
|
das war der Fehler des früher fest verdrahteten `suer`, unter dem die Images
|
||||||
|
aller Projekte landeten. Die Registry ist dagegen praktisch immer dieselbe.
|
||||||
|
|
||||||
|
Die vier Versionsangaben dienen ausschließlich der Tag-Liste. Sie sind keine
|
||||||
|
Pflicht mehr, damit ein Prüflauf keine Platzhalter erfinden muss; wer pusht,
|
||||||
|
übergibt sie wie bisher. Ihre Vorgabe ist bewusst `0.0.0` und nicht leer — die
|
||||||
|
Tag-Liste wird auch ohne Push gebildet, und ein leerer Wert ergäbe das ungültige
|
||||||
|
`…/<name>:`.
|
||||||
|
|
||||||
#### Aufrufbeispiel
|
#### Aufrufbeispiel
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -62,12 +79,45 @@ jobs:
|
|||||||
`secrets: inherit` ist notwendig — der Workflow braucht `OP_CONNECT_TOKEN` aus
|
`secrets: inherit` ist notwendig — der Workflow braucht `OP_CONNECT_TOKEN` aus
|
||||||
dem aufrufenden Repository.
|
dem aufrufenden Repository.
|
||||||
|
|
||||||
|
#### Prüfmodus ohne Push
|
||||||
|
|
||||||
|
Mit `push: false` baut der Baustein nur und veröffentlicht nichts. Es werden
|
||||||
|
dann keine Zugangsdaten aus 1Password geholt und es findet kein Registry-Login
|
||||||
|
statt. Die CI eines Projekts nutzt damit dieselbe Bau-Logik wie das Deployment,
|
||||||
|
statt sie zu duplizieren.
|
||||||
|
|
||||||
|
Weder Secrets noch Versionsangaben sind dafür nötig:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
jobs:
|
||||||
|
build-check:
|
||||||
|
uses: workflow-util/pipelines/.gitea/workflows/docker-build-push.yml@v1
|
||||||
|
with:
|
||||||
|
container-name: bk-dev-website
|
||||||
|
dockerfile: ./Dockerfile
|
||||||
|
docker-context: .
|
||||||
|
image-owner: bekemeyer-klein
|
||||||
|
push: false
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Private Submodule funktionieren in diesem Modus nicht.**
|
||||||
|
> Der Checkout-Token stammt aus demselben 1Password-Schritt, der ohne Push
|
||||||
|
> übersprungen wird. Der Checkout fällt deshalb auf den Standard-Token des Jobs
|
||||||
|
> zurück. Der genügt für das ausführende Repository, nicht aber für die
|
||||||
|
> Submodule in eigenen privaten Repositories — deren Klon scheitert mit
|
||||||
|
> `Repository not found`. Projekte **mit** privaten Submodulen können
|
||||||
|
> `push: false` daher nicht verwenden; für Projekte ohne Submodule ist der
|
||||||
|
> Modus unproblematisch.
|
||||||
|
|
||||||
|
`secrets: inherit` kann hier entfallen. Es zu belassen schadet nicht — der
|
||||||
|
Workflow greift ohne Push auf kein Secret zu.
|
||||||
|
|
||||||
#### Voraussetzungen im aufrufenden Repository
|
#### Voraussetzungen im aufrufenden Repository
|
||||||
|
|
||||||
| Name | Art | Zweck |
|
| Name | Art | Zweck |
|
||||||
| ------------------ | -------- | ----- |
|
| ------------------ | -------- | ----- |
|
||||||
| `OP_CONNECT_HOST` | Variable | Adresse des 1Password-Connect-Servers im Cluster |
|
| `OP_CONNECT_HOST` | Variable | Adresse des 1Password-Connect-Servers im Cluster. Nur beim Push nötig |
|
||||||
| `OP_CONNECT_TOKEN` | Secret | Zugang zu diesem Connect-Server |
|
| `OP_CONNECT_TOKEN` | Secret | Zugang zu diesem Connect-Server. Nur beim Push nötig |
|
||||||
| `DOCKER_HOST` | Variable | Nur nötig, wenn der Runner-Daemon rootless läuft und sein Socket nicht unter `/var/run/docker.sock` liegt (dann z. B. `unix:///run/user/1000/docker.sock`). Ist die Variable nicht gesetzt, nutzt Docker seinen Default. |
|
| `DOCKER_HOST` | Variable | Nur nötig, wenn der Runner-Daemon rootless läuft und sein Socket nicht unter `/var/run/docker.sock` liegt (dann z. B. `unix:///run/user/1000/docker.sock`). Ist die Variable nicht gesetzt, nutzt Docker seinen Default. |
|
||||||
|
|
||||||
Die eigentlichen Zugänge für Checkout und Registry liegen in 1Password
|
Die eigentlichen Zugänge für Checkout und Registry liegen in 1Password
|
||||||
|
|||||||
Reference in new issue
Block a user
ist required, kein default