TabSlate LogoTabSlateDocs
Self-hosting

Docker Compose Deployment

The documented way to run TabSlate Server — the official image behind a Caddy reverse proxy.

What the bundled Compose file runs

TabSlate Server's docker-compose.yml defines exactly two services:

  • api — the official server image, ghcr.io/tabslate-dev/tabslate-server:latest, built and published to the GitHub Container Registry. It is not published to the host: no port mapping puts it on your machine's network directly, only expose: ["8080"] inside the Compose network.
  • caddy — a Caddy reverse proxy that terminates TLS in front of api and obtains/renews a certificate automatically via Let's Encrypt, publishing ports 80 and 443 to the host.

There is no bundled PostgreSQL (or Redis) container. api connects out to whatever DATABASE_URL in your .env points at — an external Postgres instance you provide, whether that's a managed provider or one you run yourself.

Because api is never reachable over plaintext HTTP from outside the Compose network, this setup requires a domain name pointed at the server so Caddy can issue a certificate for it. If you have no domain and only need the server reachable from a private network, put your own TLS-terminating reverse proxy in front of api instead of using the bundled Caddy service — and still never publish port 8080 directly to the public internet.

Deploy

  1. Point a DNS A/AAAA record for your domain at this server.

  2. Download docker-compose.yml, Caddyfile, and .env.example:

    curl -O https://raw.githubusercontent.com/TabSlate-dev/TabSlate-server/main/docker-compose.yml
    curl -O https://raw.githubusercontent.com/TabSlate-dev/TabSlate-server/main/Caddyfile
    curl -o .env https://raw.githubusercontent.com/TabSlate-dev/TabSlate-server/main/.env.example
  3. Edit .env: set DOMAIN to that hostname, DATABASE_URL to your Postgres connection string, and JWT_SECRET to a generated secret (see Requirements). Add any optional variables you need from Environment Configuration.

  4. Start the stack:

    docker compose up -d

    (docker-compose up -d also works if you're on the older standalone Compose binary instead of the docker compose plugin.)

You can check the shape of your edited docker-compose.yml without starting anything using:

docker compose config

Checking it came up

docker compose ps
docker compose logs api
docker compose logs caddy

docker compose logs -f api follows the API service's logs live; add --tail 100 to either command to limit output to the most recent lines. See Troubleshooting for what to look for if the stack doesn't come up cleanly.

Last updated on

On this page