Skip to content

Installing Lantern Home

How to run Lantern at home with Docker Compose, keep it up to date, and keep its data safe. GITEA_HOST/OWNER stands for wherever Lantern’s repository and container images are published.

  • A Linux machine with Docker (Engine and the Compose plugin), on amd64. A small home server or a NAS that runs containers is enough: idle, the web server, worker, and database use about 400 MiB together (docs/perf.md), plus room for photos.
  • HTTPS. Offline mode, notifications, and keeping a display’s screen awake only work over HTTPS (SET-5), and Lantern’s sign-in cookies need it. Put a reverse proxy with a certificate in front of Lantern, or use Tailscale: Reverse proxy and HTTPS. Never publish Lantern’s own port to the internet.
  • A name that the household’s phones, computers, and displays reach it by, such as lantern.example.com or a Tailscale name.
  1. Get the release’s files into a folder of their own, for the version you’re installing (1.0.0 here):

    Terminal window
    mkdir lantern && cd lantern
    curl -fLO https://GITEA_HOST/OWNER/lantern/raw/tag/v1.0.0/docker-compose.yml
    curl -fL -o .env https://GITEA_HOST/OWNER/lantern/raw/tag/v1.0.0/.env.example
  2. Fill in .env. Every setting is explained in the file. The ones to set:

    SettingWhat to put
    APP_BASE_URLThe HTTPS address people will use, such as https://lantern.example.com
    APP_SECRET_KEYThe output of openssl rand -hex 32. Keep it with your backups: without it, saved connections (calendar links, the mailbox, Immich, AI) can’t be read
    POSTGRES_PASSWORDThe output of openssl rand -hex 32
    APP_IMAGEGITEA_HOST/OWNER/lantern:1.0.0: the version, never latest, so upgrades are deliberate
    APP_PUBLISH127.0.0.1:3000 when the reverse proxy runs on the same machine, so the plain-HTTP port isn’t reachable from the network
    APP_TRUST_PROXYThe reverse proxy’s address or network, so sign-in limits see each person’s own address (Reverse proxy and HTTPS)
    APP_SETUP_TOKENThe output of openssl rand -hex 16, if the machine is reachable from the internet before setup is done
  3. Log in to the registry if its images are private: docker login GITEA_HOST.

  4. Start it:

    Terminal window
    docker compose up -d

    The database starts, migrate prepares it, and then the web server and the worker start. docker compose ps shows them, and curl http://127.0.0.1:3000/healthz answers with the version.

  5. Set up the reverse proxy (Reverse proxy and HTTPS), then open APP_BASE_URL. The setup wizard asks for the setup token: APP_SETUP_TOKEN, or the one the web server prints until setup is done (docker compose logs web | grep -i "setup token"). It creates the household, the first admin, and the family.

  6. Then, as you like:

    A kitchen with one screen and no other devices can set KIOSK_MODE=1, so / opens the wall display.

The optional local AI model runs with docker compose --profile ai up -d (Setting up AI (optional)).

Lantern never updates itself.

  1. Read the release’s notes on the repository’s Releases page. With the update check on, admins also see a notice in the app when a newer release is out. To turn it on, set APP_UPDATE_CHECK_URL=https://GITEA_HOST/api/v1/repos/OWNER/lantern/releases/latest in .env, and add APP_UPDATE_CHECK_TOKEN, a read-only token, if the repository is private.

  2. Get the new release’s docker-compose.yml as in step 1 of Installing, and compare it with yours. Most releases don’t change it. Look at the new .env.example for new settings too.

  3. Set the new version in APP_IMAGE in .env.

  4. Pull and restart:

    Terminal window
    docker compose pull && docker compose up -d

    Before it changes anything, migrate dumps the database into data/backups/ (pre-migrate-<time>.dump). Only then does it apply the new version’s migrations. The web server and the worker start only if that succeeded. /healthz reports the new version.

Going back to the previous version: if no migration ran, set the old APP_IMAGE and run step 4 again. If one did, first restore the pre-migrate dump from just before the upgrade (below), since the older version doesn’t know the new database.

PostgreSQL is pinned in docker-compose.yml. A release that moves it to a new major version says so in its notes, with the steps: a major version needs a dump and a restore.

  • Every night at 03:00 (the household’s time) the worker dumps the whole database into data/backups/. It keeps them APP_BACKUP_RETENTION_DAYS days (14 by default), and always the newest. Settings → Backups shows them and makes one now.
  • Before every upgrade, migrate makes one too.
  • Export everything (Settings) downloads the household as data.json, with every photo, in one zip, readable without Lantern. Saved passwords and keys are left out.
  • Copy them off the machine. A backup on the same disk doesn’t survive the disk. Copy the whole data/ folder (the dumps and photos/) and .env to somewhere else, for example nightly after 03:30 with your usual backup tool. Leave postgres/ out: it’s the live database, and a copy taken while it runs may not open. The dumps are the database’s backup.
  • Keep .env safe. It holds APP_SECRET_KEY, without which a restored Lantern can’t read its saved connections.

Restoring a backup has the steps:

  1. pick a dump;
  2. stop the web server and the worker;
  3. replace the database with the dump using the tools in the containers, then put back photos/ from the same backup;
  4. start again.

A dump from an older version restores into a newer one: migrate brings it up to date as it starts.

With no email in Lantern, recovery is on the server, with lantern-admin in the worker container (docker compose exec worker lantern-admin help lists everything):

  • reset-password --email <address> prints a new password. It works for 24 hours, and only to choose a new one at the next sign-in. Every session of that login is signed out.
  • clear-pin-lockout --member <name> lets a member enter their PIN again, after five wrong ones.
  • set-pin --member <name> [--pin 1234] sets a member’s PIN, or a random one.
  • setup-token prints the setup token while setup isn’t done.