Skip to content

fix(apps): restore state into the volume, not docker cp into a created container; v0.3.3 - #221

Merged
ralyodio merged 1 commit into
masterfrom
fix/apps-restore-sigpipe
Nov 9, 2026
Merged

ralyodio merged 1 commit into
masterfrom
fix/apps-restore-sigpipe

Conversation

@ralyodio

@ralyodio ralyodio commented Nov 9, 2026

Copy link
Copy Markdown
Collaborator

Every failover restore failed on Docker 29 (containerd image store): docker cp into a never-started container answers "destination must be a directory". With SIGPIPE at its default that killed the dev2 gateway worker on each promotion (a crash loop; apps is turned off on dev2 and dev3 until this ships). #219 already keeps SIGPIPE ignored in long-running commands.

Restore now unpacks the snapshot into the state volume with a pinned busybox helper before the app container is created. Verified against real Docker on dev2; the e2e fake models the new restore path.

🤖 Generated with Claude Code

…reated container; v0.3.3

Live on dev2 (Docker 29.9, containerd image store) every failover restore
failed: `docker cp - <created container>:/` answers "destination must be a
directory" because a container that never started has no filesystem yet.
docker cp exited, the stdin write hit a closed pipe, and with SIGPIPE at its
default the gateway worker died (systemd counted it a clean exit) on every
promotion: a crash loop on the only Moshpit gateway until apps was turned off
there. (#219 already keeps SIGPIPE ignored in long-running commands.)

Restore now unpacks the snapshot into a fresh state volume with a pinned
busybox helper (`docker run --rm -i --network none -v <vol>:/restore ...
tar -x --strip-components=1`) before the app container is created; Docker
leaves a non-empty named volume alone, so the app starts on that state.
Verified against real Docker on dev2. The e2e fake models the new restore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

ThreatCrush Security Scan

13 finding(s)

HIGH/CRITICAL: 1 | MEDIUM: 8 | LOW: 4

Severity Rule Location
HIGH js-ssrf-outbound-request apps/web/public/sw.js:24
MEDIUM js-unescaped-html-sink apps/web/src/app/blog/[slug]/page.tsx:53
MEDIUM js-unescaped-html-sink apps/web/src/app/layout.tsx:89
MEDIUM sh-remote-script-execution scripts/dev-setup.sh:25
MEDIUM sh-eval-expansion scripts/dev-setup.sh:35
MEDIUM sh-remote-script-execution scripts/install.sh:181
MEDIUM sh-remote-script-execution scripts/install.sh:206
MEDIUM sh-remote-script-execution scripts/install.sh:399
MEDIUM sh-remote-script-execution scripts/install.sh:441
LOW py-ssrf-outbound-request examples/business-strategist-agent/chat.py:37
LOW py-ssrf-outbound-request examples/business-strategist-agent/train.py:54
LOW secret-generic-credential node/crates/c0mpute-core/src/webhook.rs:1165
LOW py-path-traversal node/crates/c0mpute-core/tests/fixtures/fake-infernet-text:29

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit 6cb0adb into master Nov 9, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant