From 5b4079dc4107d90397008e9d6479c14000c22a1b Mon Sep 17 00:00:00 2001 From: casjay Date: Sat, 3 Oct 2026 11:28:28 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Set=20sane=20Gitea=20retention?= =?UTF-8?q?=20and=20cleanup=20defaults=20=F0=9F=94=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shorter Actions retention and enable Gitea's built-in cleanup cron tasks. Existing configs receive missing keys only; user-set values are never overwritten. - rootfs/tmp/etc/gitea/app.ini: artifacts 30d, logs 90d, runs 180d; enable gc_lfs, git_gc_repos, delete_old_actions, delete_old_system_notices; explicit cleanup_actions/cleanup_action_runs - rootfs/usr/local/etc/docker/init.d/08-gitea.sh: add __gitea_ini_default and apply retention/cron defaults to existing configs when missing - README.md: document retention defaults - TODO.AI.md: record the change and its verification Claude-Session: https://claude.ai/code/session_01Kae22tmhzhmfHyqc34PZbx --- README.md | 5 +++ TODO.AI.md | 10 +++++ rootfs/tmp/etc/gitea/app.ini | 37 ++++++++++++++++++- .../usr/local/etc/docker/init.d/08-gitea.sh | 25 +++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ebc6a8..89c475c 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,11 @@ public hostname and keep `GITEA_PROTO=https`; Gitea keeps listening on plain htt `Secure`, and the proxy must forward `Host` and `X-Forwarded-Proto`. Use `GITEA_ROOT_URL` for a non-standard port or sub-path. +**Retention** — Actions artifacts are kept 30 days, job logs 90 days and run history 180 days. +Gitea's cron also garbage-collects orphaned LFS objects daily, runs `git gc` weekly, and prunes +activity-feed entries older than 1 year and system notices older than 90 days. Edit +`/config/gitea/app.ini` to change these; existing values are never overwritten on startup. + **act\_runner** | Variable | Default | Description | diff --git a/TODO.AI.md b/TODO.AI.md index c8c567e..b3ee46e 100644 --- a/TODO.AI.md +++ b/TODO.AI.md @@ -7,6 +7,16 @@ and the container exits 1 (empty days value passed to `openssl req -days`). The file is generated, so the fix belongs in the upstream gen-dockerfile template, then regenerate. +## Fixed — Gitea retention/cleanup defaults (app.ini, 08-gitea.sh) + +- Template: `[actions]` artifacts 30d, logs 90d, runs 180d; enabled `cron.gc_lfs` (daily), + `cron.git_gc_repos` (weekly, 30m timeout), `cron.delete_old_actions` (1y), + `cron.delete_old_system_notices` (90d); explicit `cron.cleanup_actions`/`cleanup_action_runs`. +- `08-gitea.sh` adds `__gitea_ini_default` (set only if the key is missing) so existing configs pick + these up without overriding user values (existing `ARTIFACT_RETENTION_DAYS` is left as-is). +- Verified: upgrade of the previous template is idempotent and keeps a custom value; fresh container's + `/api/v1/admin/cron` lists all tasks with the expected schedules, no config warnings in gitea.log. + ## Fixed — reverse-proxy/passkey support: ROOT_URL decoupled from listen protocol (08-gitea.sh) - Commit `7741c06` made `[server] PROTOCOL` follow `SERVICE_PROTOCOL` (default `https`), so a fresh diff --git a/rootfs/tmp/etc/gitea/app.ini b/rootfs/tmp/etc/gitea/app.ini index d281661..cf8c46e 100644 --- a/rootfs/tmp/etc/gitea/app.ini +++ b/rootfs/tmp/etc/gitea/app.ini @@ -250,7 +250,9 @@ NO_REPLY_ADDRESS = no-reply.REPLACE_SE [actions] ENABLED = true DEFAULT_ACTIONS_URL = github -ARTIFACT_RETENTION_DAYS = 90 +ARTIFACT_RETENTION_DAYS = 30 +LOG_RETENTION_DAYS = 90 +RUN_RETENTION_DAYS = 180 ZOMBIE_TASK_TIMEOUT = 10m ENDLESS_TASK_TIMEOUT = 3h ABANDONED_JOB_TIMEOUT = 24h @@ -381,3 +383,36 @@ RUN_AT_START = false ENABLE_SUCCESS_NOTICE = true SCHEDULE = @every 168h HTTP_ENDPOINT = https://dl.gitea.io/gitea/version.json +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[cron.cleanup_actions] +ENABLED = true +SCHEDULE = @midnight +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[cron.cleanup_action_runs] +ENABLED = true +SCHEDULE = @midnight +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[cron.gc_lfs] +ENABLED = true +RUN_AT_START = false +SCHEDULE = @every 24h +OLDER_THAN = 168h +LAST_UPDATED_MORE_THAN_AGO = 72h +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[cron.git_gc_repos] +ENABLED = true +RUN_AT_START = false +SCHEDULE = @every 168h +TIMEOUT = 30m +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[cron.delete_old_actions] +ENABLED = true +RUN_AT_START = false +SCHEDULE = @every 168h +OLDER_THAN = 8760h +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[cron.delete_old_system_notices] +ENABLED = true +RUN_AT_START = false +SCHEDULE = @every 168h +OLDER_THAN = 2160h diff --git a/rootfs/usr/local/etc/docker/init.d/08-gitea.sh b/rootfs/usr/local/etc/docker/init.d/08-gitea.sh index a4714f0..29b4287 100755 --- a/rootfs/usr/local/etc/docker/init.d/08-gitea.sh +++ b/rootfs/usr/local/etc/docker/init.d/08-gitea.sh @@ -137,6 +137,19 @@ __gitea_ini_set() { ' "$ini_file" >"$tmp_file" && cat "$tmp_file" >"$ini_file" rm -f "$tmp_file" } +# Set KEY = VALUE inside [SECTION] only when the key is not already present (keeps user choices) +__gitea_ini_default() { + local ini_file="$1" section="$2" key="$3" value="$4" + [ -f "$ini_file" ] || return 1 + if awk -v s="[$section]" -v k="$key" ' + /^\[/ { in_s = ($0 == s) } + in_s && $0 ~ "^" k "[[:space:]]*=" { found = 1; exit } + END { exit !found } + ' "$ini_file"; then + return 0 + fi + __gitea_ini_set "$ini_file" "$section" "$key" "$value" +} # - - - - - - - - - - - - - - - - - - - - - - - - - # Script to execute START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME" @@ -453,6 +466,18 @@ __update_conf_files() { https://*) __gitea_ini_set "$_ini_file" session COOKIE_SECURE true ;; *) __gitea_ini_set "$_ini_file" session COOKIE_SECURE false ;; esac + # Retention/cleanup defaults for configs created before they were added to the template + __gitea_ini_default "$_ini_file" actions LOG_RETENTION_DAYS 90 + __gitea_ini_default "$_ini_file" actions RUN_RETENTION_DAYS 180 + __gitea_ini_default "$_ini_file" cron.gc_lfs ENABLED true + __gitea_ini_default "$_ini_file" cron.gc_lfs SCHEDULE "@every 24h" + __gitea_ini_default "$_ini_file" cron.git_gc_repos ENABLED true + __gitea_ini_default "$_ini_file" cron.git_gc_repos SCHEDULE "@every 168h" + __gitea_ini_default "$_ini_file" cron.git_gc_repos TIMEOUT 30m + __gitea_ini_default "$_ini_file" cron.delete_old_actions ENABLED true + __gitea_ini_default "$_ini_file" cron.delete_old_actions OLDER_THAN 8760h + __gitea_ini_default "$_ini_file" cron.delete_old_system_notices ENABLED true + __gitea_ini_default "$_ini_file" cron.delete_old_system_notices OLDER_THAN 2160h sed -i "s|^DOMAIN[[:space:]]*=.*|DOMAIN = ${SERVER_NAME}|" "$_ini_file" sed -i "s|^SSH_DOMAIN[[:space:]]*=.*|SSH_DOMAIN = ${SERVER_NAME}|" "$_ini_file" # Remove deprecated [cors].X_FRAME_OPTIONS (moved to [security] in Gitea v1.26)