Deploys a Lemmy instance to a single VM with docker compose.
This repo is built for the current nu31forum setup:
- Lemmy runs on its own VM
- deployment happens through GitHub Actions
- external routing and TLS are handled by a separate
infraproject with Caddy - no local
nginxis used in this repo
The stack includes:
postgrespictrslemmylemmy-uialexandrite
Current versions:
dessalines/lemmy:0.19.18dessalines/lemmy-ui:0.19.18
- docker-compose.yml: runtime stack for the Lemmy VM
- lemmy.hjson.template: template for the Lemmy backend config
- render-lemmy-config.sh: renders
lemmy.generated.hjsonfrom environment variables - BACKUP.md: backup and restore instructions
- ops/backup: tested backup automation files for the VM
GitHub Actions deploys to the VM over SSH.
The workflow:
- builds
.envfrom GitHub secrets - renders
lemmy.generated.hjson - ensures Docker and Compose are installed on the target VM
- uploads deploy files to
/opt/lemmy - runs
docker compose pull - runs
docker compose up -d --remove-orphans
The workflow file is publish.yml.
The deploy workflow expects these repository secrets:
HOSTFORUM_SSH_PRIVATE_KEYLEMMY_HOSTNAMEPOSTGRES_PASSWORDPICTRS_API_KEYLEMMY_ADMIN_USERNAMELEMMY_ADMIN_PASSWORDLEMMY_ADMIN_EMAIL
Expected values for the current production setup:
HOST: the public SSH host of the Lemmy VMLEMMY_HOSTNAME: the public Lemmy domain, for examplelemmy.nu31.spaceFORUM_SSH_PRIVATE_KEY: private SSH key used by GitHub Actions to access the VM
The current workflow assumes:
- SSH port
2222 - SSH user
root - deploy path
/opt/lemmy
Those values are defined in publish.yml.
To render the Lemmy config locally:
export POSTGRES_PASSWORD=...
export PICTRS_API_KEY=...
export LEMMY_ADMIN_USERNAME=...
export LEMMY_ADMIN_PASSWORD=...
export LEMMY_ADMIN_EMAIL=...
export LEMMY_HOSTNAME=lemmy.example.com
sh ./render-lemmy-config.shTo start the stack locally:
docker compose up -dTo stop it:
docker compose downThis repo does not manage the public reverse proxy.
The VM exposes:
8536for Lemmy backend1234for Lemmy UI3000for Alexandrite
Your external proxy must route:
/api/*/pictrs/*/feeds/*/nodeinfo/*/.well-known/*- ActivityPub
Acceptrequests POSTrequests
to the backend service, and route normal web traffic to lemmy-ui.
If you expose Alexandrite on a separate domain such as a.lemmy.nu31.space,
route that host to port 3000. Keep LEMMY_HOSTNAME set to the main Lemmy
instance domain, for example lemmy.nu31.space.
See BACKUP.md.
At minimum, back up:
- PostgreSQL data
pictrsmedia data
pictrsstorage can grow quickly, so monitor media volume size.- This repo is intentionally Compose-based, not Swarm-based.
- If you change deploy secrets, make sure the rendered config and remote
.envstay in sync.