ci(nightly): assert backend container can read /import after deploy #532

Open
opened 2026-05-11 20:13:57 +02:00 by marcel · 0 comments
Owner

Type: CI / deployment guard
Priority: P2-medium — silent-failure mode (mount present but unreadable) is currently undetectable until a human notices
Source: review of #526 by Sara Holt — comment #8649, finding 3. Also relates to Tobias's UID concern in #8646, finding 4.
Parent PR: #526 (mass-import bind mount)

Summary

After Deploy staging, exec ls /import inside the backend container and fail the workflow with a ::error:: annotation if the container cannot read it. Surface the first 5 filenames for operator visibility.

Context

#526 wires the /import bind mount but only verifies it's present in the rendered compose config. It doesn't verify the running container can actually read the mount. Two silent-failure modes are possible:

  1. The host path exists but has restrictive permissions (e.g. mode 700 owned by a user the container's UID can't access).
  2. The container's UID changes in a future base-image update and loses read permission.

In either case, mass import would mysteriously "find no spreadsheet" with no obvious cause from the operator's side.

Required

Add a step to .gitea/workflows/nightly.yml after Deploy staging:

- name: Verify backend can read /import
  run: |
    docker exec archiv-staging-backend-1 sh -c 'ls /import >/dev/null 2>&1' \
      || { echo "::error::backend container cannot read /import (UID mismatch or perms)"; exit 1; }
    # And surface what's actually there for operator visibility
    docker exec archiv-staging-backend-1 sh -c 'ls /import | head -5'

Acceptance criteria

  • Step added to nightly.yml (and likely release.yml)
  • On the next staging deploy, the step passes and shows the first 5 imported filenames in the run log
  • If /srv/familienarchiv-staging/import/ is intentionally empty, the step still passes (empty ls is exit 0)
  • Failure annotation explicitly names "UID mismatch or perms" so the operator knows where to look

Linked NFRs

  • Reliability: Bind mounts required by prod-reachable features MUST be verified readable from inside the container at deploy time.
  • Observability: Mount-readability failure MUST produce an actionable, named error annotation.
  • Production rollout step in release.yml should mirror this (track separately if not done in the same PR).

Definition of Ready

  • Exact docker exec command specified
  • Failure path defined
  • Empty-directory edge case considered
  • Acceptance criteria testable

🤖 Generated with Claude Code during /implement on #526

**Type:** CI / deployment guard **Priority:** P2-medium — silent-failure mode (mount present but unreadable) is currently undetectable until a human notices **Source:** review of #526 by Sara Holt — comment [#8649](https://git.raddatz.cloud/marcel/familienarchiv/pulls/526#issuecomment-8649), finding 3. Also relates to Tobias's UID concern in [#8646](https://git.raddatz.cloud/marcel/familienarchiv/pulls/526#issuecomment-8646), finding 4. **Parent PR:** #526 (mass-import bind mount) ## Summary After `Deploy staging`, exec `ls /import` inside the backend container and fail the workflow with a `::error::` annotation if the container cannot read it. Surface the first 5 filenames for operator visibility. ## Context #526 wires the `/import` bind mount but only verifies it's present in the rendered compose config. It doesn't verify the running container can actually *read* the mount. Two silent-failure modes are possible: 1. The host path exists but has restrictive permissions (e.g. mode 700 owned by a user the container's UID can't access). 2. The container's UID changes in a future base-image update and loses read permission. In either case, mass import would mysteriously "find no spreadsheet" with no obvious cause from the operator's side. ## Required Add a step to `.gitea/workflows/nightly.yml` after `Deploy staging`: ```yaml - name: Verify backend can read /import run: | docker exec archiv-staging-backend-1 sh -c 'ls /import >/dev/null 2>&1' \ || { echo "::error::backend container cannot read /import (UID mismatch or perms)"; exit 1; } # And surface what's actually there for operator visibility docker exec archiv-staging-backend-1 sh -c 'ls /import | head -5' ``` ## Acceptance criteria - [ ] Step added to `nightly.yml` (and likely `release.yml`) - [ ] On the next staging deploy, the step passes and shows the first 5 imported filenames in the run log - [ ] If `/srv/familienarchiv-staging/import/` is intentionally empty, the step still passes (empty `ls` is exit 0) - [ ] Failure annotation explicitly names "UID mismatch or perms" so the operator knows where to look ## Linked NFRs - **Reliability:** Bind mounts required by prod-reachable features MUST be verified readable from inside the container at deploy time. - **Observability:** Mount-readability failure MUST produce an actionable, named error annotation. ## Dependencies / related - Production rollout step in `release.yml` should mirror this (track separately if not done in the same PR). ## Definition of Ready - [x] Exact docker exec command specified - [x] Failure path defined - [x] Empty-directory edge case considered - [x] Acceptance criteria testable 🤖 Generated with [Claude Code](https://claude.com/claude-code) during /implement on #526
marcel added the P2-mediumdevopstest labels 2026-05-11 20:36:42 +02:00
Sign in to join this conversation.
No Label P2-medium devops test
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#532