chadtmiller.com/knotless
git that lives in your Atmosphere account
7
# knotless-run on a runner host, as /etc/knotless/docker-compose.yml.
# deploy/runner-host/deploy.sh copies it there, beside the .env it reads;
# edit it here. The appview it finds pulls through is knotless.dev's, over
# HTTPS. With the `bots` profile, which deploy.sh turns on given a domain,
# a knotless-serve behind Caddy keeps the runner's OAuth session, for
# private repositories: Caddy answers only its bot login.
name: knotless-runner
services:
run:
image: knotless:current
restart: always
logging:
driver: journald
options:
tag: "{{.Name}}"
# Root, as on the main host: it holds the docker socket. What it runs
# is held apart by gVisor, not by this.
user: root
# As on the main host: a stop waits for runs whose steps started, up
# to --stop-wait (15 minutes).
stop_grace_period: 20m
command:
- sh
- -c
- >-
exec knotless-run
--jetstream ${KNOTLESS_JETSTREAM:-wss://jetstream.us-east.bsky.network}
--executor docker
--runtime runsc
--trusted-runtime runc
--network knotless-runs
--resolv /etc/knotless/resolv.conf
--cpus ${KNOTLESS_RUN_CPUS:-2}
--memory ${KNOTLESS_RUN_MEMORY:-3}
--pids 4096
--run-timeout ${KNOTLESS_RUN_TIMEOUT:-3600}
--jobs ${KNOTLESS_RUN_JOBS:-4}
--owner-jobs ${KNOTLESS_RUN_OWNER_JOBS:-2}
--allowance ${KNOTLESS_RUN_ALLOWANCE:-2000}
--private-allowance ${KNOTLESS_RUN_PRIVATE_ALLOWANCE:-500}
--keep-checks 30
--paused /etc/knotless-run/paused.json
--secrets /etc/knotless-run/run-secrets.json
--state /var/lib/knotless-run/state.json
--work /var/lib/knotless-run/work
--caches /var/lib/knotless-run/caches
--pulls
${KNOTLESS_RUN_DISCOVER---discover}
${KNOTLESS_RUN_ARGS:-}
${KNOTLESS_RUN_REPOS:-}
environment:
KNOTLESS_APPVIEW: ${KNOTLESS_APPVIEW:-https://knotless.dev}
# The bots' sessions, which `bots` keeps; the app password's
# session, until the runner logs in there.
KNOTLESS_CONFIG_DIR: /var/lib/knotless-run/bots
KNOTLESS_CACHE_DIR: /var/lib/knotless-run/cache
RUST_LOG: ${KNOTLESS_LOG:-info}
env_file:
# KNOTLESS_IDENTIFIER and KNOTLESS_PASSWORD: the runner's own
# account and an app password for it, used only until it logs in at
# /oauth/bot: an app password reads no private repositories.
- /etc/knotless/run.env
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# At the same path as on the host, for the step containers' mounts.
- /var/lib/knotless-run:/var/lib/knotless-run
# The pause list and the secrets, read again as runs are filed: the
# directory, so an editor's new file is seen, not the old inode.
- /etc/knotless:/etc/knotless-run:ro
deploy:
resources:
limits:
cpus: "1"
memory: 512m
# Keeps the runner's OAuth session, as the main host's serve keeps its
# bots': the operator approves once at
# https://<domain>/oauth/bot?account=<the runner's handle>, and it lasts
# two years if used every three months. Its own client key, beside the
# session, never leaves this host. It follows no feed and keeps no index.
bots:
image: knotless:current
profiles: [bots]
restart: always
logging:
driver: journald
options:
tag: "{{.Name}}"
command:
- knotless-serve
- --listen
- 0.0.0.0:2590
- --public-url
- https://${KNOTLESS_RUNNER_DOMAIN:-}
- --bots
- /var/lib/knotless-run/bots
environment:
KNOTLESS_CONFIG_DIR: /var/lib/knotless-serve/config
KNOTLESS_CACHE_DIR: /var/lib/knotless-serve/cache
# The runner's account, the one bot that may log in here.
KNOTLESS_BOT_DIDS: ${KNOTLESS_BOT_DIDS:-}
RUST_LOG: ${KNOTLESS_LOG:-info}
volumes:
- /var/lib/knotless-serve:/var/lib/knotless-serve
- /var/lib/knotless-run/bots:/var/lib/knotless-run/bots
deploy:
resources:
limits:
cpus: "0.5"
memory: 256m
# TLS for the bot login, and nothing else of serve's (Caddyfile).
caddy:
image: caddy:2
profiles: [bots]
restart: always
ports:
- "80:80"
- "443:443"
environment:
KNOTLESS_RUNNER_DOMAIN: ${KNOTLESS_RUNNER_DOMAIN:-}
volumes:
- /etc/knotless/Caddyfile:/etc/caddy/Caddyfile:ro
- /var/lib/caddy:/data
depends_on:
- bots
deploy:
resources:
limits:
cpus: "0.5"
memory: 256m