Skip to content

Run with Docker

The Docker image includes Quipthread, the dashboard, and its migration tools. You do not need to clone the repository or install Go, Bun, or Atlas.

You need Docker on a Linux AMD64 or ARM64 server. Use Docker Compose for an ongoing deployment, or docker run for a single container. Choose one of the two examples below.

Create an empty folder and save this as .env:

JWT_SECRET=replace-with-a-generated-secret
BASE_URL=http://localhost:8080
ALLOWED_ORIGINS=http://localhost:8080
DATABASE_URL=/data/db.sqlite
PORT=8080
TRUST_PROXY=false
GITHUB_CLIENT_ID=replace-with-your-client-id
GITHUB_CLIENT_SECRET=replace-with-your-client-secret

Generate JWT_SECRET with openssl rand -hex 32, then protect the file with chmod 600 .env.

Configure GitHub or Google sign-in, or use email sign-in with SMTP instead. For the GitHub example above, register http://localhost:8080/auth/github/callback as the callback URL.

  • BASE_URL is the address where you open Quipthread.
  • ALLOWED_ORIGINS lists the websites that embed your comments. Separate multiple origins with commas, such as https://example.com,https://www.example.com.

For a public deployment, use your HTTPS address and publisher origins as described below. Other settings are optional; see the environment reference.

Save this as compose.yml beside .env:

services:
app:
image: ghcr.io/quipthread/quipthread:0.1.2
restart: unless-stopped
env_file: .env
ports:
- "127.0.0.1:8080:8080"
volumes:
- quipthread-data:/data
volumes:
quipthread-data:

Start it:

docker compose up -d

Use this instead of the Compose example:

docker run -d \
--name quipthread \
--restart unless-stopped \
--env-file .env \
-p 127.0.0.1:8080:8080 \
-v quipthread-data:/data \
ghcr.io/quipthread/quipthread:0.1.2

Both examples keep the database in a persistent volume and bind port 8080 to the server’s loopback interface. Open http://localhost:8080/login on that machine. On a remote server, configure HTTPS before opening it in your browser.

The first account receives admin access. Create it before sharing the instance.

If you already use nginx, Caddy, or another reverse proxy on the host, forward your Quipthread domain to 127.0.0.1:8080.

Update .env:

BASE_URL=https://comments.example.com
ALLOWED_ORIGINS=https://publisher.example.com
TRUST_PROXY=true

Update your OAuth callback to use the same HTTPS address, then recreate the app. Only enable TRUST_PROXY when requests reach the app through your trusted proxy. Keep its port private.

With Compose, save this as compose.https.yml:

services:
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
volumes:
caddy-data:
caddy-config:

Save this as Caddyfile, using your domain:

comments.example.com {
reverse_proxy app:8080
}

Point the domain’s DNS records to your server and allow inbound ports 80 and 443. Then run:

docker compose -f compose.yml -f compose.https.yml up -d

Caddy obtains and renews HTTPS certificates automatically. Use both -f options for future commands if you added this HTTPS file.

Check that /health reports status: ok and database: ok:

curl --fail https://comments.example.com/health

For local testing, use http://localhost:8080/health. If startup fails, inspect docker compose logs --tail=100 app or docker logs quipthread.

Sign in, create a site, and copy its snippet from the dashboard. See the embed guide for details.

Set up automatic backups and test a restore before relying on the instance. The data volume protects against container replacement, not server loss.

Read the release notes, back up the database, and change the image tag to the version you want. Then run:

docker compose pull
docker compose up -d

For docker run, stop and remove the old container, then repeat the command with the new tag and the same data volume.

Startup applies database migrations automatically. Do not use docker compose down -v to update: it deletes your database volume. Keep a pre-upgrade backup in case you need to roll back.

To build your own image instead, use the source-build guide.