konnoskonnosdocs

Self-host

Self-host konnos

From bare Linux VPS to working forge in ~30 minutes. This guide is what we ran to bring up code.konnos.org.

What you need before starting

  • A Linux VPS with at least 2 GB RAM, 20 GB disk. More disk if you'll host LFS-heavy repos. konnos is happy on a small box.
  • A domain you control, e.g. code.your-domain.com. konnos needs at least one subdomain. A wildcard A record is recommended so future subdomains (matrix, docs, etc.) all work without separate DNS edits.
  • Docker 24+ and Docker Compose v2 installed on the host.
  • Ports 80 and 443 open inbound from the public internet (HTTPS + ACME challenge).
  • Port 2222 open inbound if you want git+ssh clones (ssh://git@code.your-domain.com:2222/...). Optional — HTTPS clones work without it.

Five-minute path — Docker Compose only

This is the fastest path. Everything in this repo, docker compose up, done.

git clone https://code.konnos.org/konnos/konnos.git
cd konnos
cp .env.example .env
# Edit .env and set POSTGRES_PASSWORD to a strong value:
#   openssl rand -base64 32
docker compose up -d

Visit https://your-domain.com and complete the install wizard (next section).

This works for personal use. For multi-user production, follow the production path below.

Production path — what code.konnos.org runs

The reference instance behind code.konnos.org runs on:

LayerConcern
Container orchestrationLightweight: a small VPS running Docker, with a UI on top to manage compose projects.
Reverse proxyAuto-discovers labelled containers, terminates TLS, handles HTTP→HTTPS redirect.
TLSACME (Let's Encrypt) HTTP-01 challenge. Auto-renews.
Forge runtimeThe image referenced in docker-compose.yml. Pinned to a major version.
DatabasePostgres 16, persistent volume, healthcheck-gated startup.

The docker-compose.yml in this repo is what's deployed. Mount the same compose into your reverse proxy's compose-management UI, or run it directly with docker compose up -d behind any TLS-terminating proxy you already use.

If you don't already have a reverse proxy, the path we use:

  1. Spin up a Traefik container with ACME enabled and an external Docker network (e.g., dokploy-network).
  2. Add dokploy-network to your docker-compose.yml's forgejo service so Traefik can route to it.
  3. Add Traefik labels to the forgejo service for: domain, port (3000), HTTPS entrypoint, cert resolver.

The docker-compose.yml in this repo joins dokploy-network as external: true — drop it into a Dokploy project and Dokploy injects the Traefik labels for you from the domain panel.

If you'd rather not use Dokploy, here's the minimal labels you'd add manually:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.konnos.rule=Host(`code.your-domain.com`)"
  - "traefik.http.routers.konnos.entrypoints=websecure"
  - "traefik.http.routers.konnos.tls.certresolver=letsencrypt"
  - "traefik.http.services.konnos.loadbalancer.server.port=3000"

DNS prerequisite

Before running ACME / Let's Encrypt, your domain must resolve to the VPS:

# from any machine
dig +short A code.your-domain.com
# should return your VPS public IP

If you used a wildcard *.your-domain.com A record, this works automatically. Without DNS pointing at the VPS, ACME's HTTP-01 challenge fails and you stay on a self-signed cert.

First-run install wizard

Open https://code.your-domain.com in a browser. konnos's install page renders. Fill in:

SectionFieldValue
DatabaseTypePostgreSQL
Hostpostgres:5432
Usernamekonnos (matches POSTGRES_USER in your .env)
Passwordthe value of POSTGRES_PASSWORD from your .env
Database namekonnos
SSLDisable (postgres + forgejo on same Docker network)
GeneralSite titlekonnos (lowercase)
Server domaincode.your-domain.com
SSH server domaincode.your-domain.com
SSH server port2222 (matches the host port published in the compose)
HTTP listen port3000
Application URLhttps://code.your-domain.com/
Optional → Server settingsDisable Gravatar
Disable Open Registration
Require Sign-In to View Pagesleave unchecked (Dokploy + auto-deploy needs unauthenticated git clone)
Optional → AdministratorUsernameyour handle
Emaila real address (used for ACME notifications, password reset)
Passwordstrong, save in password manager

Click Install. The forge restarts and lands you on the dashboard signed in as the admin you just created.

Email setup (later)

konnos can email password resets, notification emails, etc. Set up SMTP via your preferred provider — for the konnos.org reference instance we use Resend, but anything that speaks SMTP works (Postmark, SendGrid, even Gmail relay).

Add to your .env:

SMTP_HOST=smtp.your-provider.com
SMTP_PORT=587
SMTP_USER=
SMTP_PASSWORD=
SMTP_FROM=admin@your-domain.com

Then set the corresponding FORGEJO__mailer__* env vars in the compose's forgejo service environment block.

Backups

The two volumes that matter:

forgejo_data   →  /data — repos, LFS, attachments, config
postgres_data  →  /var/lib/postgresql/data — issues, PRs, users, settings

Minimum viable backup: nightly pg_dump of the postgres database + a tar snapshot of forgejo_data. Push both to off-site storage (S3-compatible bucket, rsync to another server, etc.). See hardening.md for a worked example.

Don't skip backups. If the VPS dies, the only thing standing between you and total data loss is your most recent backup.

What now?

Once konnos is up: