Deploy to a server
This guide sets up Playdex on one Linux server (a small VPS is enough) with automatic HTTPS from Caddy.
You need:
- A server with Docker and Git
- Two DNS names pointing at the server, e.g.
playdex.example.comandadmin.playdex.example.com - Ports 80 and 443 open
1. Generate your configuration
Section titled “1. Generate your configuration”Fill in the form. The files below update as you type. Everything is generated in your browser; secrets never leave this page.
2. Deploy
Section titled “2. Deploy”-
Clone Playdex on the server and add your files
Terminal window git clone https://github.com/ivankaizer/playdex.gitcd playdexSave
docker-compose.prod.yml,.envandCaddyfilefrom the builder into this folder. Keep.envprivate; it’s already in.gitignore. -
Build and start
Terminal window docker compose -f docker-compose.prod.yml up -d --buildOn start, the API applies database migrations, then reports healthy. Admin waits for the API before it starts.
-
Check it’s healthy
Terminal window curl -s https://playdex.example.com/api/ # → "Ok"docker compose -f docker-compose.prod.yml ps # api should be (healthy) -
Create your admin account
Playdex has no public sign-up, so every account is created by an operator. Save
create-admin.sqlfrom the builder and run:Terminal window docker compose -f docker-compose.prod.yml exec -T db \psql -U playdex -d playdex < create-admin.sqlSign in at
https://admin.playdex.example.com. The same email and password also work in the Web app. -
Invite people. See Users & admins.
Updating
Section titled “Updating”git pulldocker compose -f docker-compose.prod.yml up -d --buildMigrations run automatically when the new API starts. They’re serialized with a Postgres advisory lock, so running several API replicas is safe. Admin never migrates the database. That’s why it waits for a healthy API.
Rolling back means checking out the previous commit and rebuilding. Migrations aren’t reversed automatically, so read the release’s changes before going back across a schema change.
Backups
Section titled “Backups”All state is in Postgres (plus Apprise’s chat config, which re-creates itself):
docker compose -f docker-compose.prod.yml exec -T db pg_dump -U playdex playdex | gzip > playdex-$(date +%F).sql.gzWithout Docker Compose
Section titled “Without Docker Compose”Each app ships a Dockerfile (src/Api, src/Web, src/Admin), so any container platform works. Mind these details:
- API: set
ASPNETCORE_URLS=http://+:3000. The image health-checks port 3000 but doesn’t set it itself. Health endpoints:/health/live,/health/ready(database + migrations). - Web: nginx on port 5056. It calls
<its own origin>/api/unless you setPLAYDEX_API_URL(ending in/api/). It doesn’t proxy/apiitself, so your ingress must. - Admin: port 3100, needs only
DATABASE_URL. Health:/health/live,/health/ready. Blazor Server uses WebSockets, so make sure your proxy allows them. - Behind a proxy: set
ASPNETCORE_FORWARDEDHEADERS_ENABLED=trueon API and Admin. - Least privilege: in production, give Admin its own Postgres role with access to app tables only, no DDL. The API role should be the only one that owns the schema.