Files
apprise/IDEA.md
T
jason 28400852c4
apprise / release-apprise (push) Canceled after 0s
📖 Standardize AI.md; move build docs into IDEA.md 📖
AI.md is now the standardized application-image specification from
claudemgr/docker/CASJAYSDEVDOCKER.md (PARTs 0–8: critical rules, repo
model, template system and OCI label canon, tooling, .env.scripts,
runtime system, README layout, CI/CD, verification gates). The former
AI.md's app-specific build documentation (nginx + gunicorn + Django +
apprise stack wiring) now lives in IDEA.md alongside the existing idea
description, so nothing was lost.

- AI.md: replaced with the CASJAYSDEVDOCKER.md master template
- IDEA.md: appended the app-specific build documentation moved out of AI.md
2026-08-14 15:23:30 -04:00

7.1 KiB

Idea

This image provides a self-hosted REST notification gateway built on top of the upstream caronc/apprise-api Django web application. It bundles nginx + gunicorn + Django + the apprise notification library into a single Alpine-based container so users can send push notifications to 80+ services (Slack, Discord, Telegram, Pushover, email, MQTT, and more) by POSTing to a simple HTTP endpoint. Persistent stateful configuration profiles (named bundles of notification URLs) live under /config/apprise/store/ and survive container restarts, while nginx proxies all traffic on port 8000 to gunicorn over a Unix socket.

AI context — apprise

Build flow

  1. FROM casjaysdev/alpine:latest (build stage) with gosu sidecar.
  2. COPY ./rootfs/. / — ships all configs, scripts, and pre-bundled source tarball early.
  3. pkmgr install bash → switch to /bin/bash shell.
  4. Run 00-init.sh (sanity setup, usually a no-op stub).
  5. Run 01-system.sh (timezone, system-level tweaks).
  6. pkmgr install $PACK_LIST — installs nginx, python3, gunicorn, gevent, Django and all Alpine-packaged Python deps.
  7. Run 02-packages.sh (stub).
  8. Run 03-files.sh — auto-installs rootfs/tmp/etc/nginx//etc/nginx/, stages copies under template-files/config/.
  9. Run 04-users.sh — creates apprise system user/group via addgroup -S / adduser -S.
  10. Run 05-custom.sh — the critical build step:
    • Wipes /etc/nginx/* and replaces with our optimized config (preserving mime.types).
    • Unpacks the pre-bundled apprise-api source tarball from /tmp/apprise-src/ into /usr/local/share/apprise-api/.
    • Patches gunicorn.conf.py to use /run/apprise/gunicorn.sock instead of upstream's /tmp/ path.
    • pip install apprise PGPy slixmpp smpplib gntp (deps Alpine does not package).
    • Creates runtime directories and drops apprise.yml.sample into the template-files config seed.
  11. Run 06-post.sh (stub — late permission/symlink tweaks).
  12. Run 07-cleanup.sh (stub — per-service cache cleanup).
  13. Generic cleanup (pkmgr clean, rm -Rf /usr/share/doc/* /var/tmp/* ...).
  14. FROM scratch final stage: COPY --from=build /. /; sets ENVs, LABELs, VOLUME, EXPOSE, ENTRYPOINT/HEALTHCHECK.

Services wired

Component Binary/path Role
tini /usr/bin/tini PID 1 / reaper
entrypoint /usr/local/bin/entrypoint.sh Framework orchestrator
init.d /usr/local/etc/docker/init.d/99-apprise.sh Service configuration + launch
start-apprise /usr/local/etc/docker/bin/start-apprise Wrapper: gunicorn bg + nginx fg
gunicorn /usr/bin/gunicorn (via py3-gunicorn) WSGI server (gevent workers)
nginx /usr/sbin/nginx HTTP reverse proxy (port 8000)

init.d behavior (99-apprise.sh)

The script is sourced by entrypoint.sh via __start_init_scripts. It:

  1. Checks APPRISE_ENABLED — exits silently if set to no.
  2. Checks for the /run/.start_init_scripts.pid sentinel (prevents double-run on healthcheck invocations).
  3. Cleans up stale PID files from prior crashes.
  4. Calls framework hooks in order:
    • __run_precopy__execute_prerun (creates runtime dirs /run/apprise, /tmp/apprise, /data/logs/apprise, /config/apprise/{store,attach,plugin,conf.d})
    • __initialize_system_etc (seeds /config/nginx/ from template-files on first run)
    • __run_pre_execute_checks (runs nginx -t to validate the config before starting)
    • __update_conf_files (token replacement: REPLACE_TZ${TZ:-UTC} in nginx.conf)
    • __pre_execute (final last-mile actions)
    • __run_start_script (checks that nginx is not already running, then calls start-apprise)
    • __post_execute (background: copies apprise.yml.sample into /config/apprise/ on first run)

Config paths

Path Purpose
/etc/nginx/nginx.conf Active nginx config (wipe-and-replace from our copy)
/config/nginx/ User-editable nginx config (seeded on first run)
/config/apprise/store/ Apprise persistent config profiles (<key>.yml)
/config/apprise/attach/ Attachment staging area
/config/apprise/plugin/ Custom Apprise plugins
/config/apprise/conf.d/ Optional nginx location overrides (included optionally)
/data/logs/apprise/ nginx access/error logs + gunicorn log
/run/apprise/gunicorn.sock Unix socket between nginx and gunicorn
/usr/local/share/apprise-api/webapp/ Django app root (manage.py, core/, api/, gunicorn.conf.py)

Environment variables (runtime)

Variable Default Used by
APPRISE_ENABLED yes 99-apprise.sh
APPRISE_CONFIG_DIR /config/apprise/store gunicorn / Django
APPRISE_ATTACH_DIR /config/apprise/attach gunicorn / Django
APPRISE_PLUGIN_PATHS /config/apprise/plugin gunicorn / Django
TZ America/New_York nginx, Python logging

start-apprise wrapper

/usr/local/etc/docker/bin/start-apprise:

  1. Creates /run/apprise, /tmp/apprise, log dirs.
  2. Exports APPRISE_* env defaults if not already set.
  3. Starts gunicorn in background: cd /usr/local/share/apprise-api/webapp && gunicorn -c gunicorn.conf.py --worker-tmp-dir /dev/shm core.wsgi >> /data/logs/apprise/gunicorn.log 2>&1 &
  4. Polls (up to 15s) for /run/apprise/gunicorn.sock to appear.
  5. exec /usr/sbin/nginx -c /etc/nginx/nginx.conf — nginx runs in the foreground with daemon off;.

File layout key

rootfs/
  usr/local/bin/entrypoint.sh          # SHARED: framework orchestrator (CONTAINER_NAME="apprise")
  usr/local/bin/pkmgr                  # SHARED: apk/apt/dnf wrapper
  usr/local/etc/docker/
    functions/entrypoint.sh            # SHARED: framework function library
    init.d/99-apprise.sh               # PER-REPO: service init + launch
    bin/start-apprise                  # PER-REPO: gunicorn+nginx launch wrapper
  tmp/etc/nginx/nginx.conf             # PER-REPO: optimized nginx config
  tmp/etc/nginx/mime.types             # PER-REPO: mime types (preserved from Alpine pkg)
  root/docker/setup/
    04-users.sh                        # PER-REPO: creates apprise system user
    05-custom.sh                       # PER-REPO: wipe-replace configs + pip install