Documentation

Running Steadlink

How to install, configure, back up and upgrade the self-hosted short link service. The software is MIT-licensed; these pages cover the operator's side of it.

Quickstart

Five minutes from a clean machine to a working link.

git clone https://github.com/arjav3003jain/steadlink
cd steadlink
cp .env.example .env
docker compose up -d

The application runs the migrations on start, so the first boot takes a few seconds longer. The first account you create becomes the owner of the first workspace.

Requirements: Docker and Docker Compose, 2 GB of RAM, 40 GB of disk, and a domain you control if you want short links on your own name.

Environment

Every variable the application reads. The full table, with defaults, is in .env.example.

  • DATABASE_URL — the URL the application connects as. Must be the unprivileged role.
  • DATABASE_MIGRATION_URL — the URL the migrations run as. Must be a role that can create tables and roles. If it is unset, the application tries to migrate as the application role and fails.
  • BETTER_AUTH_SECRET — a long random string. Generate one with openssl rand -base64 32.
  • APP_URL — the public URL of the deployment, with scheme. Used in emails, webhooks and the redirect targets.
  • SMTP_* — optional. Without them, sign-in links are written to the log instead of emailed.

If APP_URL is wrong, sign-in links point at the wrong host and every email is broken. It is the single most common mistake on a first install.

Backup and restore

The whole application is one PostgreSQL database. Back it up the way you back up any database.

pg_dump -Fc -d steadlink > steadlink-2026-10-24.dump
pg_restore -d steadlink --clean --if-exists steadlink-2026-10-24.dump

Back up before every upgrade. The migrations are forward-only; a failed upgrade is recovered from a dump, not from a rollback script.

Files (QR logos, uploaded images) live in the database as well, so a database dump is a complete backup. There is no separate storage to copy.

Upgrading

docker compose pull
docker compose up -d

Migrations run on start.

Troubleshooting

  • Migrations fail on start. Check that DATABASE_MIGRATION_URL points at a role that can create tables and roles.
  • Sign-in links go somewhere else. Check APP_URL.
  • No email. Configure SMTP_*, or accept that the log is the outbox.
  • The worker is not running. The worker reads the same database; confirm the compose service is up.

The API

A REST API at /api/v4, with personal access tokens and scopes. Scoped tokens and signed webhooks are the supported entry points for anything that is not a browser.

Webhooks

Engagement and link events, signed with a per-webhook secret, delivered by a worker with backoff. The queue is visible; delivery is not silent.

The short version. Two minutes of setup, a domain you own, one database, no meter, no ads. That is the whole product.