ApiaryLensOpen Source Apiary Intelligence

Authoritative project documentation

Manual Compose install — no Scout Bee

Tested against apiarylens-0.1.0-preview.5-compose-97e5ce858208.tar.gz from the published v0.1.0-preview.5 release on 2026-07-19. The published artifact's byte count and SHA-256 were verified against the release manifest and SHA256SUMS, its keyless attestation verified with gh attestation verify, the bundle was extracted, and every command in this guide was checked against its actual layout, docker/README.md, compose.yaml, and .env.example. The runtime lifecycle (install → health → bootstrap → backup → restore → teardown) is verified by the exact-artifact UAT record in UAT-001 item 5, which walked these procedures end to end on the Ubuntu 24.04 reference host against the prior build's bundle — whose docker/ deployment tree is content-identical to this one; the two corrections that run produced (#83: secret-file permissions and .env.example identity) are incorporated below and confirmed fixed in this bundle.

Deploy the ApiaryLens backend and web frontend with Docker Compose on a Linux host you control, without Scout Bee. This is the fully supported direct path; Scout automates the same steps but is never required.

Supported host

  • x86-64 Linux; Ubuntu Server 24.04 LTS is the verified reference
  • Docker Engine with the Compose v2 plugin
  • 2 vCPU, 4 GiB RAM, 32 GiB persistent disk for the family profile
  • Inbound TCP 80 and 443; TCP 22 restricted to your own address
  • A DNS name resolving to the host
  • Outbound HTTPS for image retrieval and certificate issuance (for a host without any egress, use the offline deployment bundle and the air-gap install and transported update guide instead)
  • UTC system time and enough free disk for one release plus backups

See Cloud VM Compose for Azure, AWS, and Google Cloud host preparation and cost notes.

1. Verify the release bundle

Never deploy from a mutable tag or an unverified download.

  1. Download the Compose bundle and the release manifest from the release page of the exact version you are installing.

  2. Transfer the bundle to the server over SSH with strict host-key checking.

  3. On the server, verify the byte count and SHA-256 digest against the manifest entry:

    stat --format=%s apiarylens-<version>-compose-<sha12>.tar.gz
    sha256sum apiarylens-<version>-compose-<sha12>.tar.gz
    

    Both values must match the manifest exactly. Stop on any mismatch.

2. Lay out the release and secrets

The bundle extracts into the current directory (it has no top-level version folder), so create the versioned release directory first and extract into it. Take ownership of the /opt/apiarylens base directory itself — everything below it (releases, secrets, your own records) is then created without sudo:

sudo install -d -o "$USER" /opt/apiarylens
install -d /opt/apiarylens/releases/<version>
tar -xzf apiarylens-<version>-compose-<sha12>.tar.gz \
    -C /opt/apiarylens/releases/<version>
cd /opt/apiarylens/releases/<version>/docker

Create the two deployment secrets outside the release tree so they survive updates, in a directory only you can enter:

install -d -m 700 /opt/apiarylens/secrets
openssl rand -base64 36 > /opt/apiarylens/secrets/bootstrap-token
openssl rand -base64 48 > /opt/apiarylens/secrets/auth-root
chmod 644 /opt/apiarylens/secrets/bootstrap-token \
          /opt/apiarylens/secrets/auth-root

The chmod 644 is required: the secret files are bind-mounted read-only into the api container, which runs as the unprivileged user apiarylens (uid 10001) and cannot open host-user-only files — with mode-600 files the API fails at startup with EACCES on /run/secrets/bootstrap_token and the stack never becomes healthy. The mode-700 directory is what keeps the files private to you on the host.

  • The bootstrap token is the one-time first-owner setup code. Keep it only until the first owner and family exist, then delete the local copy.
  • The authentication root is durable deployment state. Losing or rotating it invalidates sessions and makes stored family credentials unverifiable. Protect it and include it in every backup.

Copy .env.example to .env (mode 600). It ships preset with the release's identity values (APIARYLENS_VERSION, APIARYLENS_ARTIFACT_IDENTITY, …); leave those as shipped, set APIARYLENS_SITE_ADDRESS to your real DNS name, and point the deployment at your secret files:

APIARYLENS_BOOTSTRAP_SECRET_FILE=/opt/apiarylens/secrets/bootstrap-token
APIARYLENS_AUTH_ROOT_SECRET_FILE=/opt/apiarylens/secrets/auth-root

Never put either secret value directly in .env or shell history — the variables above carry file paths, not secrets.

3. Start and verify

From the release's docker/ directory (Compose reads .env from the working directory, and compose.yaml sets the project name apiarylens):

docker compose config --quiet
docker compose build --pull
docker compose up -d --wait

Then verify every one of the following before calling the install done:

  1. Containers are healthy: docker compose ps.

  2. Public HTTPS answers and /health reports the release identity you installed:

    curl --fail --show-error --silent "https://<your-dns-name>/health"
    
  3. The bootstrap flow is protected: creating the first family requires the one-time setup code.

  4. An authenticated sign-in can read and write records.

  5. Media is private: media URLs require authentication.

  6. A backup can be created and verified — do this now, not after the first real data exists. See the Operations Guide backup procedure.

Hard rules

  • Do not expose the API container directly or publish plain HTTP.
  • Do not bind any unauthenticated service to LAN or public interfaces.
  • Do not use default or example credential values.
  • Do not run docker compose down --volumes as an update or troubleshooting step — it destroys data volumes.

Updates, rollback, and removal

Updates follow the shared lifecycle — backup first, verify the new bundle, migrate, activate, health-check, and only then commit: Operations Guide and the update lifecycle reference. The manual update path must keep the same /opt/apiarylens/releases/<version> layout so guided tooling and your own records agree about what is installed. Removal choices are covered in the Operations Guide uninstall section.

Was this page helpful?

Ask for help or suggest a documentation improvement in the public project.

Open an issue