Install with Docker Compose
The deployment is four files from the repository: a Compose file with the server and Caddy, a Caddyfile, and two example environment files.
The Compose template pins caddy:2.11.7-alpine by image digest. Updating
the repository does not update an already running edge; apply the changed
template during the deployment’s normal update process.
Directorydeploy/compose/
- compose.yml the server and Caddy
- Caddyfile certificates on demand, for the server and each handle
- example.env for Compose: the image, the name, your email
- example.pds.env for the server: secrets and settings
-
Get the files onto the host.
Terminal window git clone --depth 1 https://github.com/linkjar/pds.gitTerminal window cd pds/deploy/compose -
Choose the image.
Every push to
mainpublishesghcr.io/linkjar/pds-serverforamd64andarm64. Resolve themaintag to a digest, and pin the digest: a digest names one build, where a tag moves.Terminal window docker buildx imagetools inspect ghcr.io/linkjar/pds-server:main --format '{{.Manifest.Digest}}'It prints
sha256:…. The image isghcr.io/linkjar/pds-server@sha256:….The repository’s
Dockerfilebuilds the server with the pinned toolchain. Run this from the repository root, on the host or on a workstation with the same architecture. The first build takes a few minutes.Terminal window docker build -t linkjar-pds:local .The image is
linkjar-pds:local. -
Write
.env. Compose reads it; the server does not.Terminal window cp example.env .envSet
PDS_IMAGEto the image,PDS_HOSTNAMEtopds.example.comandACME_EMAILtooperator@example.com. -
Write
pds.env, the server’s secrets and settings.Terminal window cp example.pds.env pds.envTerminal window chmod 600 pds.envGenerate the three secrets and paste each into its line. Keep them. Sessions and the identities of the accounts depend on them, and a lost rotation key is lost control of every account’s DID.
The JWT secret:
Terminal window openssl rand --hex 16The admin password:
Terminal window openssl rand --hex 16The PLC rotation key:
Terminal window openssl ecparam --name secp256k1 --genkey --noout --outform DER | tail --bytes=+8 | head --bytes=32 | xxd --plain --cols 32The rest of the file holds settings with their usual values: the data directory inside the container, the public PLC directory, the Bluesky AppView and relay, and
PDS_INVITE_REQUIRED=true. Environment variables explains each. -
Create the data directory. The server runs as user id 1000 in the image, so the directory belongs to that id.
Terminal window sudo install -d -o 1000 -g 1000 data -
Check the configuration without starting the server.
Terminal window docker compose run --rm pds linkjar-pds check-configIt prints
the configuration is valid. A missing or malformed variable is named instead; fix it and run the check again. -
Start the server and Caddy.
Terminal window docker compose up -dTerminal window docker compose logs pdsThe server logs JSON lines. A line with
"message":"serving"and the server’s DID means it is up. Caddy asks for the server’s certificate the first time a client connects.
Next: check that it works from outside the host.
