Get started

Run it on a server

This page takes Sideporch from an installed program to a chat people can reach: a service that starts with the server, the first account, and HTTPS.

Start it as a service

With the install script, run Sideporch with systemd. Create a user for it:

sudo useradd --system --home-dir /var/lib/sideporch --shell /usr/sbin/nologin sideporch

Save this as /etc/systemd/system/sideporch.service, with your own address in --public-url:

[Unit]
Description=Sideporch team chat
After=network-online.target
Wants=network-online.target

[Service]
User=sideporch
Group=sideporch
ExecStart=/usr/local/bin/sideporch --data /var/lib/sideporch --public-url https://chat.example.com --require-setup-link
StateDirectory=sideporch
StateDirectoryMode=0700
Restart=on-failure
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Then start it, and have it start with the server:

sudo systemctl daemon-reload
sudo systemctl enable --now sideporch
journalctl -u sideporch -f    # its log

Sideporch listens on 127.0.0.1:8080, so only the server itself reaches it until you add HTTPS.

Create the admin account

While no account exists, the first visitor creates the admin account. On a server others can reach before you set it up, lock setup in one of two ways:

  • A setup code you choose (new in 0.7.0), easiest where there’s no shell, like Docker, Fly.io or Kubernetes. Generate one, keep it in your password manager, and start Sideporch with it; the setup page asks for it:

    openssl rand -base64 24    # a code nobody can guess
    docker run -d -p 8080:8080 -v sideporch:/data -e SIDEPORCH_SETUP_CODE='…' ghcr.io/niklas-heer/sideporch

    It needs at least 16 characters. Wrong codes are limited per address, and the code does nothing once the first account exists, so you can leave it set.

  • A one-time link with --require-setup-link (as in the service above), which stays out of service and container logs. Get it on the server:

    sudo -u sideporch sideporch setup-link --data /var/lib/sideporch
    docker exec sideporch /sideporch setup-link    # with Docker

Behind Cloudflare Access, setup also needs Access, and without a code, whoever Access lets in first becomes the admin.

Open the link (or enter the code) and create your account, with a passkey where your browser offers one. Then invite everyone else from People. To let people join without an invite, open sign-up under Admin → Community; see Sign-up and trust.

Options

Every option can also be set with an environment variable.

OptionEnvironment variableDefaultMeaning
--listenSIDEPORCH_LISTEN127.0.0.1:8080Address and port to listen on.
--dataSIDEPORCH_DATAsideporch-dataDirectory for everything Sideporch keeps. Back it up to back up everything.
--public-urlSIDEPORCH_PUBLIC_URLtaken from each requestThe URL people use, such as https://chat.example.com, for invite and webhook links. An https:// URL also makes cookies secure.
--setup-codeSIDEPORCH_SETUP_CODEnoneA secret of at least 16 characters that the setup page asks for before anyone can create the first account. Takes the place of --require-setup-link. New in 0.7.0.
--require-setup-linkSIDEPORCH_REQUIRE_SETUP_LINKoffRequire the one-time link from sideporch setup-link to create the first account.
--client-ip-headerSIDEPORCH_CLIENT_IP_HEADERnone: the connection’s addressBehind a reverse proxy, the header it puts visitors’ addresses in, such as X-Forwarded-For or Fly-Client-IP. Sign-in limits and bans use it. Only set it when every request comes through that proxy, or anyone could claim any address. New in 0.6.0.
--cloudflare-access-teamSIDEPORCH_CLOUDFLARE_ACCESS_TEAMnoneSign people in through Cloudflare Access: your team domain, such as myteam.cloudflareaccess.com. Set it together with the audience tag. New in 0.7.0.
--cloudflare-access-audSIDEPORCH_CLOUDFLARE_ACCESS_AUDnoneThe audience (AUD) tag of the Cloudflare Access application in front of the server. New in 0.7.0.
--cloudflare-access-requiredSIDEPORCH_CLOUDFLARE_ACCESS_REQUIREDoffRefuse pages to requests that didn’t come through Cloudflare Access; webhooks, other servers, MCP and /healthz stay open. New in 0.7.0.
--update-checkSIDEPORCH_UPDATE_CHECKtrueAsk GitHub for new releases every six hours; false keeps Sideporch from contacting GitHub. See Update. New in 0.5.0.
SIDEPORCH_SECRET_KEYsecret.key in the data directoryA passphrase to encrypt automation secrets with, instead of the key file.
RUST_LOGinfoHow much to log: warn, info, debug.

Four commands besides running the server:

  • sideporch setup-link prints the link for creating the first account.
  • sideporch reset-link USERNAME prints a one-time link for choosing a new password, for when someone, like the only admin, lost their password; with --reset-sign-in it also removes their passkeys, authenticator app and MCP tokens and signs them out everywhere, for when those are lost. New in 0.7.0.
  • sideporch restore ARCHIVE unpacks a backup. Stop the server first.
  • sideporch update installs the newest release in place of the program; see Update. New in 0.5.0.

Put it behind HTTPS

Browsers only send push notifications, install Sideporch as an app and use passkeys over HTTPS, so put a reverse proxy in front of it. Choose the name people will keep using before they make passkeys: a passkey belongs to its name, so moving to another one means signing in another way and adding new ones (an admin who has no other way in can use sideporch reset-link --reset-sign-in). Live updates use a WebSocket at /ws, which the proxy has to pass on.

With Caddy, which gets certificates by itself, this is the whole configuration:

chat.example.com {
	reverse_proxy 127.0.0.1:8080
}

With nginx:

server {
    listen 443 ssl;
    server_name chat.example.com;
    # ssl_certificate and ssl_certificate_key, for example from certbot

    client_max_body_size 0;   # Sideporch limits uploads itself; Slack exports can be large

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 1h;
    }
}

Set --public-url to the address people use. Without it, Sideporch builds links from the Host (or X-Forwarded-Host) and X-Forwarded-Proto headers the proxy passes on.

Set --client-ip-header X-Forwarded-For too, so Sideporch sees visitors’ addresses instead of the proxy’s; otherwise sign-in limits and bans would treat everyone as one visitor. Caddy sets that header by itself; with nginx, add proxy_set_header X-Forwarded-For $remote_addr;.

Check that it runs

/healthz answers ok while Sideporch runs, for monitors and container health checks:

curl -fsS http://127.0.0.1:8080/healthz

Next: keep it up to date, and set up backups.