The self-hosting stack

This commit is contained in:
2026-08-24 22:28:00 +02:00
commit 40717dfdc5
10 changed files with 1942 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
# Jarvis — the agent release, as a pullable image.
#
# OPTIONAL OVERLAY. The base stack runs perfectly without it; what it adds is the one feature a
# self-hosted instance cannot otherwise have, because enrolling a machine downloads a compiled
# binary and there is nowhere for a compose-only deployment to get one. This carries that release
# as an OCI image, so it arrives through the same `docker compose pull` as the api and the web.
#
# Turn it on by naming both files. Either spelling works:
#
# docker compose -f docker-compose.yml -f docker-compose.agent.yml up -d
#
# or, so that a plain `docker compose ...` keeps working for every later command, put this in .env:
#
# COMPOSE_FILE=docker-compose.yml:docker-compose.agent.yml
#
# Upgrading is unchanged: `docker compose pull && docker compose up -d`. The publisher re-runs,
# replaces the release in the volume, and the api picks it up WITHOUT a restart — digests are
# computed from the bytes on disk on every request, not cached at boot.
services:
# Runs once per `up`, copies its payload into the shared volume, exits. Not a server.
agent-releases:
image: ${JARVIS_IMAGE_AGENT:-git.luxit.be/luxit/jarvis-agent-dist:stable}
# Explicit, because the default would be wrong the moment somebody copies this block: a
# restarting one-shot is an infinite loop, and Compose's own default policy is already "no".
restart: "no"
volumes:
- agent_releases:/out
api:
# NOTE THE COUPLING: until the publisher has exited 0, the api does not start. That is
# deliberate — a release that failed to arrive should stop the deploy and say so, rather than
# leave an instance quietly handing 404s to every installer somebody runs this week. The cost
# is that an unreachable registry now blocks the whole stack, so if that trade is wrong for
# you, drop these three lines and the api will simply serve no build until the volume fills.
depends_on:
agent-releases:
condition: service_completed_successfully
volumes:
# Read-only: the API serves these bytes to every managed machine and never writes here.
- agent_releases:/srv/agent-releases:ro
environment:
AGENT_RELEASE_DIR: /srv/agent-releases
volumes:
agent_releases: