Commit Graph

77 Commits

Author SHA1 Message Date
jason 0ff1923d3e 🐛 Fix git fatal error reading /root/.git at gitea startup 🐛
Docker's WORKDIR is /root and the git user has no read permission on
that directory. When gitea starts via gosu git, git inherits /root as
the working directory, calls getcwd(), constructs /root/.git, and
fails with "fatal: error reading '/root/.git'" — crashing gitea.
Setting WORK_DIR=/data/gitea causes the init functions library to cd
to /data/gitea before launching the service, so git never sees /root.
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: set WORK_DIR=/data/gitea

rootfs/usr/local/etc/docker/init.d/08-gitea.sh
2026-06-05 17:40:04 -04:00
jason 7e6f4f5a84 🐛 Fix chmod error on empty ssh directory at first run 🐛
chmod 0600 $DATA_DIR/ssh/* fails with "cannot access" when the
directory is empty (first boot before keys are generated, or when
keys are symlinks in /config/ssh). Replace the glob with find -type f
which silently handles empty directories.
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: use find -exec chmod instead of glob for ssh key permissions

rootfs/usr/local/etc/docker/init.d/08-gitea.sh
2026-06-05 17:38:17 -04:00
jason 94263dc03c 📝 Document auto-detected arch runner labels in README 📝
Add runner labels table showing what gets registered per architecture,
and clarify that all jobs run in containers (no host execution).
Document full language image label list available on both arches.
- README.md: add runner labels table and arch auto-detection note

README.md
2026-06-05 17:08:23 -04:00
jason 1cc1624187 🐛 Remove :host runner labels — all jobs must run in containers 🐛
:host labels run jobs directly on the container filesystem with no
isolation. Replace all arch-specific :host labels with
:docker://ubuntu:latest so every job runs inside its own container
regardless of the runner host architecture.
- rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh: amd64/arm64/linux labels use docker://ubuntu:latest not :host
- README.md: remove :host from external runner label examples

README.md
rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
2026-06-05 17:06:16 -04:00
jason 910cf5be9b 📝 Document external runner setup for native arch matrix builds 📝
Add "Adding external runners" section covering:
- Getting a registration token from Gitea UI or API
- Installing the act_runner binary with arch auto-detection
- Registering with arch-specific labels (arm64:host, linux/arm64:host)
- Running as a systemd service
- Matrix workflow example targeting amd64 and arm64 natively
- README.md: add external runner setup section

README.md
2026-06-05 17:03:20 -04:00
jason e624d7c219 Add arch-specific runner labels for native amd64/arm64 matrix builds
Detect the host architecture at container startup and prepend
arch-specific labels to RUNNER_LABELS so matrix workflows can target
native runners by architecture:
runs-on: amd64 → dispatched to x86_64 runners
runs-on: arm64 → dispatched to aarch64 runners
runs-on: linux/amd64 / runs-on: linux/arm64 (OCI-style)
On x86_64: adds amd64:host and linux/amd64:host
On aarch64: adds arm64:host and linux/arm64:host
This enables a dedicated ARM64 server running the same image to register
native arm64 runners against the same Gitea instance, allowing full
multi-arch matrix CI without emulation.
- rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh: detect arch, prepend arch labels to RUNNER_LABELS

rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
2026-06-05 17:01:24 -04:00
jason 2e20b3b5b8 Enable Actions and forks by default; document SSH port 7833
- DEFAULT_REPO_UNITS and DEFAULT_FORK_REPO_UNITS: all units including
repo.actions so every repo and fork has everything on by default
(opt-out, not opt-in) — ready for GitHub migration
- README: clarify SSH port — internal 22 maps to external 7833 since
host port 22 is reserved for sshd
- rootfs/tmp/etc/gitea/app.ini: DEFAULT_FORK_REPO_UNITS with full unit list
- README.md: document SSH external port 7833

README.md
2026-06-05 16:51:41 -04:00
jason 51a57cfeb4 Add DEFAULT_FORK_REPO_UNITS — full feature set for forks too
Forks should get the same full set of units as new repos since the
intent is a full GitHub migration. Matches DEFAULT_REPO_UNITS exactly.
- rootfs/tmp/etc/gitea/app.ini: add DEFAULT_FORK_REPO_UNITS with all units

rootfs/tmp/etc/gitea/app.ini
2026-06-05 16:49:07 -04:00
jason 85ccdabe5d Enable Actions by default on all new repos
Add DEFAULT_REPO_UNITS to [repository] in app.ini with repo.actions
included so every new repo has Actions enabled out of the box.
Users can still disable it per-repo — opt-out rather than opt-in.
- rootfs/tmp/etc/gitea/app.ini: add DEFAULT_REPO_UNITS with repo.actions included

rootfs/tmp/etc/gitea/app.ini
2026-06-05 16:47:18 -04:00
jason cd977be93d 🐛 Re-apply resolv.conf in init.d phase to beat Docker's async rewrite 🐛
Docker writes /etc/resolv.conf at container start before PID1 launches,
and again asynchronously when the network finishes initializing. The
entrypoint's early copy gets overwritten by Docker's second write.
Re-applying the custom resolv.conf in __run_precopy (init.d phase)
happens after Docker's network setup is complete, so the search . and
options ndots:0 settings stick for the full container lifetime.
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: copy custom resolv.conf in __run_precopy

rootfs/usr/local/etc/docker/init.d/08-gitea.sh
2026-06-05 15:44:44 -04:00
jason ea11289300 🔧 update resolv.conf in rootfs 🔧
- Update DNS resolver configuration in rootfs/usr/local/etc/resolv.conf

rootfs/usr/local/etc/resolv.conf
2026-06-05 14:40:27 -04:00
jason ddc318052c 📝 Fix compose example to follow conventions 📝
- Add x-logging anchor with json-file driver
- Add pull_policy: always
- Add logging: *default-logging
- Add network block (gitea / external: false)
- Switch environment from list to map format
- Add CONTAINER_NAME to environment
- Use HOSTNAME: ${BASE_HOST_NAME:-...} pattern
- Switch volumes from absolute paths to ./volumes relative paths
- Bind ports to 172.17.0.1 (not 0.0.0.0)
- Add cgroupns_mode: private
- Add port comment at top of file
- README.md: bring compose example into line with dockerfile_conventions.md

README.md
2026-06-05 13:42:50 -04:00
jason 958439b9ee 🐛 Fix DATABASE_DIR_SQLITE override; 📝 correct docker run example 🐛
DATABASE_DIR fix:
The previous override hardcoded $DATA_DIR/db/sqlite, ignoring
DATABASE_DIR_SQLITE when it was explicitly set via env var. Changed
to respect DATABASE_DIR_SQLITE and only fall back to $DATA_DIR/db/sqlite
when the env var is not provided.
README:
- docker run and compose examples updated to match actual working flags:
--cgroupns private, --tty, --cap-add CHOWN/SYS_TIME/SYS_ADMIN,
--hostname FQDN, --domainname, GITEA_PROTO, DATABASE_DIR_SQLITE
with a separate sqlite volume mount
- Removed non-functional vars from examples (CONTAINER_PROTOCOL,
CONTAINER_DEFAULT_DATABASE_TYPE, DATABASE_BASE_DIR, WEB_PORT)
- Added DATABASE_DIR_SQLITE to the database env var table
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: respect DATABASE_DIR_SQLITE env var
- README.md: fix docker run/compose examples, add DATABASE_DIR_SQLITE to table

README.md
rootfs/usr/local/etc/docker/init.d/08-gitea.sh
2026-06-05 13:41:26 -04:00
jason b276c3ee0b 📝 Add missing env vars to README 📝
Add GITEA_HOSTNAME, FULL_DOMAIN_NAME, GITEA_ROOT_USER_NAME,
GITEA_ROOT_PASS_WORD, GITEA_USER_NAME, GITEA_USER_PASS_WORD,
GITEA_WORK_DIR, GITEA_SQL_DB_HOST, RUNNER_CACHE_PORT,
RUNNER_IP_ADDRESS, RUNNER_DEFAULT_HOME, RUNNER_CONFIG_NAME.
Reorganise the env var table into labelled groups (General, Server,
Users, Mail, Database, act_runner) for easier scanning.
- README.md: add missing env vars, group table by category

README.md
2026-06-05 13:25:10 -04:00
jason cce3b4528d 🐛 Fix sqlite DATABASE_DIR path; 📝 rewrite README 🐛
DATABASE_DIR fix (08-gitea.sh):
DATABASE_SERVICE_TYPE="sqlite" triggers a generic block that appends
/$SERVER_NAME to /data/db/sqlite. Before the SERVER_NAME fix that was
empty giving /data/db/sqlite//gitea.db; even after it would be
/data/db/sqlite/<hostname> not under DATA_DIR. Re-pin DATABASE_DIR to
$DATA_DIR/db/sqlite after the generic block.
README rewrite:
- Full env var reference table (GITEA_SERVER, GITEA_PROTO, GITEA_NAME,
GITEA_ADMIN, GITEA_EMAIL_*, GITEA_SQL_*, ACT_RUNNER_FALLBACK_VERSION,
RUNNERS_START, DOMAIN, DEBUGGER)
- Volume and port tables
- Production notes: --privileged required, GITEA_SERVER must be set,
mailer disabled by default, DNS override explained
- Canonical section order: Docker → Development → License
- README.md: full rewrite with env vars, volumes, ports, and production notes
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: fix DATABASE_DIR to always use $DATA_DIR/db/sqlite

README.md
rootfs/usr/local/etc/docker/init.d/08-gitea.sh
2026-06-05 13:20:18 -04:00
jason bd301103c4 🐛 Fix REPLACE_* token substitution in config files 🐛
Two substitution bugs fixed:
act_runner (zz-act_runner.sh):
- REPLACE_RUNNER_* tokens were only substituted inside the registration
block (guarded by SYS_AUTH_TOKEN + runners file absence). If gitea
wasn't ready on first boot, the file was copied with tokens intact
and never substituted on subsequent boots.
- Fix: substitute tokens immediately after copy, unconditionally.
Registration logic remains gated on auth token availability.
gitea app.ini (08-gitea.sh):
- REPLACE_SERVER_NAME and REPLACE_SERVER_PROTO had no matching env
vars — the script used HOSTNAME and SERVICE_PROTOCOL instead, so
__initialize_replace_variables left those tokens unsubstituted.
- Fix: export SERVER_NAME="${DOMAIN:-$HOSTNAME}" and
SERVER_PROTO="${SERVICE_PROTOCOL:-http}" as aliases after the
HOSTNAME chain is resolved.
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: add SERVER_NAME and SERVER_PROTO aliases for token substitution
- rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh: move REPLACE_ substitution outside registration guard

rootfs/usr/local/etc/docker/init.d/08-gitea.sh
rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
2026-06-05 13:14:39 -04:00
jason 541e3398a0 🐛 Fix container DNS: ship resolv.conf without search domain 🐛
Hosts with a search domain (e.g. search casjay.dev) cause containers
to inherit it. When that zone has a wildcard AAAA record, public
hostnames like github.com resolve to the host's own IPv6 address
instead of the real server, breaking all HTTPS (and any other
protocol) from inside the container.
The entrypoint already has a hook: if /usr/local/etc/resolv.conf
exists it replaces /etc/resolv.conf at container startup. Ship a
clean resolv.conf with Cloudflare + Google DNS and no search domain
so container DNS is always correct regardless of host configuration.
- rootfs/usr/local/etc/resolv.conf: new file — clean DNS, no search domain

rootfs/usr/local/etc/resolv.conf
2026-06-05 12:22:20 -04:00
jason dd8fa3d25c 🐛 Add retry logic to gitea and act_runner downloads 🐛
gitea.com was returning 502 Bad Gateway from the build host, causing
the act_runner download to fail immediately with no retry. Added
--retry 5 --retry-delay 10 --retry-all-errors to both download curl
calls so transient gateway errors don't abort the build.
- rootfs/root/docker/setup/05-custom.sh: add retry flags to gitea and act_runner curl download calls

rootfs/root/docker/setup/05-custom.sh
2026-06-04 17:30:26 -04:00
jason 65c2ec64f6 🐛 Fix act_runner download: repo renamed, new binary names 🐛
The gitea/act_runner repo was renamed to gitea/runner and binary
filenames changed from act_runner-{ver}-linux-{arch} to
gitea-runner-{ver}-linux-{arch} (with version stripping the leading
'v'). The old URLs returned 404 causing every build to fail.
Also adds resilience for builds where gitea.com is unreachable:
- 30s connect timeout / 45s max-time on API calls
- Pinned fallback version (v1.0.8) used when API returns nothing
- Fallback direct URL constructed from version tag without API
- Empty-URL guard before curl invocation prevents blank-argument error
- rootfs/root/docker/setup/05-custom.sh: fix repo path gitea/act_runner → gitea/runner, fix binary name pattern, add fallback version, add fallback URL construction, add empty-URL guard

rootfs/root/docker/setup/05-custom.sh
2026-06-04 17:13:51 -04:00
jason 5349e92de9 🐛 Disable act_runner cache — external_secret required when enabled 🐛
default_config.yaml had cache.enabled=true but no external_secret,
dir, host, or port configured. act_runner refuses to start the cache
server without external_secret, logging an error on every boot.
cache_server.yaml already has cache disabled — align default_config
to match.
- rootfs/tmp/etc/act_runner/default_config.yaml: cache.enabled false

rootfs/tmp/etc/act_runner/default_config.yaml
2026-06-04 16:54:06 -04:00
jason ab8d2b9ffc ♻️ Migrate gitea to /config/ source-of-truth architecture ♻️
Migrate gitea Docker image to the new build-time config architecture.
- rootfs/root/docker/setup/03-files.sh: rewrite to canonical form with /tmp/bin, /tmp/var, /tmp/etc, /tmp/usr handlers; remove template-files copy block
- rootfs/usr/local/etc/docker/functions/entrypoint.sh: update to latest template with __init_service_conf, __find_php_ini, __find_php_bin helpers
- rootfs/usr/local/etc/docker/init.d/*.sh: fix $(basename) UUOC → ${var##*/}; move inline comments above code lines; remove commented-out dead code
- rootfs/usr/local/share/template-files/: delete entire directory; config files now deployed via /tmp/etc/ at build time

rootfs/root/docker/setup/03-files.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/05-dockerd.sh
rootfs/usr/local/etc/docker/init.d/08-gitea.sh
rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
rootfs/usr/local/share/template-files/config/env/default.sample
rootfs/usr/local/share/template-files/config/env/examples/00-directory.sh
rootfs/usr/local/share/template-files/config/env/examples/addresses.sh
rootfs/usr/local/share/template-files/config/env/examples/certbot.sh
rootfs/usr/local/share/template-files/config/env/examples/couchdb.sh
rootfs/usr/local/share/template-files/config/env/examples/dockerd.sh
rootfs/usr/local/share/template-files/config/env/examples/global.sh
rootfs/usr/local/share/template-files/config/env/examples/healthcheck.sh
rootfs/usr/local/share/template-files/config/env/examples/mariadb.sh
rootfs/usr/local/share/template-files/config/env/examples/mongodb.sh
rootfs/usr/local/share/template-files/config/env/examples/networking.sh
rootfs/usr/local/share/template-files/config/env/examples/other.sh
rootfs/usr/local/share/template-files/config/env/examples/php.sh
rootfs/usr/local/share/template-files/config/env/examples/postgres.sh
rootfs/usr/local/share/template-files/config/env/examples/redis.sh
rootfs/usr/local/share/template-files/config/env/examples/services.sh
rootfs/usr/local/share/template-files/config/env/examples/ssl.sh
rootfs/usr/local/share/template-files/config/env/examples/supabase.sh
rootfs/usr/local/share/template-files/config/env/examples/webservers.sh
rootfs/usr/local/share/template-files/config/env/examples/zz-entrypoint.sh
rootfs/usr/local/share/template-files/config/.gitkeep
rootfs/usr/local/share/template-files/data/.gitkeep
rootfs/usr/local/share/template-files/defaults/.gitkeep
2026-06-04 14:41:57 -04:00
jason 9a193fe6e8 🐛 Explicitly install curl and ca-certificates in PACK_LIST 🐛
curl was not in PACK_LIST so Alpine fell back to the busybox curl
applet which has limited SSL/TLS support and fails cert validation.
ca-certificates was only installed in 05-custom.sh, making the
dependency implicit. Both are now explicit in PACK_LIST so Alpine
installs the full libcurl binary and Mozilla CA bundle during the
package install phase, before 05-custom.sh even runs.
- Dockerfile: add curl and ca-certificates to PACK_LIST

Dockerfile
2026-05-31 15:46:32 -04:00
jason 98640213a2 🐛 Fall back to hostname -f for GITEA_SERVER when unset 🐛
HOSTNAME resolution now tries hostname -f (FQDN) before falling back
to the short $HOSTNAME, giving a usable ROOT_URL out of the box on
hosts where the FQDN is set in /etc/hosts or DNS.
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: HOSTNAME fallback
chain: GITEA_SERVER → GITEA_HOSTNAME → FULL_DOMAIN_NAME →
hostname -f → $HOSTNAME

rootfs/usr/local/etc/docker/init.d/08-gitea.sh
2026-05-31 15:36:55 -04:00
jason 7cc09e7cfc 🐛 Fix persistent deprecated settings and ROOT_URL mismatch 🐛
Two issues with existing persistent volumes:
1. Deprecated app.ini settings ([cors].X_FRAME_OPTIONS,
[picture].DISABLE_GRAVATAR, [picture].ENABLE_FEDERATED_AVATAR) were
baked into the volume config from the old template and never removed
on subsequent container starts.
2. ROOT_URL/DOMAIN/SSH_DOMAIN were substituted once on first run from
the container hostname and never updated when GITEA_SERVER/GITEA_PROTO
env vars changed, causing the "Mismatched ROOT_URL" warning.
Fix: add migration + dynamic resync in __update_conf_files (08-gitea.sh)
that runs on every startup against both the persistent (/config/gitea)
and runtime (/etc/gitea) copies of app.ini, so changes take effect
immediately without a second restart.
Set GITEA_PROTO=https and GITEA_SERVER=git.casjay.work to populate
the correct ROOT_URL at container start.
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: add dynamic ROOT_URL
resync and deprecated-setting removal to __update_conf_files

rootfs/usr/local/etc/docker/init.d/08-gitea.sh
2026-05-31 15:34:40 -04:00
jason a3296f475f 🐛 Fix SSL errors for repository migrations 🐛
SSL interception on this network presents certificates without SANs
for the target hostname, breaking git clone operations during Gitea
migrations. Add migration and git-level TLS bypass settings.
- rootfs/tmp/etc/gitea/app.ini: add [migration] section with SKIP_TLS_VERIFY=true
- rootfs/tmp/etc/gitea/app.ini: add [git.config] http.sslVerify=false

rootfs/tmp/etc/gitea/app.ini
2026-05-31 15:25:56 -04:00
jason 185f264caf 📝 update README.md 📝
- Refresh README content with latest project changes

README.md
2026-05-31 14:46:46 -04:00
jason 0abc43bffc 🐛 Fix act_runner registration order 🐛
Runners were launched in parallel subshells with only a 2-second gap
between them. act_runner register is a network call; if Gitea was
still warming up any registration could race past an earlier one,
causing Gitea to assign IDs out of sequence (1,3,2,5,4 instead of
1,2,3,4,5).
Split into two phases: register all runners sequentially first so IDs
are assigned in the correct order, then launch all daemons in parallel
once every runner is confirmed registered.
- rootfs/usr/local/bin/start-runners: split __start_runner into
__register_runner (sequential, phase 1) and __start_runner_daemon
(parallel, phase 2); remove the sleep 2 workaround

rootfs/usr/local/bin/start-runners
2026-05-24 21:37:50 -04:00
jason 755b3db301 🐛 Fix all Gitea v1.26 deprecated config settings 🐛
Resolve all deprecation warnings emitted at runtime by updating
app.ini to use current key names and locations.
- rootfs/tmp/etc/gitea/app.ini: move X_FRAME_OPTIONS from [cors] to [security] (deprecatedSetting v1.26.0)
- rootfs/tmp/etc/gitea/app.ini: remove [picture].DISABLE_GRAVATAR (deprecatedSettingDB since v1.18, use admin panel)
- rootfs/tmp/etc/gitea/app.ini: remove [picture].ENABLE_FEDERATED_AVATAR (deprecatedSettingDB since v1.18, use admin panel)
- rootfs/tmp/etc/gitea/app.ini: rename [lfs].LFS_CONTENT_PATH → PATH (was silently ignored; correct key is PATH)
- rootfs/tmp/etc/gitea/app.ini: rename [git].MAX_GIT_DIFF_LINE_CHARACTER_COUNT → MAX_GIT_DIFF_LINE_CHARACTERS (correct struct field name)
- rootfs/tmp/etc/gitea/app.ini: remove LOG_ROTATE/DAILY_ROTATE/MAX_DAYS from [log] root section (only valid in file-writer sub-sections; dead config with MODE=console)

.claude/settings.local.json
rootfs/tmp/etc/gitea/app.ini
2026-05-24 21:18:57 -04:00
jason ae8a7583a8 🔧 Harden gitea binary download in 05-custom.sh 🔧
Fix SSL and rate-limit failures when downloading gitea during docker build.
The GitHub REST API is rate-limited at 60 req/hour for unauthenticated
requests from Docker BuildKit's outgoing IP. Additionally, BuildKit resolves
github.com via the host DNS which may return an IPv6 address served by a
transparent proxy, causing TLS cert verification failures (error 60: "no
alternative certificate subject name matches target hostname 'github.com'").
Changes:
- rootfs/root/docker/setup/05-custom.sh: replace JSON API version lookup
with a redirect-follow approach (curl -4sfL -o /dev/null -w %{url_effective})
that avoids the rate-limited /releases/latest API endpoint entirely
- rootfs/root/docker/setup/05-custom.sh: add -4 (IPv4-only) flag to all
github.com curl calls to bypass intercepted IPv6 DNS resolutions
- rootfs/root/docker/setup/05-custom.sh: add explicit ca-certificates
install and update-ca-certificates before any HTTPS downloads, since
the base image cert bundle may be stale after system upgrade

rootfs/root/docker/setup/05-custom.sh
2026-05-24 20:53:40 -04:00
jason 7668154e67 🐛 Fix silent download failure and cosmetic naming bugs 🐛
Fixes three bugs discovered during live container testing.
The critical bug was a bash post-increment no-op: `exitCode=$((exitCode++))`
assigns the *old* value back to the variable, so exitCode stays 0 even
when a download fails. This caused the Docker build to succeed silently
when the gitea binary download failed, publishing a broken image to Docker Hub.
- rootfs/root/docker/setup/05-custom.sh: change exitCode=$((exitCode++)) to
exitCode=$((exitCode + 1)) in both the gitea and act_runner failure handlers
- rootfs/usr/local/bin/entrypoint.sh: change CONTAINER_NAME and description
from "archlinux" (copied template default) to "gitea"
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: remove leading space from
[ -d " /config/ssh" ] path test so the directory existence check is correct

.claude/
rootfs/root/docker/setup/05-custom.sh
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/08-gitea.sh
2026-05-24 19:58:15 -04:00
jason 04b36738f6 📝 Update README with complete Docker run documentation 📝
Rewrite README.md to accurately reflect the container's three bundled
services (Gitea, dockerd DinD, act_runner) and all required runtime
details that were missing from the previous sparse version.
- README.md: add full description of Gitea + DinD + act_runner all-in-one image
- README.md: add --privileged note explaining DinD cgroup requirement
- README.md: document all four ports (80/7833/2375/44015) with service labels
- README.md: add volumes table (/config, /data) with descriptions
- README.md: add environment variables table (TZ, SERVER_ADDRESS, SERVER_TOKEN, RUNNER_LABELS, RUNNERS_START, RUNNERS_LOG_DIR)
- README.md: update docker-compose with all ports and privileged flag
- README.md: add docker-compose YYMM date tag convention note
- README.md: follow canonical section order (Docker → Development → License)

README.md
2026-05-24 19:42:34 -04:00
jason 895520eb77 🐛 Fix runner config filenames, cache-server, and registration log 🐛
Three more bugs found during full component verification:
1. RUNNER_CONFIG_DEFAULT pointed to config.yaml but the actual
template filename is default_config.yaml — gitea named runner
never registered because the file-existence check always failed.
2. CACHE_CONFIG_FILE pointed to cache.yaml but the actual template
filename is cache_server.yaml — cache-server launch always
skipped silently.
3. act_runner v1.0.6 requires cache.external_secret on both the
cache-server and any runner using external_server; neither config
had it, so cache-server exited immediately and runner registration
failed when external_server was present in default_config.yaml.
4. Registration log redirect was 2>/dev/stdout >>"$log" (stderr went
to original stdout, not the log); corrected to >>"$log" 2>&1.
- rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh:
- RUNNER_CONFIG_DEFAULT: config.yaml → default_config.yaml
- CACHE_CONFIG_FILE: cache.yaml → cache_server.yaml
- fix registration log redirect: >>"$RUNNER_LOG_FILE" 2>&1
- rootfs/tmp/etc/act_runner/default_config.yaml: remove
external_server (no shared secret configured; each runner uses
its own internal cache)
- rootfs/tmp/etc/act_runner/cache_server.yaml: set enabled: false
(cache-server requires external_secret; disabled until a proper
shared-secret setup is added)
Verified: 6 daemons on fresh start (1 gitea named + 5 runners), all
with 22 labels; clean reconnect on restart with no re-registration.

rootfs/tmp/etc/act_runner/cache_server.yaml
rootfs/tmp/etc/act_runner/default_config.yaml
rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
2026-05-24 15:16:16 -04:00
jason e8021e29e2 🐛 Fix act_runner token generation and gitea auto-install 🐛
Runner registration was broken by three compounding bugs:
1. Token generated at script init time (before gitea was ready)
2. gitea CLI missing --work-path/--custom-path flags, writing fatal
log messages to stdout which got captured as the token value
3. Token assignment inside a piped subshell didn't propagate back
to the parent shell, leaving SYS_AUTH_TOKEN empty at runtime
4. INSTALL_LOCK=false in app.ini template caused gitea to start in
install-wizard mode, making generate-runner-token always fail
- rootfs/tmp/etc/gitea/app.ini: set INSTALL_LOCK=true so gitea
auto-initializes the SQLite DB on first run
- rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh:
- defer SYS_AUTH_TOKEN: initialize to empty at global scope,
generate in __run_pre_execute_checks after gitea is confirmed up
- add --work-path/--custom-path to gitea CLI call; filter output
with grep -oE '[A-Za-z0-9]{20,}' to extract only the token
- guard token generation on INSTALL_LOCK=true in app.ini
- read token back from $CONF_DIR/tokens/system after the piped
__run_pre_execute_checks call returns (subshell escape)
Tested: fresh start registers all 5 runners with full 22-label set;
restart skips re-registration and reconnects all 5 daemons cleanly.

rootfs/tmp/etc/gitea/app.ini
rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
2026-05-24 14:11:11 -04:00
jason 3a21cd6091 🐛 Fix generated start script: empty su_exec produces '' command prefix 🐛
When su_exec is empty (service runs as root, no user-switching needed),
printf '%q ' $su_exec expands to the literal string '' which gets embedded
in the generated start script as a command prefix, causing bash to try
executing a program named '' and failing immediately. Also add explicit
PATH and HOME exports to the RESET_ENV=no generated script so services
are not dependent on environment inheritance.
- rootfs/usr/local/etc/docker/init.d/05-dockerd.sh: fix _q_su assignment
in both RESET_ENV branches to use ${su_exec:+...} so it's empty string
(not '') when su_exec is empty; fix format string %s%s (no space between
su and cmd, su already carries trailing space); add PATH and HOME exports
to RESET_ENV=no generated script
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: same fixes
- rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh: same fixes

rootfs/usr/local/etc/docker/init.d/05-dockerd.sh
rootfs/usr/local/etc/docker/init.d/08-gitea.sh
rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
2026-05-24 13:00:24 -04:00
jason e599f1edc8 🐛 Fix start-runners: wrong --config arg kept all runners permanently offline 🐛
The daemon was called with --config pointing at the .runner registration
state file (JSON), not a YAML config. act_runner rejected it immediately
on every start, so all runners were always offline and never reconnected.
Also fix log truncation and stale fallback labels.
- rootfs/usr/local/bin/start-runners: remove --config from act_runner
daemon invocation (act_runner finds .runner in CWD automatically after
cd "$runner_dir"); fix __log to append (>>) instead of truncate (>);
update fallback RUNNER_LABELS to match the full label set defined in
zz-act_runner.sh

rootfs/usr/local/bin/start-runners
2026-05-24 12:32:25 -04:00
jason 1f84972d9d 🗑️ Remove scaffolding template 00-server01.sh 🗑️
Was added as a reference artifact during framework migration work
and should not live in the repo.
- rootfs/usr/local/etc/docker/init.d/00-server01.sh: deleted

rootfs/usr/local/etc/docker/init.d/00-server01.sh
2026-05-24 12:24:36 -04:00
jason d74ff680d2 🐛 Fix undefined variables and ordering bugs in act_runner init script 🐛
Fix all undefined variable references and logic errors that would
prevent runner registration and daemon startup from working.
- rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh: fix GITEA_USER
typo (missing $ before SERVICE_USER); define 9 previously undefined
variables: RUNNER_IP_ADDRESS, RUNNER_CONFIG_DEFAULT, RUNNER_DEFAULT_HOME,
RUNNER_CONFIG_NAME, RUNNER_LOG_FILE, RUNNER_DAEMON_LOG, RUNNER_CACHE_HOST,
CACHE_CONFIG_FILE, CACHE_LOG_FILE; swap ctime/waitTime local declarations
so ctime is defined before waitTime uses it; quote act_runner daemon and
cache-server --config paths

rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
2026-05-24 12:23:38 -04:00
jason 4d51cc0e7c 🔧 Sync template framework updates and fix app.ini config 🔧
Bring all init scripts and support files up to the latest docker
template framework, and fully configure gitea's app.ini for a
performant, open, reverse-proxy-aware deployment.
- rootfs/tmp/etc/gitea/app.ini: add missing sections ([server],
[cache], [queue], [git], [git.timeout], [api], [webhook],
[indexer], [session], [oauth2], [metrics], [repository.release]);
raise MAX_RESPONSE_ITEMS=500; set PROTOCOL=http, HTTP_ADDR=0.0.0.0,
USE_PROXY_PROTOCOL=false; INSTALL_LOCK=false; tune DB/session/security
- rootfs/usr/local/bin/entrypoint.sh: direct template sync — new trap
style, SSL_CA fix, ENTRYPOINT_PID_FILE path, mapfile, __netstat call
- rootfs/usr/local/etc/docker/functions/entrypoint.sh: direct template
sync — add __log_debug/info/warn/error; improve __netstat, __mkdir,
__rm, __grep_test (639 changed lines)
- rootfs/usr/local/etc/docker/init.d/00-server01.sh: new generic
template/example init.d service script
- rootfs/usr/local/etc/docker/init.d/05-dockerd.sh: framework update —
__trap_err_handler ERR handler, SIGPWR split, enabled-check expanded,
debug if/else, env loop guard, $(<...) PID read, __check_service guard,
__run_start_script rewrite (printf %q, md5sum hash, bash launcher),
errorCode=${PIPESTATUS[0]}, remove unconditional SERVICE_EXIT_CODE=0,
fix __post_execute fire-and-forget
- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: same framework updates
as 05-dockerd.sh, service-specific content preserved
- rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh: same framework
updates; service-specific __post_execute daemon/cache-server logic kept
- rootfs/root/docker/setup/00-init.sh: version stamp sync
- rootfs/root/docker/setup/01-system.sh: version stamp sync
- rootfs/root/docker/setup/02-packages.sh: version stamp sync
- rootfs/root/docker/setup/03-files.sh: header-only patch, gitea-specific
body preserved
- rootfs/root/docker/setup/04-users.sh: version stamp sync
- rootfs/root/docker/setup/05-custom.sh: header-only patch, gitea/act_runner
binary download logic preserved
- rootfs/root/docker/setup/06-post.sh: version stamp sync
- rootfs/root/docker/setup/07-cleanup.sh: version stamp sync
- rootfs/usr/local/share/template-files/config/env/default.sample:
ENTRYPOINT_PID_FILE path → /run/init.d/entrypoint.pid
- rootfs/usr/local/share/template-files/config/env/examples/zz-entrypoint.sh:
ENTRYPOINT_PID_FILE path → /run/init.d/entrypoint.pid

rootfs/root/docker/setup/00-init.sh
rootfs/root/docker/setup/01-system.sh
rootfs/root/docker/setup/02-packages.sh
rootfs/root/docker/setup/03-files.sh
rootfs/root/docker/setup/04-users.sh
rootfs/root/docker/setup/05-custom.sh
rootfs/root/docker/setup/06-post.sh
rootfs/root/docker/setup/07-cleanup.sh
rootfs/tmp/etc/gitea/app.ini
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/00-server01.sh
rootfs/usr/local/etc/docker/init.d/05-dockerd.sh
rootfs/usr/local/etc/docker/init.d/08-gitea.sh
rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
rootfs/usr/local/share/template-files/config/env/default.sample
rootfs/usr/local/share/template-files/config/env/examples/zz-entrypoint.sh
2026-05-24 12:19:59 -04:00
jason 4fc5a83354 🗃️ Removed the .claude/settings.local.json 🗃️
Dockerfile
.env.scripts
.gitattributes
.gitea/workflows/docker.yaml
.gitignore
LICENSE.md
README.md
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/bin/pkmgr
2026-05-12 20:06:34 -04:00
jason 8f8cb303f9 🗃️ rootfs: shield internal entrypoint PID files from /run/*.pid sweeps 🗃️
Update the embedded entrypoint copies in rootfs/ to match the
upstream template change. Internal state files renamed to dotfiles
so they're not matched by `/run/*.pid` cleanup globs:
- /run/init.d/entrypoint.pid -> /run/.entrypoint.pid
- /run/no_exit.pid -> /run/.no_exit.pid
- /run/backup.pid -> /run/.backup.pid
- /run/__start_init_scripts.pid -> /run/.start_init_scripts.pid
Per-service PIDs in /run/init.d/ are unchanged.

rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/05-dockerd.sh
rootfs/usr/local/etc/docker/init.d/08-gitea.sh
rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
rootfs/usr/local/share/template-files/config/env/default.sample
rootfs/usr/local/share/template-files/config/env/examples/zz-entrypoint.sh
2026-05-05 19:11:44 -04:00
jason 3dc89312eb 🗃️ readme: rename rootfs/ to volumes/ for compose context 🗃️
Aligns README install/run snippets with the new convention split:
rootfs/ for Dockerfile-build content (image filesystem), volumes/
for docker-compose host bind-mounts. Compose mounts, host bind
paths, and runtime data dirs are renamed; Dockerfile COPY/ADD
sources (where present) are preserved.

README.md
2026-05-05 14:34:56 -04:00
jason 729f003d43 🔧 Update configuration files 🔧
.claude/settings.local.json
2026-04-26 02:55:33 -04:00
jason 3c8cdd11fe 🗃️ Update codebase 🗃️
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2025-11-30 16:25:31 -05:00
jason e8ff6f5b08 🐳 Enhancement: Entrypoint Script Modifications for Docker Containers 🐳
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2025-11-30 16:01:56 -05:00
jason b9d56bbcb9 🗃️ Update codebase 🗃️
rootfs/tmp/etc/docker/daemon.json
rootfs/usr/local/etc/docker/init.d/05-dockerd.sh
2025-11-29 16:01:40 -05:00
jason 63d18bb750 🔧 Update configuration files 🔧
.claude/
Dockerfile
.env.scripts
rootfs/tmp/etc/docker/daemon.json
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/05-dockerd.sh
2025-11-29 15:48:20 -05:00
jason a46ba76ca9 🗃️ Update codebase 🗃️
rootfs/usr/local/etc/docker/init.d/08-gitea.sh
rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
2025-11-29 15:21:51 -05:00
jason 265f823955 🗃️ Update codebase 🗃️
rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh
2025-11-29 14:41:59 -05:00
jason ef6d219131 🗃️ Update codebase 🗃️
rootfs/usr/local/etc/docker/init.d/08-gitea.sh
2025-11-29 14:30:40 -05:00
jason 3abf0704ee 🗃️ Update codebase 🗃️
rootfs/usr/local/etc/docker/init.d/08-gitea.sh
2025-11-29 13:32:03 -05:00