fix deploy: use crane for daemonless push (resolves gitea DNS)
Some checks failed
CI / lint-test (push) Successful in 1m28s
Deploy / build (push) Successful in 7m16s
Deploy / scan (push) Failing after 31s
Deploy / report-vulns (push) Has been skipped

docker push goes through the host daemon which can't resolve
'gitea' (not on any Docker network). crane pushes directly
from the job container's network stack — resolves via Docker
DNS, pushes over HTTP with --insecure.

Flow: docker build → docker save → crane push
- Build via host socket (works)
- Save to tarball (local filesystem)
- crane push tarball to gitea:3000 (job container DNS)

Reverted DinD-rootless (needs privileged for user namespaces).
Back to socket-mounted runner with daemonless push.
This commit is contained in:
kert
2026-03-23 22:58:53 -04:00
parent 392456a3b0
commit df356f417b
7 changed files with 109 additions and 69 deletions

View File

@@ -16,51 +16,61 @@ jobs:
- name: Log in to container registry - name: Install crane
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login gitea:3000 -u "${{ secrets.REGISTRY_USER }}" --password-stdin run: curl -sL https://github.com/google/go-containerregistry/releases/latest/download/go-containerregistry_Linux_x86_64.tar.gz | tar xz -C /usr/local/bin crane
- name: Log in to registry
run: crane auth login gitea:3000 -u "${{ secrets.REGISTRY_USER }}" -p "${{ secrets.REGISTRY_TOKEN }}"
env:
CRANE_INSECURE: "true"
- name: Compute short SHA - name: Compute short SHA
run: echo "SHORT_SHA=$(echo $GITHUB_SHA | head -c 8)" >> "$GITHUB_ENV" run: echo "SHORT_SHA=$(echo $GITHUB_SHA | head -c 8)" >> "$GITHUB_ENV"
- name: Build notebooks - name: Build notebooks
run: docker build -f notebooks/Dockerfile -t gitea:3000/homelab/stack/notebooks:${{ env.SHORT_SHA }} -t gitea:3000/homelab/stack/notebooks:latest notebooks/ run: docker build -f notebooks/Dockerfile -t local/notebooks:build notebooks/
- name: Push notebooks - name: Push notebooks
run: | run: |
docker push gitea:3000/homelab/stack/notebooks:${{ env.SHORT_SHA }} docker save local/notebooks:build -o /tmp/notebooks.tar
docker push gitea:3000/homelab/stack/notebooks:latest crane push /tmp/notebooks.tar gitea:3000/homelab/stack/notebooks:${{ env.SHORT_SHA }} --insecure
crane push /tmp/notebooks.tar gitea:3000/homelab/stack/notebooks:latest --insecure
- name: Build zotero - name: Build zotero
run: docker build -f zotero/Dockerfile -t gitea:3000/homelab/stack/zotero:${{ env.SHORT_SHA }} -t gitea:3000/homelab/stack/zotero:latest zotero/ run: docker build -f zotero/Dockerfile -t local/zotero:build zotero/
- name: Push zotero - name: Push zotero
run: | run: |
docker push gitea:3000/homelab/stack/zotero:${{ env.SHORT_SHA }} docker save local/zotero:build -o /tmp/zotero.tar
docker push gitea:3000/homelab/stack/zotero:latest crane push /tmp/zotero.tar gitea:3000/homelab/stack/zotero:${{ env.SHORT_SHA }} --insecure
crane push /tmp/zotero.tar gitea:3000/homelab/stack/zotero:latest --insecure
- name: Build docs - name: Build docs
run: docker build -f docs/Dockerfile -t gitea:3000/homelab/stack/docs:${{ env.SHORT_SHA }} -t gitea:3000/homelab/stack/docs:latest . run: docker build -f docs/Dockerfile -t local/docs:build .
- name: Push docs - name: Push docs
run: | run: |
docker push gitea:3000/homelab/stack/docs:${{ env.SHORT_SHA }} docker save local/docs:build -o /tmp/docs.tar
docker push gitea:3000/homelab/stack/docs:latest crane push /tmp/docs.tar gitea:3000/homelab/stack/docs:${{ env.SHORT_SHA }} --insecure
crane push /tmp/docs.tar gitea:3000/homelab/stack/docs:latest --insecure
- name: Build api - name: Build api
run: docker build -f api/Dockerfile -t gitea:3000/homelab/stack/api:${{ env.SHORT_SHA }} -t gitea:3000/homelab/stack/api:latest . run: docker build -f api/Dockerfile -t local/api:build .
- name: Push api - name: Push api
run: | run: |
docker push gitea:3000/homelab/stack/api:${{ env.SHORT_SHA }} docker save local/api:build -o /tmp/api.tar
docker push gitea:3000/homelab/stack/api:latest crane push /tmp/api.tar gitea:3000/homelab/stack/api:${{ env.SHORT_SHA }} --insecure
crane push /tmp/api.tar gitea:3000/homelab/stack/api:latest --insecure
- name: Build mc - name: Build mc
run: docker build -f rustfs/Dockerfile.mc -t gitea:3000/homelab/stack/mc:${{ env.SHORT_SHA }} -t gitea:3000/homelab/stack/mc:latest rustfs/ run: docker build -f rustfs/Dockerfile.mc -t local/mc:build rustfs/
- name: Push mc - name: Push mc
run: | run: |
docker push gitea:3000/homelab/stack/mc:${{ env.SHORT_SHA }} docker save local/mc:build -o /tmp/mc.tar
docker push gitea:3000/homelab/stack/mc:latest crane push /tmp/mc.tar gitea:3000/homelab/stack/mc:${{ env.SHORT_SHA }} --insecure
crane push /tmp/mc.tar gitea:3000/homelab/stack/mc:latest --insecure
scan: scan:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -17,48 +17,58 @@ jobs:
- name: Log in to container registry - name: Install crane
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login gitea:3000 -u "${{ secrets.REGISTRY_USER }}" --password-stdin run: curl -sL https://github.com/google/go-containerregistry/releases/latest/download/go-containerregistry_Linux_x86_64.tar.gz | tar xz -C /usr/local/bin crane
- name: Log in to registry
run: crane auth login gitea:3000 -u "${{ secrets.REGISTRY_USER }}" -p "${{ secrets.REGISTRY_TOKEN }}"
env:
CRANE_INSECURE: "true"
- name: Build notebooks - name: Build notebooks
run: docker build --no-cache -f notebooks/Dockerfile -t gitea:3000/homelab/stack/notebooks:hardened -t gitea:3000/homelab/stack/notebooks:latest notebooks/ run: docker build --no-cache -f notebooks/Dockerfile -t local/notebooks:build notebooks/
- name: Push notebooks - name: Push notebooks
run: | run: |
docker push gitea:3000/homelab/stack/notebooks:hardened docker save local/notebooks:build -o /tmp/notebooks.tar
docker push gitea:3000/homelab/stack/notebooks:latest crane push /tmp/notebooks.tar gitea:3000/homelab/stack/notebooks:hardened --insecure
crane push /tmp/notebooks.tar gitea:3000/homelab/stack/notebooks:latest --insecure
- name: Build zotero - name: Build zotero
run: docker build --no-cache -f zotero/Dockerfile -t gitea:3000/homelab/stack/zotero:hardened -t gitea:3000/homelab/stack/zotero:latest zotero/ run: docker build --no-cache -f zotero/Dockerfile -t local/zotero:build zotero/
- name: Push zotero - name: Push zotero
run: | run: |
docker push gitea:3000/homelab/stack/zotero:hardened docker save local/zotero:build -o /tmp/zotero.tar
docker push gitea:3000/homelab/stack/zotero:latest crane push /tmp/zotero.tar gitea:3000/homelab/stack/zotero:hardened --insecure
crane push /tmp/zotero.tar gitea:3000/homelab/stack/zotero:latest --insecure
- name: Build docs - name: Build docs
run: docker build --no-cache -f docs/Dockerfile -t gitea:3000/homelab/stack/docs:hardened -t gitea:3000/homelab/stack/docs:latest . run: docker build --no-cache -f docs/Dockerfile -t local/docs:build .
- name: Push docs - name: Push docs
run: | run: |
docker push gitea:3000/homelab/stack/docs:hardened docker save local/docs:build -o /tmp/docs.tar
docker push gitea:3000/homelab/stack/docs:latest crane push /tmp/docs.tar gitea:3000/homelab/stack/docs:hardened --insecure
crane push /tmp/docs.tar gitea:3000/homelab/stack/docs:latest --insecure
- name: Build api - name: Build api
run: docker build --no-cache -f api/Dockerfile -t gitea:3000/homelab/stack/api:hardened -t gitea:3000/homelab/stack/api:latest . run: docker build --no-cache -f api/Dockerfile -t local/api:build .
- name: Push api - name: Push api
run: | run: |
docker push gitea:3000/homelab/stack/api:hardened docker save local/api:build -o /tmp/api.tar
docker push gitea:3000/homelab/stack/api:latest crane push /tmp/api.tar gitea:3000/homelab/stack/api:hardened --insecure
crane push /tmp/api.tar gitea:3000/homelab/stack/api:latest --insecure
- name: Build mc - name: Build mc
run: docker build --no-cache -f rustfs/Dockerfile.mc -t gitea:3000/homelab/stack/mc:hardened -t gitea:3000/homelab/stack/mc:latest rustfs/ run: docker build --no-cache -f rustfs/Dockerfile.mc -t local/mc:build rustfs/
- name: Push mc - name: Push mc
run: | run: |
docker push gitea:3000/homelab/stack/mc:hardened docker save local/mc:build -o /tmp/mc.tar
docker push gitea:3000/homelab/stack/mc:latest crane push /tmp/mc.tar gitea:3000/homelab/stack/mc:hardened --insecure
crane push /tmp/mc.tar gitea:3000/homelab/stack/mc:latest --insecure
scan: scan:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -38,7 +38,7 @@ jobs:
- name: Build notebooks - name: Build notebooks
run: docker build -f notebooks/Dockerfile -t ci-test-notebooks notebooks/ run: docker build -f notebooks/Dockerfile -t local/notebooks:build notebooks/
zotero: zotero:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -54,7 +54,7 @@ jobs:
- name: Build zotero - name: Build zotero
run: docker build -f zotero/Dockerfile -t ci-test-zotero zotero/ run: docker build -f zotero/Dockerfile -t local/zotero:build zotero/
docs: docs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -70,7 +70,7 @@ jobs:
- name: Build docs - name: Build docs
run: docker build -f docs/Dockerfile -t ci-test-docs . run: docker build -f docs/Dockerfile -t local/docs:build .
api: api:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -86,7 +86,7 @@ jobs:
- name: Build api - name: Build api
run: docker build -f api/Dockerfile -t ci-test-api . run: docker build -f api/Dockerfile -t local/api:build .
mc: mc:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -102,4 +102,4 @@ jobs:
- name: Build mc - name: Build mc
run: docker build -f rustfs/Dockerfile.mc -t ci-test-mc rustfs/ run: docker build -f rustfs/Dockerfile.mc -t local/mc:build rustfs/

View File

@@ -15,51 +15,61 @@ jobs:
- name: Log in to container registry - name: Install crane
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login gitea:3000 -u "${{ secrets.REGISTRY_USER }}" --password-stdin run: curl -sL https://github.com/google/go-containerregistry/releases/latest/download/go-containerregistry_Linux_x86_64.tar.gz | tar xz -C /usr/local/bin crane
- name: Log in to registry
run: crane auth login gitea:3000 -u "${{ secrets.REGISTRY_USER }}" -p "${{ secrets.REGISTRY_TOKEN }}"
env:
CRANE_INSECURE: "true"
- name: Compute short SHA - name: Compute short SHA
run: echo "SHORT_SHA=$(echo $GITHUB_SHA | head -c 8)" >> "$GITHUB_ENV" run: echo "SHORT_SHA=$(echo $GITHUB_SHA | head -c 8)" >> "$GITHUB_ENV"
- name: Build notebooks - name: Build notebooks
run: docker build -f notebooks/Dockerfile -t gitea:3000/homelab/stack/notebooks:${{ env.SHORT_SHA }} -t gitea:3000/homelab/stack/notebooks:latest notebooks/ run: docker build -f notebooks/Dockerfile -t local/notebooks:build notebooks/
- name: Push notebooks - name: Push notebooks
run: | run: |
docker push gitea:3000/homelab/stack/notebooks:${{ env.SHORT_SHA }} docker save local/notebooks:build -o /tmp/notebooks.tar
docker push gitea:3000/homelab/stack/notebooks:latest crane push /tmp/notebooks.tar gitea:3000/homelab/stack/notebooks:${{ env.SHORT_SHA }} --insecure
crane push /tmp/notebooks.tar gitea:3000/homelab/stack/notebooks:latest --insecure
- name: Build zotero - name: Build zotero
run: docker build -f zotero/Dockerfile -t gitea:3000/homelab/stack/zotero:${{ env.SHORT_SHA }} -t gitea:3000/homelab/stack/zotero:latest zotero/ run: docker build -f zotero/Dockerfile -t local/zotero:build zotero/
- name: Push zotero - name: Push zotero
run: | run: |
docker push gitea:3000/homelab/stack/zotero:${{ env.SHORT_SHA }} docker save local/zotero:build -o /tmp/zotero.tar
docker push gitea:3000/homelab/stack/zotero:latest crane push /tmp/zotero.tar gitea:3000/homelab/stack/zotero:${{ env.SHORT_SHA }} --insecure
crane push /tmp/zotero.tar gitea:3000/homelab/stack/zotero:latest --insecure
- name: Build docs - name: Build docs
run: docker build -f docs/Dockerfile -t gitea:3000/homelab/stack/docs:${{ env.SHORT_SHA }} -t gitea:3000/homelab/stack/docs:latest . run: docker build -f docs/Dockerfile -t local/docs:build .
- name: Push docs - name: Push docs
run: | run: |
docker push gitea:3000/homelab/stack/docs:${{ env.SHORT_SHA }} docker save local/docs:build -o /tmp/docs.tar
docker push gitea:3000/homelab/stack/docs:latest crane push /tmp/docs.tar gitea:3000/homelab/stack/docs:${{ env.SHORT_SHA }} --insecure
crane push /tmp/docs.tar gitea:3000/homelab/stack/docs:latest --insecure
- name: Build api - name: Build api
run: docker build -f api/Dockerfile -t gitea:3000/homelab/stack/api:${{ env.SHORT_SHA }} -t gitea:3000/homelab/stack/api:latest . run: docker build -f api/Dockerfile -t local/api:build .
- name: Push api - name: Push api
run: | run: |
docker push gitea:3000/homelab/stack/api:${{ env.SHORT_SHA }} docker save local/api:build -o /tmp/api.tar
docker push gitea:3000/homelab/stack/api:latest crane push /tmp/api.tar gitea:3000/homelab/stack/api:${{ env.SHORT_SHA }} --insecure
crane push /tmp/api.tar gitea:3000/homelab/stack/api:latest --insecure
- name: Build mc - name: Build mc
run: docker build -f rustfs/Dockerfile.mc -t gitea:3000/homelab/stack/mc:${{ env.SHORT_SHA }} -t gitea:3000/homelab/stack/mc:latest rustfs/ run: docker build -f rustfs/Dockerfile.mc -t local/mc:build rustfs/
- name: Push mc - name: Push mc
run: | run: |
docker push gitea:3000/homelab/stack/mc:${{ env.SHORT_SHA }} docker save local/mc:build -o /tmp/mc.tar
docker push gitea:3000/homelab/stack/mc:latest crane push /tmp/mc.tar gitea:3000/homelab/stack/mc:${{ env.SHORT_SHA }} --insecure
crane push /tmp/mc.tar gitea:3000/homelab/stack/mc:latest --insecure
scan: scan:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -11,11 +11,7 @@ runner:
container: container:
network: "ci" network: "ci"
privileged: false privileged: false
# "-" disables auto-mount (which fails with rootless Docker because
# it tries to mount /var/run/docker.sock from the HOST, but the host
# socket is at /run/user/1000/docker.sock)
docker_host: "-" docker_host: "-"
# Mount the actual HOST socket path into job containers options: "-v /run/user/1000/docker.sock:/var/run/docker.sock"
options: "-v /run/user/1000/docker.sock:/var/run/docker.sock --dns 127.0.0.11"
valid_volumes: valid_volumes:
- /run/user/1000/** - /run/user/1000/**

View File

@@ -221,7 +221,6 @@ services:
networks: networks:
- ci - ci
- storage - storage
privileged: true
environment: environment:
- GITEA_INSTANCE_URL=http://gitea:3000 - GITEA_INSTANCE_URL=http://gitea:3000
- GITEA_RUNNER_REGISTRATION_TOKEN=${ACT_RUNNER_TOKEN} - GITEA_RUNNER_REGISTRATION_TOKEN=${ACT_RUNNER_TOKEN}
@@ -234,6 +233,8 @@ services:
- ./act-runner/config.yaml:/config.yaml:ro - ./act-runner/config.yaml:/config.yaml:ro
depends_on: depends_on:
- gitea - gitea
security_opt:
- no-new-privileges:true
restart: unless-stopped restart: unless-stopped
notebooks: notebooks:

View File

@@ -49,20 +49,28 @@ def _build_push_step(
no_cache: bool = False, no_cache: bool = False,
load_only: bool = False, load_only: bool = False,
) -> str: ) -> str:
"""Plain docker build + push — avoids GitHub Action TLS/compat issues.""" """docker build (via socket) + crane push (daemonless, uses container DNS).
docker push goes through the host daemon which can't resolve 'gitea'.
crane pushes directly from the job container's network stack.
"""
name = img["name"] name = img["name"]
tags = [t.strip() for t in tags_expr.split(",") if t.strip()] tags = [t.strip() for t in tags_expr.split(",") if t.strip()]
tag_flags = " ".join(f"-t {t}" for t in tags) local_tag = f"local/{name}:build"
cache_flag = " --no-cache" if no_cache else "" cache_flag = " --no-cache" if no_cache else ""
lines = f"""\ lines = f"""\
- name: Build {name} - name: Build {name}
run: docker build{cache_flag} -f {img["dockerfile"]} {tag_flags} {img["context"]}""" run: docker build{cache_flag} -f {img["dockerfile"]} -t {local_tag} {img["context"]}"""
if not load_only and tags: if not load_only and tags:
push_cmds = "\n ".join(f"docker push {t}" for t in tags) # Save to tarball, then crane push each tag (daemonless)
push_cmds = "\n ".join(
f"crane push /tmp/{name}.tar {t} --insecure" for t in tags
)
lines += f""" lines += f"""
- name: Push {name} - name: Push {name}
run: | run: |
docker save {local_tag} -o /tmp/{name}.tar
{push_cmds}""" {push_cmds}"""
return lines return lines
@@ -108,10 +116,15 @@ def _download_artifact_step(name: str) -> str:
def _docker_login_step(registry: str) -> str: def _docker_login_step(registry: str) -> str:
"""Login using PAT secret — plain docker login (avoids action compat issues).""" """Install crane and authenticate — daemonless push tool."""
return f"""\ return f"""\
- name: Log in to container registry - name: Install crane
run: echo "${{{{ secrets.REGISTRY_TOKEN }}}}" | docker login {registry} -u "${{{{ secrets.REGISTRY_USER }}}}" --password-stdin""" run: curl -sL https://github.com/google/go-containerregistry/releases/latest/download/go-containerregistry_Linux_x86_64.tar.gz | tar xz -C /usr/local/bin crane
- name: Log in to registry
run: crane auth login {registry} -u "${{{{ secrets.REGISTRY_USER }}}}" -p "${{{{ secrets.REGISTRY_TOKEN }}}}"
env:
CRANE_INSECURE: "true\""""
# ── Workflow generators ────────────────────────────────────────── # ── Workflow generators ──────────────────────────────────────────