fix(ci): replace overlay2 sync with workspace bind mount for DooD
runner-config.yaml: correct path to /srv/gitea-workspace (VPS, not Synology). docker-compose.observability.yml: revert 5 bind mounts to plain relative paths; OBS_CONFIG_DIR variable is no longer needed. nightly.yml / release.yml: remove OBS_CONFIG_DIR env injection and the "Sync observability configs to host" step from both workflows. With workdir_parent=/srv/gitea-workspace and an identical host<->container bind mount, $(pwd) inside job containers resolves to a real host path the daemon can find — no privileged container, no overlay2 inspection, no nsenter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -85,7 +85,6 @@ jobs:
|
|||||||
GLITCHTIP_SECRET_KEY=${{ secrets.GLITCHTIP_SECRET_KEY }}
|
GLITCHTIP_SECRET_KEY=${{ secrets.GLITCHTIP_SECRET_KEY }}
|
||||||
GLITCHTIP_DOMAIN=https://glitchtip.archiv.raddatz.cloud
|
GLITCHTIP_DOMAIN=https://glitchtip.archiv.raddatz.cloud
|
||||||
SENTRY_DSN=${{ secrets.SENTRY_DSN }}
|
SENTRY_DSN=${{ secrets.SENTRY_DSN }}
|
||||||
OBS_CONFIG_DIR=/srv/familienarchiv-staging/obs-configs
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
- name: Verify backend /import:ro mount is wired
|
- name: Verify backend /import:ro mount is wired
|
||||||
@@ -132,24 +131,6 @@ jobs:
|
|||||||
--profile staging \
|
--profile staging \
|
||||||
up -d --wait --remove-orphans
|
up -d --wait --remove-orphans
|
||||||
|
|
||||||
- name: Sync observability configs to host
|
|
||||||
# DooD: runner-config.yaml only shares /var/run/docker.sock with the host
|
|
||||||
# daemon — no workspace directory is mapped. Relative bind mounts in
|
|
||||||
# docker-compose.observability.yml would resolve to paths that don't
|
|
||||||
# exist on the host; Docker auto-creates directories in their place,
|
|
||||||
# causing "not a directory" mount failures at container startup.
|
|
||||||
#
|
|
||||||
# Fix: find the job container's overlay2 merged directory (visible in the
|
|
||||||
# host's mount namespace), then use nsenter to copy from there into a
|
|
||||||
# stable host path. The overlay path is the job container's full
|
|
||||||
# filesystem as seen from the host — no socket tricks needed.
|
|
||||||
run: |
|
|
||||||
OVERLAY=$(docker inspect "$(hostname)" --format '{{.GraphDriver.Data.MergedDir}}')
|
|
||||||
SRC="${OVERLAY}$(pwd)/infra/observability"
|
|
||||||
docker run --rm --privileged --pid=host \
|
|
||||||
alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d \
|
|
||||||
sh -c "nsenter -t 1 -m -- sh -c 'mkdir -p /srv/familienarchiv-staging/obs-configs && cp -r \"${SRC}/.\" /srv/familienarchiv-staging/obs-configs/'"
|
|
||||||
|
|
||||||
- name: Start observability stack
|
- name: Start observability stack
|
||||||
run: |
|
run: |
|
||||||
docker compose \
|
docker compose \
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ jobs:
|
|||||||
GLITCHTIP_SECRET_KEY=${{ secrets.GLITCHTIP_SECRET_KEY }}
|
GLITCHTIP_SECRET_KEY=${{ secrets.GLITCHTIP_SECRET_KEY }}
|
||||||
GLITCHTIP_DOMAIN=https://glitchtip.archiv.raddatz.cloud
|
GLITCHTIP_DOMAIN=https://glitchtip.archiv.raddatz.cloud
|
||||||
SENTRY_DSN=${{ secrets.SENTRY_DSN }}
|
SENTRY_DSN=${{ secrets.SENTRY_DSN }}
|
||||||
OBS_CONFIG_DIR=/srv/familienarchiv-production/obs-configs
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
- name: Build images
|
- name: Build images
|
||||||
@@ -105,16 +104,6 @@ jobs:
|
|||||||
--env-file .env.production \
|
--env-file .env.production \
|
||||||
up -d --wait --remove-orphans
|
up -d --wait --remove-orphans
|
||||||
|
|
||||||
- name: Sync observability configs to host
|
|
||||||
# DooD: same overlay2 trick as nightly.yml — see that file for the
|
|
||||||
# full rationale. Production path: /srv/familienarchiv-production/obs-configs.
|
|
||||||
run: |
|
|
||||||
OVERLAY=$(docker inspect "$(hostname)" --format '{{.GraphDriver.Data.MergedDir}}')
|
|
||||||
SRC="${OVERLAY}$(pwd)/infra/observability"
|
|
||||||
docker run --rm --privileged --pid=host \
|
|
||||||
alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d \
|
|
||||||
sh -c "nsenter -t 1 -m -- sh -c 'mkdir -p /srv/familienarchiv-production/obs-configs && cp -r \"${SRC}/.\" /srv/familienarchiv-production/obs-configs/'"
|
|
||||||
|
|
||||||
- name: Start observability stack
|
- name: Start observability stack
|
||||||
run: |
|
run: |
|
||||||
docker compose \
|
docker compose \
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ services:
|
|||||||
container_name: obs-prometheus
|
container_name: obs-prometheus
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ${OBS_CONFIG_DIR:-./infra/observability}/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
- ./infra/observability/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
||||||
- prometheus_data:/prometheus
|
- prometheus_data:/prometheus
|
||||||
command:
|
command:
|
||||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||||
@@ -79,7 +79,7 @@ services:
|
|||||||
container_name: obs-loki
|
container_name: obs-loki
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ${OBS_CONFIG_DIR:-./infra/observability}/loki/loki-config.yml:/etc/loki/loki-config.yml:ro
|
- ./infra/observability/loki/loki-config.yml:/etc/loki/loki-config.yml:ro
|
||||||
- loki_data:/loki
|
- loki_data:/loki
|
||||||
command: -config.file=/etc/loki/loki-config.yml
|
command: -config.file=/etc/loki/loki-config.yml
|
||||||
expose:
|
expose:
|
||||||
@@ -98,7 +98,7 @@ services:
|
|||||||
container_name: obs-promtail
|
container_name: obs-promtail
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ${OBS_CONFIG_DIR:-./infra/observability}/promtail/promtail-config.yml:/etc/promtail/promtail-config.yml:ro
|
- ./infra/observability/promtail/promtail-config.yml:/etc/promtail/promtail-config.yml:ro
|
||||||
- /var/lib/docker/containers:/var/lib/docker/containers:ro
|
- /var/lib/docker/containers:/var/lib/docker/containers:ro
|
||||||
# :ro restricts file-system access but NOT Docker API permissions — a compromised Promtail has full daemon access. Accepted risk on single-operator self-hosted archive.
|
# :ro restricts file-system access but NOT Docker API permissions — a compromised Promtail has full daemon access. Accepted risk on single-operator self-hosted archive.
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
@@ -118,7 +118,7 @@ services:
|
|||||||
container_name: obs-tempo
|
container_name: obs-tempo
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ${OBS_CONFIG_DIR:-./infra/observability}/tempo/tempo.yml:/etc/tempo.yml:ro
|
- ./infra/observability/tempo/tempo.yml:/etc/tempo.yml:ro
|
||||||
- tempo_data:/var/tempo
|
- tempo_data:/var/tempo
|
||||||
command: -config.file=/etc/tempo.yml
|
command: -config.file=/etc/tempo.yml
|
||||||
expose:
|
expose:
|
||||||
@@ -148,7 +148,7 @@ services:
|
|||||||
GF_USERS_ALLOW_SIGN_UP: "false"
|
GF_USERS_ALLOW_SIGN_UP: "false"
|
||||||
volumes:
|
volumes:
|
||||||
- grafana_data:/var/lib/grafana
|
- grafana_data:/var/lib/grafana
|
||||||
- ${OBS_CONFIG_DIR:-./infra/observability}/grafana/provisioning:/etc/grafana/provisioning:ro
|
- ./infra/observability/grafana/provisioning:/etc/grafana/provisioning:ro
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "wget -qO- http://localhost:3000/api/health | grep -q ok || exit 1"]
|
test: ["CMD-SHELL", "wget -qO- http://localhost:3000/api/health | grep -q ok || exit 1"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
|
|||||||
@@ -7,20 +7,20 @@ container:
|
|||||||
# is the requirement: Docker Compose resolves relative bind mounts to
|
# is the requirement: Docker Compose resolves relative bind mounts to
|
||||||
# $(pwd) inside the job container and passes that absolute path to the
|
# $(pwd) inside the job container and passes that absolute path to the
|
||||||
# host daemon — the daemon must find the file at that exact host path.
|
# host daemon — the daemon must find the file at that exact host path.
|
||||||
# Prerequisite: mkdir -p /volume1/gitea-workspace on the NAS, and add
|
# Prerequisite: mkdir -p /srv/gitea-workspace on the host, and add
|
||||||
# - /volume1/gitea-workspace:/volume1/gitea-workspace
|
# - /srv/gitea-workspace:/srv/gitea-workspace
|
||||||
# to the runner service volumes in gitea's docker-compose.yml.
|
# to the runner service volumes in gitea's compose.yaml.
|
||||||
workdir_parent: /volume1/gitea-workspace
|
workdir_parent: /srv/gitea-workspace
|
||||||
# whitelists volumes that workflow steps may bind-mount
|
# whitelists volumes that workflow steps may bind-mount
|
||||||
valid_volumes:
|
valid_volumes:
|
||||||
- "/var/run/docker.sock"
|
- "/var/run/docker.sock"
|
||||||
- "/volume1/gitea-workspace"
|
- "/srv/gitea-workspace"
|
||||||
# appended to `docker run` when the runner spawns a job container
|
# appended to `docker run` when the runner spawns a job container
|
||||||
# SECURITY: Mounting the Docker socket grants job containers root-equivalent
|
# SECURITY: Mounting the Docker socket grants job containers root-equivalent
|
||||||
# access to the host Docker daemon. Acceptable here because only trusted code
|
# access to the host Docker daemon. Acceptable here because only trusted code
|
||||||
# from this private repo runs on this runner. Do NOT use on a runner that
|
# from this private repo runs on this runner. Do NOT use on a runner that
|
||||||
# accepts untrusted PRs from external contributors.
|
# accepts untrusted PRs from external contributors.
|
||||||
options: "-v /var/run/docker.sock:/var/run/docker.sock -v /volume1/gitea-workspace:/volume1/gitea-workspace"
|
options: "-v /var/run/docker.sock:/var/run/docker.sock -v /srv/gitea-workspace:/srv/gitea-workspace"
|
||||||
# keep network mode default (bridge) — Testcontainers handles its own networking
|
# keep network mode default (bridge) — Testcontainers handles its own networking
|
||||||
force_pull: false
|
force_pull: false
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user