An easy-to-host PDS on the ATProtocol, MacOS. Grandma-approved.

feat(MM-66): add Docker image derived from Nix build #4

Summary#

  • Adds nix/docker.nix — a standalone buildLayeredImage derivation for the relay binary, including sqlite runtime, CA certificates, and timezone data
  • Extends flake.nix to expose packages.{aarch64,x86_64}-linux.docker-image using pkgs.lib.optionalAttrs pkgs.stdenv.isLinux; the Darwin package outputs are unchanged
  • Updates CLAUDE.md with the nix build .#docker-image command (Linux-only caveat) and documents the new nix/ directory in the project structure
  • Adds tests/verify-mm66.sh — automated verification script for AC1.3 (docker-image absent on Darwin) and AC3.4 (nix/docker.nix tracked by git)

Test Plan#

  • nix eval confirms docker-image present for aarch64-linux and x86_64-linux
  • nix eval confirms docker-image absent for aarch64-darwin and x86_64-darwin (AC1.3)
  • git ls-files nix/docker.nix returns the file (AC3.4)
  • bash tests/verify-mm66.sh passes
  • Linux verification required: see docs/test-plans/2026-03-08-MM-66.md for the full human test plan (AC2.1–AC5.1 require a Linux system with Docker)
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:web:malpercio.dev/sh.tangled.repo.pull/3mgl4gjdehj22
+46 -39
Interdiff #1 #2
.gitignore

This file has not been changed.

+1 -1
CLAUDE.md
··· 11 11 ## Commands 12 12 - `nix develop --impure --accept-flake-config` - Enter dev shell (flags required; --impure for devenv CWD detection, --accept-flake-config activates the Cachix binary cache in nixConfig — without it, a cold build takes 20+ minutes) 13 13 - `nix build .#relay --accept-flake-config` - Build relay binary (output at ./result/bin/relay) 14 - - `nix build .#docker-image --accept-flake-config` - Build Docker image tarball (Linux only; `docker-image` is not exposed on macOS — use a remote Linux builder or CI) 14 + - `nix build .#docker-image --accept-flake-config` - Build Docker image tarball (Linux only; output at `./result`; load with `docker load < result`; `docker-image` is not exposed on macOS — use a remote Linux builder or CI) 15 15 - `cargo build` - Build all crates 16 16 - `cargo test` - Run all tests 17 17 - `cargo clippy` - Lint
+1 -1
docs/design-plans/2026-03-08-MM-66.md
··· 54 54 - **`TZDIR`**: An environment variable recognised by the C library and Rust's `time`/`chrono` crates that points to the timezone database directory. Set in the Docker image config to the tzdata store path. 55 55 - **`cargoArtifacts`**: Crane's name for the pre-built dependency artifact set produced by `buildDepsOnly`. Passed into `buildPackage` so incremental rebuilds skip recompiling dependencies. 56 56 - **closure**: In Nix, the full set of store paths that a derivation depends on transitively. The Docker image's closure is exactly what ends up in its filesystem layers. 57 - - **`self.shortRev`**: A flake variable holding the short git commit hash of the repository at build time. Mentioned in the tag strategy as a future replacement for `"latest"` to produce traceable image tags. 57 + - **`self.shortRev`**: A flake variable holding the short git commit hash of the repository at build time. Mentioned in the tag strategy as a future replacement for `"latest"` to produce traceable image tags. Note: `self.shortRev` is absent on dirty trees (uncommitted changes), causing a flake evaluation error unless guarded as `self.shortRev or "dev"`. 58 58 - **stub**: Used in this document to mean the relay binary currently compiles and exits but does not serve HTTP traffic. The Docker packaging is tested against this stub rather than a fully functional server. 59 59 60 60 ## Architecture
docs/implementation-plans/2026-03-08-MM-66/phase_01.md

This file has not been changed.

docs/implementation-plans/2026-03-08-MM-66/phase_02.md

This file has not been changed.

docs/implementation-plans/2026-03-08-MM-66/test-requirements.md

This file has not been changed.

docs/test-plans/2026-03-08-MM-66.md

This file has not been changed.

flake.nix

This file has not been changed.

+6 -1
nix/docker.nix
··· 2 2 pkgs.dockerTools.buildLayeredImage { 3 3 name = "relay"; 4 4 tag = "latest"; 5 - contents = [ relay pkgs.sqlite.out pkgs.cacert pkgs.tzdata ]; 5 + contents = [ 6 + relay 7 + pkgs.sqlite.out # runtime shared library only; .out excludes headers/dev outputs 8 + pkgs.cacert 9 + pkgs.tzdata 10 + ]; 6 11 config = { 7 12 Entrypoint = [ "${relay}/bin/relay" ]; 8 13 Env = [
+38 -36
tests/verify-mm66.sh
··· 3 3 set -euo pipefail 4 4 5 5 PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" 6 + cd "$PROJECT_ROOT" 6 7 7 8 echo "==================================================" 8 9 echo "MM-66 Automated Verification Tests" 9 10 echo "==================================================" 10 11 echo 11 12 12 - # Track pass/fail status 13 13 FAILED=0 14 14 15 - # AC1.3: Verify docker-image is absent for Darwin systems 15 + # AC1.3: Verify docker-image is absent for Darwin systems, present for Linux. 16 + # 17 + # Uses `nix eval` to inspect package attribute names per system — structurally 18 + # reliable and avoids parsing `nix flake show` tree output with brittle grep -A 19 + # heuristics. --accept-flake-config activates the Cachix binary cache; without 20 + # it, evaluation on a cold machine may trigger a 20+ minute build. 16 21 echo "AC1.3: Checking docker-image platform availability..." 17 22 18 - # First, try nix flake show 19 - if nix flake show --accept-flake-config 2>/dev/null | grep -q docker-image; then 20 - echo " nix flake show: Available" 21 - # Check that docker-image only appears under Linux systems 22 - DARWIN_DOCKER=$(nix flake show --accept-flake-config 2>/dev/null | grep -A 5 "aarch64-darwin\|x86_64-darwin" | grep -c "docker-image" || true) 23 - LINUX_DOCKER=$(nix flake show --accept-flake-config 2>/dev/null | grep -A 5 "aarch64-linux\|x86_64-linux" | grep -c "docker-image" || true) 24 - 25 - if [ "$DARWIN_DOCKER" -eq 0 ] && [ "$LINUX_DOCKER" -gt 0 ]; then 26 - echo " PASS: docker-image present only on Linux systems (aarch64-linux, x86_64-linux)" 27 - else 28 - echo " FAIL: docker-image incorrectly appearing on Darwin or missing from Linux" 29 - FAILED=1 30 - fi 23 + DARWIN_PACKAGES=$(nix eval --json --accept-flake-config ".#packages.aarch64-darwin" --apply 'builtins.attrNames') 24 + if echo "$DARWIN_PACKAGES" | grep -q "docker-image"; then 25 + echo " FAIL: docker-image incorrectly present on aarch64-darwin" 26 + FAILED=1 31 27 else 32 - # Fallback: Use nix eval to check package attributes per system 33 - echo " nix flake show: Unavailable (expected due to devenv CWD detection issue), using fallback" 28 + echo " PASS: docker-image absent from aarch64-darwin" 29 + fi 34 30 35 - # Check Darwin systems do NOT have docker-image 36 - DARWIN_PACKAGES=$(nix eval --json ".#packages.aarch64-darwin" --apply 'builtins.attrNames' 2>/dev/null || echo "[]") 37 - if echo "$DARWIN_PACKAGES" | grep -q "docker-image"; then 38 - echo " FAIL: docker-image incorrectly present on aarch64-darwin" 39 - FAILED=1 40 - else 41 - echo " PASS: docker-image absent from aarch64-darwin" 42 - fi 43 - 44 - # Check Linux systems DO have docker-image 45 - LINUX_PACKAGES=$(nix eval --json ".#packages.x86_64-linux" --apply 'builtins.attrNames' 2>/dev/null || echo "[]") 46 - if echo "$LINUX_PACKAGES" | grep -q "docker-image"; then 47 - echo " PASS: docker-image present on x86_64-linux" 48 - else 49 - echo " WARN: docker-image not detected on x86_64-linux (may be due to evaluation context)" 50 - fi 31 + LINUX_PACKAGES=$(nix eval --json --accept-flake-config ".#packages.x86_64-linux" --apply 'builtins.attrNames') 32 + if echo "$LINUX_PACKAGES" | grep -q "docker-image"; then 33 + echo " PASS: docker-image present on x86_64-linux" 34 + else 35 + echo " FAIL: docker-image missing from x86_64-linux" 36 + FAILED=1 51 37 fi 52 38 53 39 echo 54 40 55 - # AC3.4: Verify nix/docker.nix is tracked by git 41 + # AC3.4: Verify nix/docker.nix is tracked by git. 56 42 echo "AC3.4: Checking nix/docker.nix git tracking..." 57 43 58 - cd "$PROJECT_ROOT" 59 - 60 44 if git ls-files nix/docker.nix | grep -q "nix/docker.nix"; then 61 45 echo " PASS: nix/docker.nix is tracked by git" 62 46 else ··· 65 49 fi 66 50 67 51 echo 52 + 53 + # Docker smoke test (Linux only — docker-image is not exposed on Darwin). 54 + # Runs when Docker is available and relay:latest is already loaded, confirming 55 + # the relay binary and libsqlite3.so are present in the image closure. The relay 56 + # is a stub and may exit non-zero; that is acceptable. Only linker/missing-file 57 + # errors indicate a broken image. 58 + if command -v docker >/dev/null 2>&1 && docker image inspect relay:latest >/dev/null 2>&1; then 59 + echo "Docker smoke test: relay:latest found — verifying binary and dynamic linking..." 60 + OUTPUT=$(docker run --rm relay:latest 2>&1 || true) 61 + if echo "$OUTPUT" | grep -qE "no such file|error while loading shared libraries"; then 62 + echo " FAIL: linker or missing-binary error detected" 63 + echo " $OUTPUT" 64 + FAILED=1 65 + else 66 + echo " PASS: relay:latest ran without linker or missing-binary errors" 67 + fi 68 + echo 69 + fi 68 70 69 71 # Summary 70 72 echo "=================================================="

History

4 rounds 0 comments
sign up or login to add to the discussion
9 commits
expand
docs: add MM-66 Docker image design plan
feat(MM-66): add nix/docker.nix and expose docker-image on Linux
docs(MM-66): note docker-image is Linux-only in CLAUDE.md
docs(MM-66): add nix/ directory to project structure in CLAUDE.md
test(MM-66): add automated verification script for AC1.3 and AC3.4
docs: add test plan for MM-66 Docker image
docs(MM-66): commit implementation plans and ignore nix result symlink
fix(MM-66): address PR review — verify-mm66.sh silent failures, comments, CLAUDE.md
docs(MM-66): note NixOS Docker sysctl issue in test plan step 4.1
expand 0 comments
pull request successfully merged
8 commits
expand
docs: add MM-66 Docker image design plan
feat(MM-66): add nix/docker.nix and expose docker-image on Linux
docs(MM-66): note docker-image is Linux-only in CLAUDE.md
docs(MM-66): add nix/ directory to project structure in CLAUDE.md
test(MM-66): add automated verification script for AC1.3 and AC3.4
docs: add test plan for MM-66 Docker image
docs(MM-66): commit implementation plans and ignore nix result symlink
fix(MM-66): address PR review — verify-mm66.sh silent failures, comments, CLAUDE.md
expand 0 comments
7 commits
expand
docs: add MM-66 Docker image design plan
feat(MM-66): add nix/docker.nix and expose docker-image on Linux
docs(MM-66): note docker-image is Linux-only in CLAUDE.md
docs(MM-66): add nix/ directory to project structure in CLAUDE.md
test(MM-66): add automated verification script for AC1.3 and AC3.4
docs: add test plan for MM-66 Docker image
docs(MM-66): commit implementation plans and ignore nix result symlink
expand 0 comments
6 commits
expand
docs: add MM-66 Docker image design plan
feat(MM-66): add nix/docker.nix and expose docker-image on Linux
docs(MM-66): note docker-image is Linux-only in CLAUDE.md
docs(MM-66): add nix/ directory to project structure in CLAUDE.md
test(MM-66): add automated verification script for AC1.3 and AC3.4
docs: add test plan for MM-66 Docker image
expand 0 comments