Skip to content

Self-host guide

Run it on your own server.

The self-hosted build is the same app as the hosted one, in one Docker container. Everything it stores lives in a SQLite file and an uploads folder on a single volume. Put it on the internet under your own domain, or keep it on the dropzone WiFi.

Runtime
Bun in Docker
Database
SQLite file
Port
3000
Price
Free

What you need

  • Any 64-bit machine with Docker: a mini PC in the manifest office, a NAS, or a Raspberry Pi 4 or 5. Put it and the router on a UPS.
  • A friend who is comfortable with a terminal, the router's admin page and DNS settings, for about an hour.
  • A domain only if people outside the building need it: online tandem bookings, jumpers at home, and online payments once they ship. Manifest, check-in, waivers and the hangar display work on the dropzone WiFi alone, even when the internet line is down.

Install

You don’t need the source code: Log-Book ships as a ready-made Docker image for regular PCs and for ARM boards like the Raspberry Pi 4 or 5 (64-bit OS). With Docker installed, run the installer. It asks how people will reach the server and its name, creates the secrets, starts everything and prints the address.

Install
curl -fsSL https://log-book.app/install.sh | bash

Run it again any time: it keeps your settings and secrets. Prefer to do it by hand? Three steps: download the compose file and settings, edit them, start.

Manual install
mkdir log-book && cd log-book
RAW=https://raw.githubusercontent.com/MarthinusBosman/log-book/main
# 1. download the compose file, settings template and front-end configs
curl -fsSLO $RAW/docker-compose.yml
curl -fsSL $RAW/.env.example -o .env
mkdir -p deploy && for f in Caddyfile.public Caddyfile.lan Caddyfile.lan-http; do
  curl -fsSL $RAW/deploy/$f -o deploy/$f; done
# 2. edit .env: ORIGIN=…, SECRETS_KEY= (openssl rand -hex 32),
#    COMPOSE_PROFILES=https | tunnel | lan | lan-http
nano .env
# 3. start (pulls the image)
docker compose up -d

Whoever creates the dropzone becomes its owner. Add your aircraft and pricelist, then give your staff their roles from Settings → Members & roles.

How people reach it

Pick one front end. The installer asks; by hand, set COMPOSE_PROFILES=<name> in .env or use docker compose --profile <name> up -d.

Own domain

Anyone, anywhere. A domain, a public IP, ports 80 and 443 forwarded.

--profile https

Cloudflare Tunnel

Anyone, anywhere. A domain on Cloudflare. No static IP, works behind CGNAT.

--profile tunnel

WiFi only, HTTPS

Devices on your network. Nothing to buy. Each staff device trusts a certificate once.

--profile lan

WiFi only, HTTP

Devices on your network. Nothing. Use it on a WiFi with a password.

--profile lan-http

Custom domain

Your own domain, e.g. manifest.your-dz.co.za

  1. 1 Register a domain (a .co.za costs roughly R50–R150 a year) or add a subdomain to the dropzone website’s domain.
  2. 2 In the DNS settings add an A record (and AAAA for IPv6) for "manifest" pointing at your public IP. Use a CNAME to a dynamic-DNS name if the IP changes.
  3. 3 Give the server a fixed LAN IP (DHCP reservation) and forward ports 80 and 443 on the router to it.
  4. 4 Fill in .env and start the https profile. Caddy gets and renews the Let’s Encrypt certificate on its own.
Own domain
# .env
DOMAIN=manifest.your-dz.co.za
ORIGIN=https://manifest.your-dz.co.za
PROTOCOL_HEADER=x-forwarded-proto
HOST_HEADER=x-forwarded-host

docker compose --profile https up -d

No static IP, or behind CGNAT: Cloudflare Tunnel

Most LTE/5G and many fibre lines have no public IP to forward ports to. A tunnel connects outwards from the server instead, so nothing on the router changes.

  1. 1 Add your domain to a free Cloudflare account (you switch its nameservers to Cloudflare).
  2. 2 Zero Trust → Networks → Tunnels → Create a tunnel → Cloudflared. Cloudflare asks for a card when you first activate Zero Trust, even on the free plan. Copy the token.
  3. 3 Add a public hostname: manifest.your-dz.co.za, service HTTP, URL app:3000.
  4. 4 Put the token in .env and start the tunnel profile. Cloudflare handles HTTPS.
Cloudflare Tunnel
# .env
TUNNEL_TOKEN=eyJ…
ORIGIN=https://manifest.your-dz.co.za
ADDRESS_HEADER=cf-connecting-ip

docker compose --profile tunnel up -d

Free names

  • DuckDNS gives you a free name like mydz.duckdns.org. Use it like your own domain; it needs a public IP, so not behind CGNAT.
  • Cloudflare Tunnel is free, but needs a domain you own.
  • We don’t offer subdomains on log-book.app for self-hosted servers. That may come later; nothing is scheduled.

Dropzone WiFi only

No domain, nothing on the internet. The server sits in the office and only devices on your network can open it.

  1. 1 Give the server a fixed address with a DHCP reservation on the router, e.g. 192.168.1.10.
  2. 2 Pick a name. Best: a local DNS entry such as logbook.internal on the router, Pi-hole, AdGuard Home or OpenWrt. Or no setup at all: name the server "logbook" and use logbook.local (mDNS; reliable on iPhone, Mac and Windows, patchy on Android before 13 and on TVs). The plain IP always works as a fallback.
  3. 3 Choose HTTPS or plain HTTP. HTTPS uses a certificate Caddy makes itself: each staff device installs it once from http://192.168.1.10/ca.crt. Plain HTTP needs nothing, but traffic isn’t encrypted, so only use it on a WiFi with a password.
  4. 4 Leave ORIGIN empty so the app answers on every name you listed, and start the lan or lan-http profile.
Local DNS name
# Pi-hole: Local DNS → DNS Records
# AdGuard Home: Filters → DNS rewrites
# OpenWrt / dnsmasq:
address=/logbook.internal/192.168.1.10
WiFi only
# .env
LAN_HOSTS=logbook.internal, logbook.local, 192.168.1.10
ORIGIN=
PROTOCOL_HEADER=x-forwarded-proto
HOST_HEADER=x-forwarded-host

docker compose --profile lan up -d       # HTTPS, local certificate
docker compose --profile lan-http up -d  # or: plain HTTP on port 80

Logins work over plain HTTP. What browsers block without HTTPS: “Near me” on the Dropzones page, one-tap copy buttons and the share sheet. Signatures, waivers, photo uploads and the hangar display all work. Jumpers reach the server only while they’re on your WiFi.

Payments

Your dropzone is the merchant. Payments go to your own PayFast or Stripe account and settle straight into your bank account; Log-Book never holds the money.

Works today

  • Pay at manifest: staff mark slots paid as cash, card machine or EFT from the load.
  • Wallet top-ups: the jumper pays at the desk and staff press Add funds on the jumper’s page.
  • Jumpers pay their slots from the wallet, and staff pay can go into wallets.
  • Tandem bookings without online payment: customers pay at check-in.

Online card payments Coming soon

PayFast and Stripe aren’t live yet: you can save your details now, but nothing is charged and customers don’t see the option. To be ready, set SECRETS_KEY first, then:

  1. 1 South Africa: open a PayFast merchant account (payfast.io) in the dropzone’s name. For testing, register a sandbox account at sandbox.payfast.co.za.
  2. 2 Copy the Merchant ID and Merchant Key from the PayFast dashboard (Settings → Developer Settings) and set a Salt Passphrase there.
  3. 3 Paste all three into Settings → Payments → PayFast. Keep Test mode on for sandbox details, off for live ones.
  4. 4 Outside South Africa: Stripe. The settings page stores country, currency and a connected account ID; connecting your Stripe account from the page is planned.

When online payments ship, the server will need a public address (own domain or tunnel) so the provider can confirm payments.

Hangar TV

Open Display in the app, or create a Public display link from its menu so the TV doesn’t need a staff login. The board refreshes every 10 seconds and keeps going when the internet is down, as long as the TV is on your network. On a Raspberry Pi or mini PC behind the TV:

Kiosk browser
chromium --kiosk --noerrdialogs \
  'http://logbook.internal/dz/your-dz/display?token=…'

On a smart TV or streaming stick, use a kiosk browser app with “start on boot”, and the IP or a router DNS name rather than .local.

Configuration

Everything goes in .env next to the compose file.

ORIGIN
The URL people use, e.g. https://manifest.your-dz.co.za. Form posts from any other address are rejected. Leave it empty (ORIGIN=) on a LAN that answers on several names.
SECRETS_KEY
Any long random string. Encrypts the payment-provider keys you save in settings. Set it before you add PayFast and keep a copy with your backups.
PORT, APP_BIND
Host port for the app (3000). Set APP_BIND=127.0.0.1 when a front end is in use.
DOMAIN
Own-domain mode: the name Caddy gets a certificate for.
TUNNEL_TOKEN
Cloudflare Tunnel mode: the token from the Cloudflare dashboard.
LAN_HOSTS
WiFi-only HTTPS mode: every name and IP people may type, comma separated.
PROTOCOL_HEADER, HOST_HEADER
x-forwarded-proto and x-forwarded-host behind any of the front ends.
RESEND_API_KEY, EMAIL_FROM
Optional: send password resets, invites and booking confirmations through Resend from your own verified domain. Unset = emails only appear in the log.
FEDERATION_GLOBAL_URL
Origin of the hosted Log-Book instance, for linking jumper accounts.
FEDERATION_CLIENT_ID, FEDERATION_CLIENT_SECRET
Issued when you register your server (see below).

Backups

Everything is in /data: the database and uploaded files such as waiver PDFs and signatures. The backup script takes a consistent snapshot while the app runs; copy it somewhere off the machine. Keep your SECRETS_KEY with it.

Nightly backup
docker compose exec app bun scripts/backup.ts
docker compose cp app:/data/backups ./backups
docker compose cp app:/data/uploads ./backups/uploads

You can also download a full dropzone export as JSON from Export inside the app. It's handy as a second copy, or for moving to the hosted version later.

Updates

Take a backup, then pull the new image. Database migrations run when it starts, so keep that backup until you’re happy with the new version. Downtime is the few seconds the container takes to restart. To upgrade only when you choose, pin a version such as LOG_BOOK_VERSION=0.1.0 in .env.

Update
cd log-book
docker compose exec app bun scripts/backup.ts   # backup first
docker compose pull && docker compose up -d     # migrations run on start

# optional, in .env: stay on a release line
LOG_BOOK_VERSION=0.1

The full guide

Step-by-step details (certificate install per device, router DNS examples, CGNAT checks, every environment variable) are in the full self-hosting guide. Ready-made Caddy configs live in deploy/.

Log-Book is free software under the AGPL-3.0-or-later licence; the source code is public. Changed it and running it for others? The licence asks you to share your changes with those users too.

Rather not run a server?

The hosted version is the same app, and you can move your data across with an export later.