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
🗃️ Updated 🗃️
2026-06-12 05:39:45 -04:00
🦈🏠🐜 Initial Commit 🐜🦈🏠
2025-09-16 23:50:20 -04:00
2026-08-02 23:28:19 -04:00
🗃️ Updated 🗃️
2026-06-12 05:39:45 -04:00
🗃️ Updated 🗃️
2026-06-12 05:39:45 -04:00
2026-08-03 09:41:46 -04:00
2026-08-02 23:26:29 -04:00
2026-05-12 20:08:00 -04:00

opengist

A containerized OpenGist — a self-hosted pastebin powered by Git. Create, share, and fork code snippets with full Git history, HTTP clone, SSH push/pull, and OAuth2 login via GitHub, GitLab, Gitea, or OpenID Connect. Built on Alpine Linux with SQLite storage and no external database required.


📦 Install

sudo bash -c "$(curl -q -LSsf "https://github.com/systemmgr/installer/raw/main/install.sh")"
sudo systemmgr --config && sudo systemmgr install scripts
dockermgr update opengist

Manual docker run

docker run -d \
  --restart always \
  --name casjaysdevdocker-opengist-latest \
  --hostname opengist \
  -e TZ=${TIMEZONE:-America/New_York} \
  -v /srv/$USER/docker/casjaysdevdocker/opengist/latest/volumes/data:/data:z \
  -v /srv/$USER/docker/casjaysdevdocker/opengist/latest/volumes/config:/config:z \
  -p 172.17.0.1:80:80 \
  -p 172.17.0.1:7823:7823 \
  casjaysdevdocker/opengist:latest

docker-compose

services:
  opengist:
    image: casjaysdevdocker/opengist:latest
    container_name: casjaysdevdocker-opengist
    hostname: opengist
    environment:
      - TZ=America/New_York
    volumes:
      - "/srv/$USER/docker/casjaysdevdocker/opengist/latest/volumes/data:/data:z"
      - "/srv/$USER/docker/casjaysdevdocker/opengist/latest/volumes/config:/config:z"
    ports:
      - "172.17.0.1:80:80"
      - "172.17.0.1:7823:7823"
    restart: always

⚙️ Configuration

Volumes

Path Purpose
/config Runtime configuration (auto-generated on first start)
/data Gist repositories, SQLite database, logs, and index

Ports

Port Protocol Purpose
80 HTTP Web UI and HTTP Git clone/pull
7823 TCP Built-in SSH server for Git push/pull

Environment variables

Variable Default Description
TZ America/New_York Container timezone
HOSTNAME casjaysdev-opengist Sets the external-url in opengist config
SERVER_NAME / FULL_DOMAIN_NAME Override hostname for external URL
OPENGIST_APPNAME_ENABLED yes Set to no to disable the service
OPENGIST_ROOT_USER_NAME Initial admin username
OPENGIST_ROOT_PASS_WORD Initial admin password
OPENGIST_USER_NAME Initial normal user name
OPENGIST_USER_PASS_WORD Initial normal user password
DEBUGGER Set to on to enable shell-level debug tracing

Runtime config overrides

Place a shell script at /config/env/opengist.sh inside the container (or mount it as a file) to override any variable at runtime without rebuilding the image. A template is written on first start.

OAuth2

After first start, edit /config/opengist/config.yaml to add OAuth2 credentials:

github.client-key: <your-key>
github.secret:     <your-secret>

gitlab.client-key: <your-key>
gitlab.secret:     <your-secret>
gitlab.url:        https://gitlab.com/

gitea.client-key:  <your-key>
gitea.secret:      <your-secret>
gitea.url:         https://your-gitea-instance/

oidc.client-key:      <your-key>
oidc.secret:          <your-secret>
oidc.discovery-url:   https://auth.example.com/.well-known/openid-configuration

OAuth2 callback URLs must follow the pattern: http://<opengist-url>/oauth/<github|gitlab|gitea|openid-connect>/callback


🛠️ Development

Prerequisites

  • Docker with buildx support
  • git

Get source

git clone "https://github.com/casjaysdevdocker/opengist" \
  "$HOME/Projects/github/casjaysdevdocker/opengist"
cd "$HOME/Projects/github/casjaysdevdocker/opengist"

Or via dockermgr:

dockermgr download src casjaysdevdocker/opengist

Build the image

buildx

The build downloads the latest OpenGist release binary from GitHub at build time and bundles it into the image.


📄 License

WTFPL — see LICENSE.md

🤖 casjay: Github 🤖
casjaysdevdocker: Github Docker

S
Description
Repo for opengist
Readme
248 KiB
Languages
Shell 93.8%
Dockerfile 6.2%