Files
Anthias/docs
Viktor Petersson 5e00c8ba25 refactor(docker): drop celery image, restore base apt layer dedup (#2776)
* refactor(docker): drop celery image, restore base apt layer dedup

- Delete Dockerfile.celery.j2; compose now runs celery on the
  anthias-server image with a `command:` override.
- Make viewer extend Dockerfile.base.j2 (mirroring test); drop 17
  packages duplicated between viewer and base_apt_dependencies, plus
  4 within-list duplicates.
- Move `# syntax=docker/dockerfile:1.4` to line 1 of every rendered
  Dockerfile. It previously lived in uv-builder.j2 line 1 and got
  bumped mid-file for server by the bun-builder prelude, silently
  disabling the 1.4 frontend and breaking cache-key parity with
  viewer — the actual blocker for layer dedup.
- Collapse CI matrix from (board × service) to (board) so all
  services for a board build on the same runner with the same
  buildkit cache, producing byte-identical apt layer digests at the
  registry.
- Add ENV DJANGO_SETTINGS_MODULE to the server image so the merged
  image runs both server and celery CMDs.
- Update all five compose templates (prod, balena prod, balena dev,
  dev, test) to redirect anthias-celery at the server image with a
  command: override. dev compose pins an explicit `image:` tag so
  both services share the locally-built SHA.
- Remove old anthias-celery / srly-ose-celery containers in
  upgrade_containers.sh so the recreated container can take the name.

Verified end-to-end on x86: server and viewer apt layers share a
single digest; SHARED SIZE jumps from 132 MB to 1.216 GB; merged
image runs both workloads in compose (celery task round-trips
through Redis to SUCCESS).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* perf(docker): cache buildkit layers in GHCR registry across CI runs

Add a --cache-backend / $BUILDX_CACHE_BACKEND option to
tools.image_builder with two modes:

- `local` (default): writes to /tmp/.buildx-cache/<board>/.
  Unchanged from before; right for local dev.
- `registry`: pushes BuildKit cache to
  ghcr.io/screenly/anthias-<service>:buildcache-<board>. Reuses the
  GHCR login already done by docker-build.yaml, no extra tokens or
  third-party actions needed.

Wire CI to use registry mode on push events (master) so subsequent
runs of the same board pull cached layers — the ~825 MB extracted
apt install per service goes from ~3 min cold to a few seconds
warm. workflow_dispatch on a non-master branch falls back to local
mode (effectively no-cache) so manual runs can't pollute the master
cache.

Drop the old actions/cache@v5 step that mirrored
/tmp/.buildx-cache/<board> through actions/cache — registry cache
is per-step rather than one big tarball, so it survives the GitHub
Actions cache 10 GB-per-repo eviction better.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(image-builder): move local cache out of /tmp to user XDG cache dir

SonarCloud python:S5443 flagged the previous /tmp/.buildx-cache/
default as a security hotspot — `/tmp` is world-writable, so on a
multi-user host another account could in principle tamper with the
buildkit cache. Switch to $XDG_CACHE_HOME/anthias-buildx/<board>/
(default ~/.cache/anthias-buildx/), which is per-user by default
and follows XDG Base Directory convention.

CI is unaffected: docker-build.yaml uses --cache-backend=registry
on push events, which pushes cache to GHCR and never touches the
local path. Local dev users with stale state in
/tmp/.buildx-cache/<board>/ can rm it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(docker): correct cache-backend comments to match real behavior

Two doc fixes per Copilot review on #2776:

- tools/image_builder/__main__.py: the cache-backend rationale
  block still referenced /tmp/.buildx-cache/<board>; update to
  $XDG_CACHE_HOME/anthias-buildx/<board> so it matches the
  implementation moved in 529a50e0.
- .github/workflows/docker-build.yaml: the env comment claimed
  pull-request builds read from the registry cache, but this
  workflow has no pull_request trigger — non-push runs are
  workflow_dispatch, which both falls through to local cache and
  skips `docker login ghcr.io`, so it has no GHCR auth at all.
  Rewrite the comment around the push / workflow_dispatch split
  the code actually implements.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(docker): address Copilot review on registry cache + test compose

- tools/image_builder/__main__.py: comment in the registry-cache
  branch said the cache namespace was "picked from the build's tag
  list", but the implementation hardcodes
  ghcr.io/screenly/anthias-{service}. Rewrite the comment to
  describe what the code actually does and call out the hardcode
  so a future namespaces refactor doesn't silently break cache.
- docker-compose.test.yml: anthias-celery had its own `build:`
  block pointing at Dockerfile.test, claiming "reuses the test
  image" — but compose builds two separate images per service
  even with identical context, defeating the dedup intent. Mirror
  the docker-compose.dev.yml pattern: pin anthias-test to an
  explicit `image: anthias-test:dev` tag and have anthias-celery
  reference the same tag with no `build:`. Also bind-mount the
  source into celery so it picks up code changes (matches
  anthias-test's existing volume).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(image-builder): read-only registry cache without --push

Per Copilot review: --cache-backend=registry previously tried to
push cache to ghcr.io/... regardless of --push, so a local invocation
without GHCR auth would fail mid-build with a confusing registry
error. Split the behavior:

- Reads (cache_from) are always set when registry mode is active —
  the anthias-* GHCR packages are public, so warm-starting off CI's
  cache without auth works and helps local dev.
- Writes (cache_to) only happen when --push is also set, since
  that's when the workflow has authenticated to GHCR. Without
  --push, log a yellow warning and skip cache_to.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(docker): set DJANGO_SETTINGS_MODULE in test image for celery worker

Per Copilot review on #2776 (suppressed-due-to-low-confidence note,
but the bug is real): docker-compose.test.yml runs the celery
worker from anthias-test:dev. celery_tasks.py calls django.setup()
at module import time, which needs DJANGO_SETTINGS_MODULE in the
environment. The pre-refactor Dockerfile.celery.j2 set it
explicitly; this PR moved that ENV to Dockerfile.server.j2 only,
so the production celery (running on the server image) is fine but
the test celery would have crashed with ImproperlyConfigured.

Set the same ENV in Dockerfile.test.j2. Server and test images
both ship a usable Django environment for any process that imports
anthias_django.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 15:21:43 +01:00
..

Documentation

How to get logs from Anthias

SSH into your Raspberry Pi. For instance, if you've set pi for the username and raspberrypi for the hostname, then run:

$ ssh pi@raspberrypi

Anthias makes use of Docker for containerization. To get the logs from the containers, you can either make use of the docker logs command or you can use the docker-compose logs command.

Using docker logs

For instance, the command below will show you the logs from the server container:

$ docker logs -f screenly-anthias-server-1

If you'd want to see the logs from other containers, simply replace the name of the container in the command above. Here's a table of the available containers:

Container Name Description
screenly-anthias-server-1 uvicorn (HTTP, WebSocket at /ws, static + media file serving)
screenly-anthias-celery-1 Celery service (async tasks)
screenly-anthias-viewer-1 Viewer service
screenly-anthias-redis-1 Redis (Celery broker + Channels layer)

Using docker-compose logs

Important

Before running the succeeding commands, make sure that you're in the /home/${USER}/anthias directory:

$ cd /home/${USER}/anthias # e.g., /home/pi/anthias if the user is `pi`

If you'd like to see the logs of a specific container or service via Docker Compose, you can run the following:

$ docker compose logs -f ${SERVICE_NAME}
# e.g., docker compose logs -f anthias-server

Check out this section of the Developer documentation page for the list of available services.

Enabling SSH

See the official documentation

Updating Anthias

Run the following command in your console:

$ bash <(curl -sL https://install-anthias.srly.io)

Alternatively, you can also run the following command:

$ $HOME/anthias/bin/run_upgrade.sh

Accessing the REST API

To get started, open your browser and go to http://<ip-address>/api/docs/ (or http://localhost:8000/api/docs/ if you're in development mode). You should see the API docs for the endpoints.

TLS / SSL

Anthias supports two independent SSL features:

1. Serving HTTPS (Caddy sidecar)

bin/enable_ssl.sh writes a docker-compose.ssl.override.yml that adds a caddy:2-alpine sidecar in front of anthias-server. Caddy terminates TLS on host ports 80 (redirected to HTTPS) and 443, and reverse-proxies plain HTTP to anthias-server:8080. There are three modes:

# Default — Caddy issues a cert from its built-in local CA. Good for
# IP-based LAN access; browsers will warn that the CA is untrusted.
$ ./bin/enable_ssl.sh

# Auto Let's Encrypt — needs the domain to resolve to this host and
# port 80 to be reachable from the internet for the HTTP-01 challenge.
$ ./bin/enable_ssl.sh --domain example.com --email you@example.com
$ ./bin/enable_ssl.sh --domain example.com --staging   # ACME staging

# Bring your own certificate.
$ ./bin/enable_ssl.sh --cert /path/to/cert.pem --key /path/to/key.pem

# Turn it back off (Caddy + override removed; cert files are kept).
$ ./bin/disable_ssl.sh

When SSL is not enabled, no Caddy container is pulled or run — the default install is unchanged.

2. Trusting a custom CA for outbound requests

If Anthias needs to fetch assets from an internal HTTPS server signed by a private CA, install the CA into the anthias-server and anthias-viewer trust stores:

Warning

This section only works for devices running Raspberry Pi OS Lite.

$ cd $HOME/anthias
$ ./bin/add_certificate.sh /path/to/certificate.crt

More details about generating self-signed certificates can be found here.