Reach compiler and Docker runtime: who should own image version pinning for reproducible builds?
0 reputation · 24 Jan 2022, 22:20 UTC
0 reputation · 24 Jan 2022, 22:20 UTC
We are adopting Reach (reach.sh) for a DApp project and want a repeatable development environment across laptops and CI. Reach distributes its compiler and standard library as Docker images invoked through the ./reach wrapper script, so the host only needs Docker. That makes the boundary between the Reach toolchain and the Docker runtime the place where reproducibility either holds or silently breaks.
Our goal: two machines running the same .rsh source should produce identical compilation output and behave identically against the local devnet. The uncertainty is that the wrapper appears to select image versions, but it is unclear whether it pins mutable tags or content-addressed digests. Tags can drift when re-pulled, so "same Reach release" may not mean "same images." Compilation output also depends on the chosen connector (Algorand vs Ethereum-style), so pinning must cover both compiler and connector. Some of our machines sit behind a corporate proxy, and one developer uses rootless Docker, which may change devnet networking assumptions.
29275 reputation · 25 Jan 2022, 00:01 UTC
The Reach toolchain side — the wrapper script and your project's pinned Reach release — should own version selection, and your repository should own recording the resolved digests. The Docker runtime should be treated as a dumb executor: it runs whatever image reference it is handed and should never decide which version that is. If you let the runtime (or a developer's local image cache) influence which image runs, you have moved the reproducibility boundary to the least controllable place.
Whether the ./reach wrapper resolves images by mutable tag or by digest is a property of the specific Reach release you installed, and it has changed across versions of similar toolchain wrappers, so treat it as unverified until you check. Two quick checks on one machine settle it:
# See which images the wrapper actually pulls/uses
REACH_DEBUG=1 ./reach compile --help 2>&1 | grep -i 'docker\|image'
# After a compile, inspect what is in the local cache
docker images --digests | grep -i reachIf the wrapper references tags like reachsh/reach:x.y.z, then "same release" does not guarantee "same bytes" — a re-published tag or a stale local cache on one laptop will silently diverge. If it references @sha256:... digests, the release pin is already content-addressed and your remaining risk is much smaller.
A practical pattern: after first setup on a clean machine, record digests into a checked-in file:
docker images --digests --format '{{.Repository}}@{{.Digest}}' \
| grep -i reach > reach-images.lockThen add a CI step that fails if the resolved digests differ from the lockfile. That gives you drift detection without fighting the wrapper. Only if you observe actual drift should you override image references yourself (e.g., via the wrapper's environment-variable overrides, if your release exposes them) — overriding prematurely couples you to internals that change between releases.
Neither rootless Docker nor a corporate proxy changes image reproducibility — digests are digests regardless of how the bytes arrived. The risk is at the devnet networking layer, not the compiler layer:
host.docker.internal or specific localhost bindings, test that path explicitly on the rootless machine.HTTP(S)_PROXY in the Docker daemon config (not just your shell), but a transparent caching proxy that serves correct content does not alter digests — verify with docker inspect on the pulled image if you suspect rewriting.Pin the Reach release plus connector in the repo, record resolved digests in a lockfile, and let Docker be a generic executor. Verify the wrapper's tag/digest behavior on your exact release before deciding whether you need to override image references — that one check determines how much of this you actually have to build.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.