Something went wrong. Try again.
Fork of atproto-crates for SCN forked from ngerakines.me/atproto-crates
atproto pds permissioned-data rust
Something went wrong. Try again.
atproto-crates Dockerfile.pds-debug
7.2 kB · 143 lines
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144# The PDS as a single container, with a shell and enough tooling to inspect a# running deployment from the inside.## docker build -f Dockerfile.pds-debug -t atproto-pds:debug .## This is `Dockerfile.pds` with its runtime stage swapped: same builder, same# binary, same environment, same volume layout, so it can be deployed against# an existing volume and swapped back without touching the data. On Railway,# point `dockerfilePath` in `railway.toml` at this file, deploy, do the work,# and point it back.## The reason it exists: the production image is distroless, and Railway's# console needs `/bin/sh` -- "The console couldn't start because this container# doesn't include a shell". Distroless has no shell on purpose, so there is no# way to answer that from inside `Dockerfile.pds` without giving up the# property that makes it worth deploying.## WHICH IS THE POINT: prefer `Dockerfile.pds`. Everything durable this server# holds is reachable from a shell here -- every account row, every record, and# `$PDS_DATA_DIRECTORY/keys/*.key`, which are the repository *signing* keys.# Anyone who reaches this container reaches those. Deploy this image# deliberately, for as long as the question takes, and go back.## What is installed and why:## bash, coreutils already in `debian:bookworm-slim`, and the reason it is# the base: the console needs a shell, and `sha256sum`# names the actor DB.# sqlite3 the databases -- see the paths below.# curl XRPC endpoints, from inside, past the proxy.# jq every XRPC response is JSON.# less, procps reading output and seeing what is running.# ca-certificates NOT optional. distroless/cc ships a trust store and# debian-slim does not, so without this the PLC directory,# handle resolution and every outbound HTTPS call fail with# a certificate error and nothing else changes.## Where the state is, all under `PDS_DATA_DIRECTORY` (`/data` here):## accounts.sqlite the accounts directory -- one row per account,# handles, states, invite codes, OAuth rows.# actors/<sha256(did)>.sqlite one file per account: its repository, records,# blobs and spaces tables. The name is the hex# SHA-256 of the DID, so `pds-actor-db` below# exists to save you computing it by hand.# keys/<ref>.key signing and rotation keys.## Both databases are WAL. Read them read-only -- `sqlite3 -readonly` -- while# the server is running: a writing connection from the console can block the# server on a lock, and `.dump` of a live database without one is a torn read.# The one time to drop `-readonly` is with the server stopped and a `-wal` file# left behind, because replaying it into the main file is a write.
# Keep in step with `channel` in rust-toolchain.toml, `rust-version` in the# workspace Cargo.toml, and the builder stages in `Dockerfile`,# `Dockerfile.pds` and `crates/atproto-pds/Dockerfile`. The CI "toolchain pins"# step fails on drift, and covers this file for the same reason it covers the# others: `COPY . .` brings `rust-toolchain.toml` with it, so rustup builds# with the pinned toolchain whatever this line says, and a stale pin here# misreports the image rather than breaking it.FROM rust:1.97-slim-bookworm AS builder
RUN apt-get update && apt-get install -y --no-install-recommends \ pkg-config libssl-dev \ && rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/appCOPY . .
# The commit the image is built from, as in `Dockerfile.pds`: `.dockerignore`# strips `.git`, so without `--build-arg BUILD_REV=<commit>` the server reports# `unknown` in `/xrpc/_health`, the User-Agent and the startup log. On Railway# the default is `RAILWAY_GIT_COMMIT_SHA`, the commit a GitHub-triggered deploy# builds; a `railway up` deploy has none, and an empty or missing one gives# `unknown`. An explicit `BUILD_REV` wins. `Dockerfile.pds` has the long# version. Pass the same value the deployed image was built with.ARG RAILWAY_GIT_COMMIT_SHAARG BUILD_REV=${RAILWAY_GIT_COMMIT_SHA:-unknown}ENV BUILD_REV=$BUILD_REV
# The same feature set as `Dockerfile.pds`, so this image answers questions# about the deployment rather than about a different build of it -- `smtp`# especially, since without it `EmailService` compiles down to `Disabled` and# the email paths behave differently from the ones being debugged. A test# fails if this default and `Dockerfile.pds`'s stop matching, because a debug# image built from a different feature set answers the wrong questions.## Pass the same `--build-arg PDS_FEATURES=...` you passed the deployed image# when it was built with anything other than the default.## `atproto-pds-admin` comes along because it is the supported way to ask a# running server about itself, and reaching it over loopback from the console# skips the proxy and the public admin surface entirely.ARG PDS_FEATURES=clap,smtp,metrics,hickory-dnsRUN cargo build --release --features "${PDS_FEATURES}" \ --bin pds --bin atproto-pds-admin
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ sqlite3 \ curl \ jq \ less \ procps \ && rm -rf /var/lib/apt/lists/*
COPY --from=builder /usr/src/app/target/release/pds /usr/local/bin/pdsCOPY --from=builder /usr/src/app/target/release/atproto-pds-admin /usr/local/bin/atproto-pds-admin
# Resolve a DID to its per-actor database, because the filename is a hash and# nothing in a directory listing says which account it belongs to. Kept as a# file in the tree rather than written from a `RUN` heredoc, which needs a# BuildKit frontend this cannot assume the deploying platform runs.## pds-actor-db did:plc:xyz -> prints the path# pds-actor-db did:plc:xyz '.tables' -> runs it, read-only# pds-actor-db did:plc:xyz 'select count(*) from repo_record;'COPY tools/pds-debug/pds-actor-db /usr/local/bin/pds-actor-dbRUN chmod +x /usr/local/bin/pds-actor-db
# Identical to `Dockerfile.pds`, deliberately -- the whole value of this image# is that it comes up against the same volume in the same place.## Still no `VOLUME` (Railway rejects it, and elsewhere it silently creates an# anonymous one), and still no `PDS_PORT` (setting it pins the listener and# ignores the `PORT` the platform assigns). `Dockerfile.pds` carries the long# version of both.## Root, also deliberately: `Dockerfile.pds` runs as root, so the volume's files# are owned by it. A non-root user here would read nothing.ENV PDS_DATA_DIRECTORY=/dataENV PDS_BIND=0.0.0.0
EXPOSE 4800
ENTRYPOINT ["/usr/local/bin/pds"]
LABEL org.opencontainers.image.title="atproto-pds-debug"LABEL org.opencontainers.image.description="AT Protocol Personal Data Server, with shell and database tooling"LABEL org.opencontainers.image.source="https://tangled.org/ngerakines.me/atproto-crates"LABEL org.opencontainers.image.licenses="MIT"