🐛 Never overwrite existing config when seeding /config 🐛
gitea / release-gitea (push) Successful in 18m49s

Without the .initialized marker, startup copied the baked template
over existing files in /config, resetting app.ini and regenerating
secrets. Seeding now only adds files that are missing.

- rootfs/usr/local/etc/docker/init.d/08-gitea.sh: seed copy uses cp -Rn instead of cp -Rf
- rootfs/usr/local/etc/docker/init.d/05-dockerd.sh: same change, protects a user-edited daemon.json
- rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh: same change, protects user-edited runner config
- TODO.AI.md: record the bug, the verification, and the upstream template follow-up

Claude-Session: https://claude.ai/code/session_01Kae22tmhzhmfHyqc34PZbx
This commit is contained in:
casjay committed 2026-10-03 20:12:40 -04:00
1 parent 5b4079dc41
commit 246fb4494c
4 files changed
+15 -4

No files matched your search

+11
View File
@@ -7,6 +7,17 @@
and the container exits 1 (empty days value passed to `openssl req -days`). The file is 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. generated, so the fix belongs in the upstream gen-dockerfile template, then regenerate.
## Fixed — startup overwrote user config when `.initialized` marker was missing (init.d seed copy)
- `__run_precopy` in `08-gitea.sh`, `05-dockerd.sh` and `zz-act_runner.sh` did
`cp -Rf "$ETC_DIR/." "$CONF_DIR/"` whenever `$CONF_DIR/.initialized` was absent (since commit
`42d0439`), replacing an existing `app.ini` with the template: custom settings lost and
SECRET_KEY/INTERNAL_TOKEN/LFS_JWT_SECRET regenerated. Now `cp -Rn` (fills missing files, never
overwrites). Verified with a real 428-line `app.ini` and no marker: all lines and all four secrets
preserved; before the fix the same test changed SECRET_KEY and INTERNAL_TOKEN.
- The same `__run_precopy` block is generated: the upstream start-service template needs the same
`cp -Rn` change or the next regeneration will bring the bug back.
## Fixed — Gitea retention/cleanup defaults (app.ini, 08-gitea.sh) ## Fixed — Gitea retention/cleanup defaults (app.ini, 08-gitea.sh)
- Template: `[actions]` artifacts 30d, logs 90d, runs 180d; enabled `cron.gc_lfs` (daily), - Template: `[actions]` artifacts 30d, logs 90d, runs 180d; enabled `cron.gc_lfs` (daily),
@@ -279,7 +279,7 @@ __run_precopy() {
if [ -d "$ETC_DIR" ] && ! [ -L "$ETC_DIR" ]; then if [ -d "$ETC_DIR" ] && ! [ -L "$ETC_DIR" ]; then
if [ ! -f "$CONF_DIR/.initialized" ]; then if [ ! -f "$CONF_DIR/.initialized" ]; then
mkdir -p "$CONF_DIR" mkdir -p "$CONF_DIR"
cp -Rf "$ETC_DIR/." "$CONF_DIR/" 2>/dev/null || true cp -Rn "$ETC_DIR/." "$CONF_DIR/" 2>/dev/null || true
fi fi
rm -Rf "$ETC_DIR" rm -Rf "$ETC_DIR"
ln -sf "$CONF_DIR" "$ETC_DIR" ln -sf "$CONF_DIR" "$ETC_DIR"
@@ -345,7 +345,7 @@ __run_precopy() {
# during container startup, after the entrypoint's initial copy. Applying it here # during container startup, after the entrypoint's initial copy. Applying it here
# (in the init.d phase) ensures it takes effect after Docker finishes network setup. # (in the init.d phase) ensures it takes effect after Docker finishes network setup.
[ -f "/usr/local/etc/resolv.conf" ] && cp -f "/usr/local/etc/resolv.conf" "/etc/resolv.conf" 2>/dev/null || true [ -f "/usr/local/etc/resolv.conf" ] && cp -f "/usr/local/etc/resolv.conf" "/etc/resolv.conf" 2>/dev/null || true
# Seed /config/$SERVICE_NAME from the baked /etc copy on first initialisation only. # Seed /config/$SERVICE_NAME from the baked /etc copy on first initialisation only; cp -n never overwrites existing user files.
# The marker file $CONF_DIR/.initialized is written after substitution completes; # The marker file $CONF_DIR/.initialized is written after substitution completes;
# delete it to force a re-seed (e.g. after intentional config reset). # delete it to force a re-seed (e.g. after intentional config reset).
# Then replace the /etc/$SERVICE_NAME directory with a symlink to /config/$SERVICE_NAME # Then replace the /etc/$SERVICE_NAME directory with a symlink to /config/$SERVICE_NAME
@@ -353,7 +353,7 @@ __run_precopy() {
if [ -d "$ETC_DIR" ] && ! [ -L "$ETC_DIR" ]; then if [ -d "$ETC_DIR" ] && ! [ -L "$ETC_DIR" ]; then
if [ ! -f "$CONF_DIR/.initialized" ]; then if [ ! -f "$CONF_DIR/.initialized" ]; then
mkdir -p "$CONF_DIR" mkdir -p "$CONF_DIR"
cp -Rf "$ETC_DIR/." "$CONF_DIR/" 2>/dev/null || true cp -Rn "$ETC_DIR/." "$CONF_DIR/" 2>/dev/null || true
fi fi
rm -Rf "$ETC_DIR" rm -Rf "$ETC_DIR"
ln -sf "$CONF_DIR" "$ETC_DIR" ln -sf "$CONF_DIR" "$ETC_DIR"
@@ -379,7 +379,7 @@ __run_precopy() {
if [ -d "$ETC_DIR" ] && ! [ -L "$ETC_DIR" ]; then if [ -d "$ETC_DIR" ] && ! [ -L "$ETC_DIR" ]; then
if [ ! -f "$CONF_DIR/.initialized" ]; then if [ ! -f "$CONF_DIR/.initialized" ]; then
mkdir -p "$CONF_DIR" mkdir -p "$CONF_DIR"
cp -Rf "$ETC_DIR/." "$CONF_DIR/" 2>/dev/null || true cp -Rn "$ETC_DIR/." "$CONF_DIR/" 2>/dev/null || true
fi fi
rm -Rf "$ETC_DIR" rm -Rf "$ETC_DIR"
ln -sf "$CONF_DIR" "$ETC_DIR" ln -sf "$CONF_DIR" "$ETC_DIR"