Skip to content

Without Docker

Ingle is a single static binary with an embedded database engine, so Docker is optional. This guide runs it as a hardened systemd service on Debian, Ubuntu or Raspberry Pi OS, with Caddy installed alongside for HTTPS.

You end up with:

  • Ingle running as its own ingle user, starting at boot and restarting if it stops.
  • Its data in /var/lib/ingle, the only place it can write.
  • Settings in /etc/ingle/ingle.env.
  • HTTPS from Caddy, with a real certificate and nothing opened to the internet.
  • A backup every night, with the last 14 kept.
  • Ingle v0.2.1 or later. That’s the first release with the service files in deploy/systemd/; v0.2.0 doesn’t have them.
  • A 64-bit Linux machine with systemd: Intel/AMD (amd64) or ARM (arm64, such as a Raspberry Pi 4 or 5 on 64-bit Raspberry Pi OS). 32-bit Raspberry Pi OS isn’t supported.
  • For HTTPS, the same domain and Cloudflare setup as the Docker guide: the DNS record and an API token.

Download a release for your machine, check it, and install the binary:

Terminal window
VERSION=v0.2.1 # the latest release
ARCH=$(dpkg --print-architecture) # amd64 or arm64
curl -fsSLO https://github.com/lukeskelhorn/ingle/releases/download/$VERSION/ingle_${VERSION}_linux_${ARCH}.tar.gz
curl -fsSLO https://github.com/lukeskelhorn/ingle/releases/download/$VERSION/checksums.txt
sha256sum --check --ignore-missing checksums.txt
tar -xzf ingle_${VERSION}_linux_${ARCH}.tar.gz
cd ingle_${VERSION}_linux_${ARCH}
sudo install -m 0755 ingle /usr/local/bin/ingle
ingle version

Check the releases page for the latest version. Stay in this folder for the next steps: it has the service files in deploy/systemd/.

Terminal window
sudo useradd --system --home-dir /var/lib/ingle --shell /usr/sbin/nologin ingle
sudo install -d -m 0755 /etc/ingle
sudo install -m 0640 -g ingle deploy/systemd/ingle.env.example /etc/ingle/ingle.env

The defaults in /etc/ingle/ingle.env suit Caddy on the same machine: Ingle listens on 127.0.0.1:8080 only, and believes Caddy’s X-Forwarded-For. Edit it to change the timezone, backups or anything else in Configuration.

Terminal window
sudo cp deploy/systemd/ingle.service deploy/systemd/ingle-backup.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now ingle
systemctl status ingle
curl http://127.0.0.1:8080/healthz # ok v0.2.1

The unit is locked down: Ingle can only write /var/lib/ingle, can’t see home directories, and has no extra privileges. systemd-analyze security ingle rates it 1.2, “OK”.

To change the unit, use sudo systemctl edit ingle rather than editing the file, so an update doesn’t overwrite your changes.

Install Caddy from its own apt repository:

Terminal window
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl gnupg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install -y caddy

The packaged Caddy can’t use Cloudflare DNS, so swap in a build with the caddy-dns/cloudflare plugin. The diversion keeps it in place when apt updates Caddy:

Terminal window
curl -fsSL -o caddy "https://caddyserver.com/api/download?os=linux&arch=${ARCH}&p=github.com/caddy-dns/cloudflare"
chmod +x caddy
sudo dpkg-divert --divert /usr/bin/caddy.default --rename /usr/bin/caddy
sudo mv caddy /usr/bin/caddy.custom
sudo update-alternatives --install /usr/bin/caddy caddy /usr/bin/caddy.default 10
sudo update-alternatives --install /usr/bin/caddy caddy /usr/bin/caddy.custom 50
caddy list-modules | grep cloudflare # dns.providers.cloudflare

Give Caddy the Cloudflare token, readable only by root:

Terminal window
sudo install -m 0600 /dev/null /etc/caddy/cloudflare.env
sudo sh -c 'echo CLOUDFLARE_API_TOKEN=your-token >> /etc/caddy/cloudflare.env'
sudo mkdir -p /etc/systemd/system/caddy.service.d
printf '[Service]\nEnvironmentFile=/etc/caddy/cloudflare.env\n' | sudo tee /etc/systemd/system/caddy.service.d/cloudflare.conf

Then the Caddyfile. Copy the one from deploy/systemd/ and put your address on its first line:

Terminal window
sudo cp deploy/systemd/Caddyfile /etc/caddy/Caddyfile
sudo sed -i 's/ingle.home.example.com/ingle.home.yourdomain.com/' /etc/caddy/Caddyfile
sudo systemctl daemon-reload
sudo systemctl restart caddy
journalctl -u caddy -f # wait for "certificate obtained successfully"

Open your address on your phone or laptop, and follow the first-run setup.

Ingle backs itself up every night into /var/lib/ingle/backups. See Backups and restore for taking one now, keeping them somewhere else, and restoring.

Take a backup, swap the binary, and restart:

Terminal window
sudo systemctl start ingle-backup
# download and unpack the new release, as in step 1, then:
sudo install -m 0755 ingle /usr/local/bin/ingle
sudo systemctl restart ingle

Database changes are applied when Ingle starts. Read the release’s Upgrade notes first: see Upgrades. If the release changes the files in deploy/systemd/, copy them over again and run sudo systemctl daemon-reload.

Set INGLE_PHOTOS_DIR in /etc/ingle/ingle.env, for example /mnt/nas/photos, then sudo systemctl restart ingle. Ingle can read anything outside home directories, so most mounts work as they are. The ingle user needs read access to the files.

A folder under /home is hidden from the service. Allow it with sudo systemctl edit ingle:

[Service]
ProtectHome=tmpfs
BindReadOnlyPaths=/home/sam/Pictures/family

ingle healthcheck asks the running server whether its database answers, and exits non-zero if not. To run it every 5 minutes:

Terminal window
sudo cp deploy/systemd/ingle-healthcheck.service deploy/systemd/ingle-healthcheck.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now ingle-healthcheck.timer

A failure shows in systemctl --failed and the journal. To be told about it, add an OnFailure= unit with sudo systemctl edit ingle-healthcheck, or point your monitoring at https://your-address/healthz.

  • Logs: journalctl -u ingle -f.
  • It won’t start: systemctl status ingle shows the error. A bad setting names the variable, for example INGLE_BACKUP_AT "3am": want HH:MM.
  • “address already in use”: something else is on port 8080. Set INGLE_ADDR=127.0.0.1:8090 (say) in /etc/ingle/ingle.env, and change the port in the Caddyfile to match.
  • Backups to another folder fail with “permission denied”: add ReadWritePaths= for it with sudo systemctl edit ingle, and sudo chown ingle:ingle the folder.
  • Port 80 or 443 directly, without a proxy: Ingle has no privileges, so it can’t bind ports below 1024. Add AmbientCapabilities=CAP_NET_BIND_SERVICE and CapabilityBoundingSet=CAP_NET_BIND_SERVICE with sudo systemctl edit ingle, or use a proxy.

More in Troubleshooting.