diff --git a/plan/22-migration.md b/plan/22-migration.md index 6f311ef..9d0506d 100644 --- a/plan/22-migration.md +++ b/plan/22-migration.md @@ -153,6 +153,41 @@ cochi's copy. Rolling back to cochi then **silently loses** those new accounts/skins. Safe for hours as a fallback; not for weeks. If you must roll back after real use, re-export from oxps and re-import onto cochi first. +## Troubleshooting + +### minecraft crash-loops on a fresh host: `AccessDeniedException: /data/kubejs/config` + +Symptom (in `docker compose logs minecraft`), restarting every ~15s: + +``` +java.nio.file.AccessDeniedException: /data/kubejs/config +Caused by: NullPointerException: Cannot invoke "...ConsoleJS.error(...)" + because "dev.latvian.mods.kubejs.script.ConsoleJS.STARTUP" is null +``` + +**Cause.** The compose file bind-mounts the kubejs *source* subdirs read-only +(`server_scripts`, `startup_scripts`, `data`, `assets`). To place those mounts, +Docker auto-creates their parent `/data/kubejs` — and on a **fresh `mc_data` +volume** it creates it as **root:root**. The itzg container runs as **uid 1000**, +so KubeJS can't create its writable siblings (`config/`, `cache/`, `generated/`, +`logs/`) → init aborts → `ConsoleJS.STARTUP` stays null → NPE → exit 1. + +This only bites a **fresh world** (migration, new host, wiped `mc_data`). On an +aged host like cochi `/data/kubejs` predates the ro submounts and is already +1000-owned, so it never surfaced there. + +**Fix** — chown the dir to 1000 once (durable; survives restarts): + +```bash +docker compose stop minecraft +docker run --rm -v _mc_data:/data alpine chown 1000:1000 /data/kubejs +docker compose up -d minecraft +``` + +`` is the checkout dir basename (e.g. `ulicraft-server`). Distinct from +the "don't mount the whole kubejs dir ro" gotcha in `plan/05-minecraft.md` — same +mod, different trigger (ownership of the auto-created parent, not a ro root). + ## Re-running / testing Everything is idempotent-ish and safe to rehearse: diff --git a/tooling/migrate-import.sh b/tooling/migrate-import.sh index b8db4b2..1ef0e73 100755 --- a/tooling/migrate-import.sh +++ b/tooling/migrate-import.sh @@ -176,6 +176,14 @@ Remaining manual steps (see plan/22-migration.md for detail): 7. Bring it up: ./update-all.sh --hard 8. Re-op players once they've joined: docker compose exec minecraft rcon-cli op +Fresh-world gotcha: if minecraft crash-loops on a fresh mc_data with + "AccessDeniedException: /data/kubejs/config" (ConsoleJS.STARTUP null), Docker + created /data/kubejs as root while the container runs as uid 1000. Fix once: + docker compose stop minecraft + docker run --rm -v ${PROJ}_mc_data:/data alpine chown 1000:1000 /data/kubejs + docker compose up -d minecraft + Details: plan/22-migration.md (Troubleshooting). + Rollback note: same domain means DNS points at ONE host. Once a player registers or changes a skin here, this drasl.db diverges from cochi — rolling back to cochi silently loses those changes. Keep the fallback window short.