Self-built .deb packages (caddy/xcaddy+cloudflare, forgejo, forgejo-runner) published to the bit-crafts Debian registry.
  • Shell 90.4%
  • Dockerfile 9.6%
Find a file
Younes Benmoussa 9cea1c1c4b
All checks were successful
ci / build (caddy) (push) Successful in 1m22s
ci / build (forgejo) (push) Successful in 20s
ci / build (forgejo-runner) (push) Successful in 9s
release / publish (caddy) (push) Successful in 1m20s
release / publish (forgejo) (push) Successful in 21s
release / publish (forgejo-runner) (push) Successful in 11s
release / release-marker (push) Successful in 3s
deb: forgejo-runner installs NON-ROOT out-of-the-box; caddy unit gains logs/env/hardening
forgejo-runner .deb was unusable for a non-root runner: postinst did
'install -d -m0750 /var/lib/forgejo-runner /etc/forgejo-runner' (root:root), so a non-root
daemon could not read config.yaml (permission denied), and the unit had no User=. Fix:
postinst now creates a 'forgejo-runner' system user (added to 'docker' for socket access),
owns the workdir, and makes /etc/forgejo-runner 0755 (traversable); the unit sets
User/Group=forgejo-runner + After/Wants docker.service. Installs working non-root OOTB —
no manual chmod/chown/drop-in.

caddy .deb unit: add EnvironmentFile=-/etc/caddy/cloudflare.env (optional, '-' = generic),
NoNewPrivileges=true, LogsDirectory=caddy (so /var/log/caddy is created for the access-log).
2026-06-03 20:40:07 +01:00
.forgejo/workflows seed bit-crafts-dependencies: caddy/forgejo/forgejo-runner .deb pipeline 2026-06-03 14:47:05 +01:00
caddy deb: forgejo-runner installs NON-ROOT out-of-the-box; caddy unit gains logs/env/hardening 2026-06-03 20:40:07 +01:00
ci-images/go seed bit-crafts-dependencies: caddy/forgejo/forgejo-runner .deb pipeline 2026-06-03 14:47:05 +01:00
forgejo deps: GPG verify hard-fail via in-repo pinned Forgejo key (no keyserver dependency) 2026-06-03 19:25:48 +01:00
forgejo-runner deb: forgejo-runner installs NON-ROOT out-of-the-box; caddy unit gains logs/env/hardening 2026-06-03 20:40:07 +01:00
keys deps: GPG verify hard-fail via in-repo pinned Forgejo key (no keyserver dependency) 2026-06-03 19:25:48 +01:00
lib seed bit-crafts-dependencies: caddy/forgejo/forgejo-runner .deb pipeline 2026-06-03 14:47:05 +01:00
.gitignore deps: GPG verify hard-fail via in-repo pinned Forgejo key (no keyserver dependency) 2026-06-03 19:25:48 +01:00
README.md seed bit-crafts-dependencies: caddy/forgejo/forgejo-runner .deb pipeline 2026-06-03 14:47:05 +01:00

bit-crafts-dependencies

Self-built .deb packages for software the NAS runs that Debian does not provide adequately, published to the bit-crafts Debian registry so the nodes can install and update them with plain apt.

This repo packages only the genuinely self-built binaries. It deliberately does not repackage anything Debian already ships well, nor anything vendored at build time.

Dependency classification

Software Version Why it's here / not here Action
caddy 2.11.3 Debian ships 2.6.2 without DNS-provider plugins; we need caddy-dns/cloudflare for ACME DNS-01 → must build with xcaddy. Packaged (caddy/)
forgejo 15.0.2 Not in Debian; upstream binary from code.forgejo.org. Packaged (forgejo/)
forgejo-runner 12.10.2 Not in Debian; upstream binary from code.forgejo.org. Packaged (forgejo-runner/)
hugo, incus, keepalived, chrony, unbound, nfs, fail2ban, ufw, rsync, pgbouncer, postgresql-17, qbittorrent-nox, libadwaita 1.7, gtk4, cmocka, blueprint-compiler, meson, ninja … (Trixie) Debian Trixie provides a sufficient version. Nothing — use apt
liburing 2.14, xxhash 0.8.3, blake3 1.8.5 (pinned) Vendored at build via meson wraps (static-linked) in bitcrafts-dev. Nothing — vendored
jellyfin, jellyfin-ffmpeg (upstream) Installed from the official repo.jellyfin.org apt repo (third-party, not self-built). Nothing — third-party apt
bitcrafts-tools / -vigil (own) Built & published by their own repos' CI. Elsewhere

Layout

caddy/            VERSION  build-deb.sh  debian/{caddy.service,postinst,postrm}
forgejo/          VERSION  build-deb.sh  debian/{forgejo.service,postinst}
forgejo-runner/   VERSION  build-deb.sh  debian/{forgejo-runner.service,postinst}
lib/deb.sh        shared .deb assembly + sha256 helpers (no external deps; no `bx`)
ci-images/go/     Dockerfile for the ci-base-go CI image (Go + xcaddy + dpkg-dev + gnupg + python3)
.forgejo/workflows/
  ci.yml          PR/push -> build each dep (matrix), no publish
  release.yml     tag v* / workflow_dispatch -> build + publish-deb + Forgejo release marker
  rebuild.yml     monthly cron / workflow_dispatch -> rebuild + publish-deb

Each build-deb.sh is self-contained (sources only lib/deb.sh) and emits to dist/. caddy is built from source (xcaddy, pinned caddy + plugin versions, static/CGO-off). forgejo / forgejo-runner are upstream binaries verified by sha256 (hard gate) + a pinned GPG signature (Forgejo key 3BF4E813F84812411DA01E5BC4186DF66F4B6750).

CI image (ci-base-go)

Built/pushed once from ci-images/go/Dockerfile on ci-large:

docker build -t git.bit-crafts.com/bit-crafts/ci-base-go:trixie -f ci-images/go/Dockerfile ci-images/go
docker push  git.bit-crafts.com/bit-crafts/ci-base-go:trixie

release.yml / rebuild.yml pin it by digest — re-pin after any rebuild.

Bumping / adding a dependency

  1. Edit the dep's VERSION (or add a new dep/ folder with VERSION + build-deb.sh, and add it to the workflow matrices).
  2. Push a PR → ci.yml builds it.
  3. Publish: push a tag vX.Y.Z (or run release.yml via workflow_dispatch).

Installing on a node (consumer)

The registry is already wired on the workstation/nodes:

# /etc/apt/sources.list.d/bit-crafts.list  (one-line, not DEB822)
deb https://pkgs.bit-crafts.com/api/packages/bit-crafts/debian trixie main
# key: https://pkgs.bit-crafts.com/api/packages/bit-crafts/debian/repository.key
sudo apt update && sudo apt install caddy        # our 2.11.3 wins over Debian's 2.6.2

⚠️ This repo produces packages; it does not migrate the running services. The live caddy/forgejo/forgejo-runner still run from /usr/local/bin (manual installs). Switching the hosts to these apt packages is a separate, deliberate operation.

Secrets

None are committed. CI auth uses the org secret PKG_TOKEN (write:package). Build-time GPG keys are fetched from a public keyserver into a throwaway GNUPGHOME and are .gitignored.