Hardened Production Container & Exclusive Directory Lock #34
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Construct the hardened production Docker container for
life serve(minimal non-root Linux runtime, locked binary, read-only root filesystem) and implement an exclusive OS advisory directory lock (flock) on the persistent data volume to prevent dual-writer SQLite WAL corruption during container rollouts, orchestrator rescheduling, or accidental multi-instance deployments.Background & Technical Rationale
The Dual-Writer Hazard in SQLite WAL Deployments
The
lifeservice stores its core state in an append-only SQLite database operating in Write-Ahead Logging (WAL) mode withsynchronous=FULL. While SQLite WAL allows concurrent reader connections within a single process or host, it strictly requires that at most one process acts as a database writer at any given time.In containerized and orchestrated environments (such as Docker Swarm or Kubernetes), deployment rollouts, rolling updates, or misconfigured replica counts can inadvertently launch a new container instance while an older instance is still draining connections or shutting down. If two service instances mount the same persistent volume directory simultaneously, concurrent access to
life.sqlite3,life.sqlite3-wal, andlife.sqlite3-shmwill cause index divergence, page corruption, and catastrophic transaction loss.Operational Safety Invariants
replicas: 1) is unreliable during host network partitions, node draining, or rolling updates.update_config: order: stop-first) and pinned to an explicitly selected host node with local persistent storage.life servemust acquire an exclusive non-blocking OS file lock (flock(LOCK_EX | LOCK_NB)) on/var/lib/life-service/life.lock. If another process holds the lock, startup must immediately abort with an explicit error and fatal exit code.Container Hardening Standards
UID 10001:GID 10001, namedlife).read_only: true). Only the persistent volume (/var/lib/life-service) and a small in-memory/tmpfilesystem may have write permissions.ca-certificates), and the IANA timezone database (tzdata). No compilers, package managers, development headers, or unnecessary shells are permitted.Exact Technical References & Specifications
1. Operations Security Specification: Deployment Topology
From
docs/technical/operations-security.md(lines 5–12):2. Startup & Graceful Shutdown Contract
From
docs/technical/operations-security.md(lines 47–50):3. Verification Scenario D06
From
docs/technical/verification.md(lines 139):Formal Citations
docs/technical/operations-security.md:docs/technical/verification.md:What to Build
1. Multi-Stage Production Containerfile (
Dockerfile)Construct the hardened container build:
2. Exclusive Directory Lock Manager (
src/storage/lock.rs)Implement the filesystem lock guard using
nix::fcntl::flockorfs2::FileExt:3. Startup & Signal Integration (
src/server/mod.rs)ServiceDirectoryLock::acquireinto the startup sequence oflife servebefore any database connection pool is created.LockError::AlreadyLocked:stderr:"FATAL: Directory lock acquisition failed for /var/lib/life-service/life.lock. Dual-writer prevention activated."tokio::signal::unix::signal(SignalKind::terminate())andsignal(SignalKind::interrupt())):shutdown_timeout_seconds).4. Integration Test Suite (
tests/service_directory_lock.rs)Acceptance Criteria
Observable Assertions & Verification
USER 10001:10001, and runs with a read-only root filesystem (--read-only), writing exclusively to the persistent volume and/tmp.life servecreates and acquires an exclusive advisory lock onlife.lockin the configured data directory.life serveinstance against an already-locked directory fails immediately with an explicit error, preventing dual-writer database access (Scenario D06).SIGTERMorSIGINTtriggers a graceful shutdown that completes pending operations within the drain timeout, closes SQLite cleanly, and releases the directory lock without unlinkinglife.lockfrom disk (Scenario D06).unknownin SQLite and never falsely reported as failed or dropped (Scenario D08).tests/service_directory_lock.rsreproduces Scenario D06 and passes in CI.Notes
docker buildwas not executed: the Docker daemon could not be started here, and this host isaarch64-darwinwith no Linux builder configured, so the Linux artifact cannot be built locally either. What was verified instead: ~20 static Dockerfile checks, flake evaluation of theaarch64-linuxruntime-root target, a real host build of the runtime root, and an audit showing all writes land in the configured data directory (plus SQLite temp files inTMPDIR), which is what--read-onlydepends on.Cargo.tomlauthors chore still pending (no dependency added).Blocked by
Issue #034: Hardened Production Container & Exclusive Directory Lockto Hardened Production Container & Exclusive Directory Lock