Commit Graph
32 Commits
Author SHA1 Message Date
jason b53c36f33d 🐛 Fix opengist external-url never being substituted 🐛
Found while build-testing the freshly regenerated image in a temp
data/config dir: opengist served REPLACE_HOSTNAME literally in every
generated URL, and http.git-enabled routes redirected to bogus paths,
because __update_conf_files() was patching a config file
($ETC_DIR/opengist.yaml) that doesn't exist -- the shipped config is
named config.yaml. Also normalized the substituted value: opengist's
external-url must be a full URL (scheme+host), not a bare hostname,
or it breaks absolute-URL/redirect generation; ssh.external-domain
must stay a bare domain, so it now gets its own REPLACE_SSH_HOSTNAME
token instead of reusing the schemed value.

Verified via: docker build, then a container run against a scratch
temp dir with data/config volumes -- health check reports healthy,
config.yaml shows the correct external-url/ssh.external-domain, and
/-/all, /-/login, /-/register all return 200 with real opengist HTML.

- rootfs/usr/local/etc/docker/init.d/00-opengist.sh: __update_conf_files
  now targets $ETC_DIR/config.yaml (was opengist.yaml, a nonexistent
  file), prefixes sysname with http:// when no scheme is present for
  external-url, and replaces ssh.external-domain via a separate
  REPLACE_SSH_HOSTNAME token using the unschemed hostname
- rootfs/tmp/etc/opengist/config.yaml: ssh.external-domain placeholder
  changed from REPLACE_HOSTNAME to REPLACE_SSH_HOSTNAME
2026-08-03 11:37:00 -04:00
jason d8b9bd2a4f Update to latest docker template revision
- .env.scripts: synced version stamp to current template; preserved ENV_PULL_URL=casjaysdev/alpine (gen-dockerfile's --update path had a bug computing "alpine" instead, corrected manually per the casjaysdevdocker->casjaysdev/* base-image convention)
- rootfs/usr/local/bin/entrypoint.sh: regenerated from current template; fixes stale CONTAINER_NAME="alpine" -> "opengist" and normalizes whitespace
- rootfs/usr/local/etc/docker/functions/entrypoint.sh: replaced from template; picks up upstream fix for __symlink/__initialize_ssl_certs returning nonzero on success under set -e
- rootfs/root/docker/setup/00-init.sh, 01-system.sh, 02-packages.sh, 03-files.sh, 04-users.sh, 06-post.sh, 07-cleanup.sh: version stamp bump only, no logic change
- rootfs/root/docker/setup/05-custom.sh: version stamp bump only; restored the opengist binary download/install logic that the template regeneration would have wiped (this file is app-specific, not boilerplate)
2026-08-03 11:05:14 -04:00
jason 5b995c205b 🐛 Fix database dir excluded from permission fixup, causing restart loop 🐛
Root cause: the `git` service user's UID is assigned dynamically (random,
non-persistent across container recreations), and __fix_permissions
re-chowns APPLICATION_DIRS on every startup to whatever UID `git`
currently has. However DATABASE_DIR / DATABASE_BASE_DIR (e.g.
/data/db/sqlite for the sqlite backend) live under /data/db, outside
APPLICATION_DIRS ($ETC_DIR $CONF_DIR $DATA_DIR $LOG_DIR $TMP_DIR
$RUN_DIR $VAR_DIR, where DATA_DIR is /data/opengist, not /data). So
whenever the on-disk DB ownership didn't already match the current
`git` UID, it was never corrected, and opengist failed every start
with "attempt to write a readonly database (8)", causing the
container to exit and get restarted indefinitely.

Reproduced against a live instance (git.casjay.work,
casjaysdevdocker/opengist:latest): confirmed via container logs and
`id git` vs `ls -la /data/db/sqlite` that the sqlite file's owning UID
did not match the current `git` UID, and manually chowning it fixed
that boot but the mismatch could recur on any future UID reassignment.
Reproduced locally by pre-seeding a volume with the DB owned by an
arbitrary UID (9999) and confirming, pre-fix, __fix_permissions never
touched it; post-fix, the container's first boot re-chowns it to the
newly assigned `git` UID and opengist starts cleanly.

- rootfs/usr/local/etc/docker/init.d/00-opengist.sh: after the
  database-type case block resolves DATABASE_DIR/DATABASE_BASE_DIR,
  append both to ADD_APPLICATION_DIRS so __fix_permissions picks them
  up on every startup, regardless of database backend
2026-08-03 10:47:06 -04:00
jason b016f1db1d 🐛 Fix container restart loop from set -e propagation 🐛
Build and Push / build (push) Failing after 1s
opengist / release-opengist (push) Failing after 53s
Root cause: many functions in functions/entrypoint.sh ended with a bare,
unguarded `[ "$DEBUGGER" = "on" ] && echo/printf/__service_banner ...`
statement as their last executed line. With DEBUGGER unset (the default
runtime case), the `[ ]` test is false, so the function's implicit
return value is nonzero. Several of these functions (most critically
__symlink, called bare from __setup_mta) are invoked as unguarded
statements from other functions, and the whole entrypoint runs under
`set -eo pipefail`, so the nonzero return aborted the entire script
chain immediately after startup — explaining why the container only
printed the first log line and exited 1, and why it only worked with
DEBUGGER=on (which makes the echo run and return 0, masking the bug).

Verified via two clean docker buildx build + run cycles: before the
fix, `docker inspect` showed the container crash-looping (exit 1,
~3.9s uptime); after, `RestartCount=0 Status=running Health=healthy`
with opengist fully started, DEBUGGER unset.

- rootfs/usr/local/etc/docker/functions/entrypoint.sh: append `|| true`
  to all 26 bare `[ "$DEBUGGER" = "on" ] && ...` statements so their
  result never propagates as the enclosing function's return value
- TODO.AI.md: log 20 pre-existing script-lint findings on the same
  file (missing `--` on grep, missing `local` on a few function-local
  vars, missing VERSION= line) found incidentally while diagnosing
  this bug; deferred as unrelated cleanup, not part of this fix
2026-08-03 09:41:46 -04:00
jason 99554a060e 🐛 Fix opengist download SSL failure in 05-custom.sh 🐛
Docker build was failing with "SSL: no alternative certificate subject
name matches target hostname" when curl resolved api.github.com/
github.com via dual-stack (IPv6-preferring) lookup. Forcing IPv4
(matching the pattern already used in the gitea container's
05-custom.sh) resolves it. Also fixed lint findings surfaced while
touching the file, and a real exit-code bug where the script always
exited 0 regardless of install success/failure.

- rootfs/root/docker/setup/05-custom.sh: add -4 to both curl calls;
  prefix script-local vars with OPENGIST_ (matching setup-script env
  prefix convention, project name not script filename); add -- to
  grep; add matching VERSION= assignment for the ##@Version header;
  fix trailing exit code capture that always exited 0 by exiting
  $OPENGIST_EXITCODE directly instead of overwriting it with $? of an
  unrelated command
2026-08-02 22:12:21 -04:00
jason 5a588e7075 🗃️ Update codebase 🗃️
opengist / release-opengist (push) Failing after 2m12s
Build and Push / build (push) Failing after 29m24s
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2026-08-02 20:43:58 -04:00
jason 77dd33ce22 🐛 Fix entrypoint hang and lost-interpreter bugs 🐛
Build and Push / build (push) Failing after 4s
opengist / release-opengist (push) Failing after 1m26s
- rootfs/usr/local/bin/entrypoint.sh:
  1. The "start all services" gate
     (`if [ "$START_SERVICES" = "yes" ] || [ -z "$1" ]`) always evaluated
     true on a first-run container regardless of $1, because
     START_SERVICES is force-set to "yes" whenever no PID file exists yet.
     Any command passed to `docker run` — `exec ...`, `sh -c ...`,
     `shell`, or an arbitrary program — was swallowed into the
     service-start+monitor branch before reaching the `case "$1"`
     statement that already handles those subcommands, hanging the
     container as a daemon instead of running the given command. Changed
     the condition to `if [ -z "$1" ]` so the daemon branch only fires
     when no command was given at all.
  2. The `*/bin/sh | */bin/bash | bash | sh | shell)` case branch
     unconditionally shifted $1 before `__exec_command "$@"` (a bare
     `exec "$@"`). For `docker run image sh -c 'cmd'` this turned the
     exec into `exec -c cmd` (command not found, exit 127) instead of
     `exec sh -c 'cmd'`. Split the branch: real interpreter names
     (*/bin/sh, */bin/bash, bash, sh) now pass through unshifted; the
     "shell" keyword (not a real interpreter) gets its own branch that
     shifts and prepends "sh" to any remaining args, or falls back to a
     bare `__exec_command` (exec bash -l) when none remain.
  Verified `bash -n` passes. Found and fixed upstream in
  dockersrc/go, confirmed identical in this repo's generated
  entrypoint.sh, and mechanically applied here with the same patch.
2026-07-27 23:15:09 -04:00
jason 653850c1fd 📝 Migrate /var/lib/srv docker paths to /srv in README 📝
Build and Push / build (push) Has been cancelled
opengist / release-opengist (push) Has been cancelled
Update volume mount examples and dockerHome variable from
the old /var/lib/srv/$USER/docker layout to /srv/$USER/docker.
- README.md: update volume path references to /srv/$USER/docker

README.md
rootfs/usr/local/bin/copy
rootfs/usr/local/bin/healthcheck
rootfs/usr/local/bin/symlink
2026-07-10 12:16:48 -04:00
jason 3b463a4bba 🗃️ Update codebase 🗃️
Build and Push / build (push) Failing after 2s
opengist / release-opengist (push) Failing after 2s
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2026-06-26 23:51:32 -04:00
jason 575cbfdd2c 🐛 Fix __create_service_env to write .local.sh to disk 🐛
The .local.sh block defined stub functions in memory but never
wrote the file to disk, so __file_exists_with_content always
failed and __create_service_env returned non-zero on every run.
Fix: use a heredoc to write the stub functions into .local.sh.
- rootfs/usr/local/etc/docker/init.d/00-opengist.sh: write .local.sh
via heredoc in __create_service_env; bump version to 202606261600-git

rootfs/usr/local/etc/docker/init.d/00-opengist.sh
2026-06-26 21:04:36 -04:00
jason bc212ec85c 🗃️ Updated 🗃️
Dockerfile
.env.scripts
.gitattributes
.gitea/workflows/build.yml
.gitignore
README.md
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/opengist/config.yaml
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/00-opengist.sh
rootfs/usr/local/etc/resolv.conf
2026-06-12 05:39:45 -04:00
jason 00be90c1a0 🐛 Fix resolv.conf: add search . and ndots:0 to block domain search 🐛
--domainname on the container sets the kernel domainname, which c-ares
uses to infer a search domain even when /etc/resolv.conf has no search
line. This caused c-ares to query github.com.casjay.work AAAA and get
the host's own IPv6 address, routing all outbound HTTPS to the local
nginx instead of the real server.
Adding 'search .' and 'options ndots:0' explicitly disables search
domain inference regardless of the kernel domainname setting.
- rootfs/usr/local/etc/resolv.conf: add search . and options ndots:0

rootfs/usr/local/etc/resolv.conf
2026-06-05 14:34:08 -04:00
jason 0a90c12502 🐛 Fix container DNS: ship resolv.conf without search domain 🐛
Hosts with a search domain cause containers to inherit it. When the
zone has a wildcard AAAA record, public hostnames resolve to the host's
own IPv6 address instead of the real server, breaking all outbound
HTTPS and DNS 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:34:59 -04:00
jason 0a8cc3019b ♻️ Migrate opengist to /config/ source-of-truth architecture ♻️
Migrate opengist 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/00-opengist.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:47:16 -04:00
jason e9de36a20b 🗃️ Updated the functions file 🗃️
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2026-05-24 12:27:21 -04:00
jason 052e8e041c 🗃️ 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:08:00 -04:00
jason d4764c5f7a 🗃️ 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/00-opengist.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:12:36 -04:00
jason 4fbe926613 🗃️ Update codebase 🗃️
rootfs/usr/local/bin/entrypoint.sh
2026-02-05 02:38:25 -05:00
jason b3f234d69e 🗃️ Update codebase 🗃️
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/00-opengist.sh
2026-02-02 11:14:08 -05:00
jason fb32ddf69c 🗃️ Update codebase 🗃️
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2025-11-30 16:25:53 -05:00
jason 8ca45bd693 🔄 Updated entrypoint.sh script in docker functions directory 🔄
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2025-11-30 16:05:13 -05:00
jason 9d28639a1f 🗃️ Update codebase 🗃️
rootfs/usr/local/etc/docker/init.d/00-opengist.sh
2025-11-29 15:03:05 -05:00
jason 3d43b8a912 🗃️ Fixed the entrypoint scripts 🗃️
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2025-11-29 12:37:07 -05:00
jason d454bd1983 🗃️ Updated Dockerfile* and .env.scripts* 🗃️
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2025-11-29 11:04:42 -05:00
jason 92a70efe12 🗃️ Update codebase 🗃️
rootfs/usr/local/etc/docker/functions/entrypoint.sh
2025-11-29 09:15:08 -05:00
jason 44a1274db1 🗃️ Update codebase 🗃️
rootfs/usr/local/bin/entrypoint.sh
2025-11-29 09:01:33 -05:00
jason c8fe84678e 🗃️ Update codebase 🗃️
Dockerfile
rootfs/usr/local/bin/entrypoint.sh
2025-11-29 08:48:14 -05:00
jason b777766b07 🗃️ Fixed typo 🗃️
rootfs/root/docker/setup/05-custom.sh
2025-11-29 08:26:08 -05:00
jason 35b17f6ce1 🔧 Update configuration files 🔧
Dockerfile
.env.scripts
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/usr/local/bin/entrypoint.sh
rootfs/usr/local/bin/pkmgr
rootfs/usr/local/etc/docker/functions/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/00-opengist.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
2025-11-29 08:22:47 -05:00
jason a912f0e336 🗃️ Committing everything that changed 🗃️
rootfs/usr/local/etc/docker/functions/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/00-opengist.sh
2025-09-20 06:39:39 -04:00
jason e893bbf09d 🗃️ Committing everything that changed 🗃️
rootfs/usr/local/etc/docker/functions/
2025-09-20 05:27:53 -04:00
jason 591e8cb540 🦈🏠🐜 Initial Commit 🐜🦈🏠 2025-09-16 23:50:20 -04:00