atproto-docker #
Prebuilt, digest-pinned container images for the atproto services that keep
turning up in local development, so no project has to compile Go or Rust to run
a devnet. Built for linux/amd64 and linux/arm64, published to
atcr.io/mokkenstorm.dev.
| image | upstream | licence |
|---|---|---|
atcr.io/mokkenstorm.dev/jetstream |
bluesky-social/jetstream | MIT or Apache-2.0 |
atcr.io/mokkenstorm.dev/constellation |
microcosm.blue/microcosm-rs | AGPL-3.0-only |
atcr.io/mokkenstorm.dev/slingshot |
microcosm.blue/microcosm-rs | MIT or Apache-2.0 |
Consumers pin the @sha256 digest, never a tag. Tags here are transport
handles: they exist to get bytes into the registry and are never reused.
Publishing a new revision #
Two phases, because a digest cannot be known until the image exists.
-
Change the revision in
sources.envand merge it. Thepublishworkflow builds and pushes it, then prints one line per service:IMAGE_LOCK JETSTREAM_IMAGE=atcr.io/mokkenstorm.dev/jetstream@sha256:... -
Copy the digests into whatever pins them downstream. For crate that is
e2e/devnet/images.env, followed bymake e2e-images-verify,make e2e-up, and the e2e suite before merging.
A retry must start a new pipeline rather than reuse a tag. To build locally
without publishing, ./fetch-sources.sh clones the pinned revisions into
jetstream/ and microcosm-rs/; build from there directly.
Registry credential #
The workflow needs REGISTRY_USER (the atcr handle) and REGISTRY_TOKEN.
Prefer a device secret over an app password. Mint one by running the credential helper's device flow on a workstation and approving it in a browser:
curl -fsSL https://atcr.io/static/install.sh | bash
docker-credential-atcr login
The atcr_device_... secret it stores is a registry-scoped bearer credential
that atcr.io/auth/token accepts as a Basic password, so CI can use it directly
with no helper installed. It appears in docker-credential-atcr status under
the device name it was minted with, and can be revoked on its own.
A full-access ATProto app password also works, but grants far more than the
registry and is documented as the legacy path. A read-only app password does
not work: minting the hold service token calls
com.atproto.server.getServiceAuth, which rejects it with a permanent
InsufficientScope.
A device secret is only as durable as the account's underlying OAuth session.
If publishing fails with oauth_session_expired, re-run the device flow and
replace the secret.
Licences #
Each image carries org.opencontainers.image.source, .revision, and
.licenses labels pointing at the exact upstream revision it was built from.
Constellation is AGPL-3.0-only. The source label, the revision label, and these build instructions together are the first-publication source notice for the binaries published here.
SBOM and provenance attestations are deliberately disabled until we adopt a pinned verifier that can validate the actual in-toto subjects and predicate types for both platform manifests.