# 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:///oauth/bot?account=, 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