diff --git a/AI.md b/AI.md index 6c1e27b..e972c0a 100644 --- a/AI.md +++ b/AI.md @@ -1,607 +1,514 @@ -# Docker Container Repository Specification +# CasjaysDev Docker Application Image Specification (casjaysdevdocker) -## Repository Overview +**Name**: {name} -**Repository:** casjaysdevdocker -**Maintainer:** CasjaysDev -**License:** WTFPL / MIT -**Purpose:** Collection of containerized applications using standardized Alpine-based templates +**About this file:** This is the complete, authoritative specification for a CasjaysDev +Docker **application image** repository (`casjaysdevdocker/{name}`). It is a master +template — copied into an app image repo as that repo's `AI.md`. It is **permanent** — +never delete it from a repo that carries it. + +**Note:** `{name}` in this file is a reference token, not setup-time replacement text. Its +value is always the repo directory basename (`basename "$PWD"`). + +**Maintenance procedure:** The bootstrap/update runbook (regenerating files after upstream +template changes, creating new repos) is NOT in this file — it lives in the +`dockersrc-bootstrap` agent (it handles both repo families via `REPO_TYPE` detection). +This file defines the standards that procedure enforces. --- -## Repository Structure +# PART INDEX -This repository contains multiple Docker container projects organised as subdirectories. Each project follows a consistent structure and naming convention. - -### Directory Layout - -``` -casjaysdevdocker/ -├── ampache/ # Media streaming server -├── apprise/ # Notification service -├── aria2/ # Download manager -├── bind/ # DNS server -├── bun/ # JavaScript runtime -├── caddy/ # Web server -├── code/ # VS Code server -├── couchdb/ # NoSQL database -├── ddns/ # Dynamic DNS client -├── deno/ # JavaScript runtime -├── docker/ # Docker-in-Docker -├── enclosed/ # Encrypted note sharing -├── forgejo/ # Git forge -├── gitea/ # Git service -├── gotify/ # Push notification server -├── i2pd/ # I2P router -├── icecast/ # Audio streaming -├── ifconfig/ # IP info service -├── jekyll/ # Static site generator -├── lighttpd/ # Web server -├── mailman/ # Mailing list manager -├── mariadb/ # SQL database -├── mongodb/ # NoSQL database -├── mpd/ # Music player daemon -├── mysql/ # SQL database -├── navidrome/ # Music streaming -├── neovim/ # Text editor -├── nextcloud/ # Cloud storage -├── nginx/ # Web server -├── nodejs/ # Node.js runtime -├── ntfy/ # Notification service -├── ollama/ # LLM runtime -├── opencloud/ # Cloud platform -├── opengist/ # Gist clone -├── pastebin/ # Pastebin service -├── php/ # PHP runtime -├── podman/ # Container runtime -├── postfix/ # Mail server -├── postgres/ # SQL database -├── proftpd/ # FTP server -├── python/ # Python runtime -├── redis/ # In-memory database -├── soft-serve/ # Git server -├── sqlite/ # SQL database -├── ssl-ca/ # SSL certificate authority -├── tftpd/ # TFTP server -├── tor/ # Tor relay -├── traefik/ # Reverse proxy -├── transmission/ # BitTorrent client -├── valkey/ # Redis fork -├── vim/ # Text editor -├── webmin/ # Web admin interface -├── wordpress/ # CMS platform -├── wttr/ # Weather service -├── xfce4/ # Desktop environment -├── ympd/ # MPD web client -├── youtube-dl/ # Video downloader -└── tools/ # Shared tools & scripts -``` +| PART | Title | +|------|-------| +| 0 | Critical rules | +| 1 | Repository model & structure | +| 2 | Template system reference | +| 3 | Tooling — gen-dockerfile & gen-script | +| 4 | `.env.scripts` reference | +| 5 | Runtime system — setup scripts, entrypoint, init.d | +| 6 | README.md standard layout | +| 7 | CI/CD workflows | +| 8 | Verification & commit | --- -## Standard Project Structure +# PART 0: CRITICAL RULES -Each project directory contains: +## Org mapping + +| System | Org | Example | +|--------|-----|---------| +| GitHub (source) | `casjaysdevdocker` | `https://github.com/casjaysdevdocker/{name}` | +| Docker Hub (push) | `casjaysdevdocker` | `casjaysdevdocker/{name}` | + +`casjaysdevdocker` repos are **applications** (gitea, opengist, super-productivity, +ampache, aria2, …). They always build FROM the pre-built, multi-arch `casjaysdev/*` base +images — never directly from upstream distro images. The bases themselves live in the +separate `dockersrc` org (GitHub `dockersrc/{base}` → Docker Hub `casjaysdev/{base}`) — +see the base specification (`DOCKERSRC.md`). + +## Non-negotiable rules + +1. **`AI.md` is permanent** — never delete it from the repo. +2. **Generated files are owned by the template system** — never hand-tune content that + `gen-dockerfile` regenerates (see PART 1 ownership table); fix the upstream + `gen-dockerfile` template instead, then regenerate. +3. **Hand-crafted files are owned by the repo** — `gen-dockerfile` must never overwrite + app-specific init.d scripts, custom bin scripts, a `05-custom.sh` with real content, or + a hand-crafted README (PART 6). +4. **Removed OCI labels stay removed** (PART 2) — never re-add `base.name`, + `schema-version`, or duplicate `authors`/`source` entries. +5. **`image.url` is a browsable page** — `https://hub.docker.com/r/casjaysdevdocker/{name}`. + `docker.io` is only a registry pull host; it is never a label URL. +6. **`image.source` and `image.documentation` are the GitHub repo** — + `https://github.com/casjaysdevdocker/{name}`. +7. **One Dockerfile, one file set** — app repos build one image (`latest` + date tag); + version variants (`Dockerfile.{ver}`) belong to base repos only. +8. **Always `FROM casjaysdev/`** — never pull an upstream distro image directly; + the base repos exist so every app shares one patched, multi-arch foundation. +9. **Only `root/`, `tmp/`, and `usr/` may exist at `rootfs/` top level** (PART 1). +10. **Maintenance runs through the `dockersrc-bootstrap` agent** — do not improvise the + update procedure from memory. + +--- + +# PART 1: REPOSITORY MODEL & STRUCTURE + +## What an app image repo is + +A `casjaysdevdocker/{name}` repo containerizes one application on top of a +`casjaysdev/*` base. It publishes a single image (`casjaysdevdocker/{name}:latest` plus a +date tag) — no per-version Dockerfile variants. The application itself is installed in +`05-custom.sh` and started by one or more init.d service scripts. + +## Standard tree ``` -project-name/ -├── .dockerignore # [generated] Docker build exclusions -├── .env.scripts # [generated] Environment variables for gen-dockerfile -├── .git/ # Git repository -├── .gitattributes # [generated] Git attributes +{name}/ +├── AI.md # This specification (permanent) +├── Dockerfile # [generated] single build file +├── .dockerignore # [generated] +├── .env.scripts # [generated] build config +├── .gitattributes # [generated] ├── .gitea/workflows/ -│ ├── docker.yaml # [hand-crafted] Legacy CI workflow — do not overwrite -│ └── build.yml # [generated] by gen-dockerfile actions — regenerate freely -├── .gitignore # [generated] Git ignore patterns -├── Dockerfile # [generated] Container build definition -├── LICENSE.md # License information -├── README.md # [generated] Project documentation -└── rootfs/ # Container filesystem overlay - ├── root/docker/setup/ # [generated] Build-time setup scripts - │ ├── 00-init.sh - │ ├── 01-system.sh - │ ├── 02-packages.sh - │ ├── 03-files.sh - │ ├── 04-users.sh - │ ├── 05-custom.sh - │ ├── 06-post.sh - │ └── 07-cleanup.sh +│ └── build.yml # [generated] gen-dockerfile actions +├── .gitignore # [generated] +├── LICENSE.md # License (WTFPL / app's own license) +├── README.md # [generated*] standard layout (PART 6) +└── rootfs/ # Container filesystem overlay + ├── root/docker/setup/ # [generated*] build-time setup scripts 00–07 + ├── tmp/ # staged files installed at build time (optional) └── usr/local/ - ├── bin/ - │ ├── entrypoint.sh # [generated] Container entrypoint - │ └── pkmgr # [generated] Package manager wrapper - ├── etc/docker/ - │ ├── functions/ - │ │ └── entrypoint.sh # [generated] Entrypoint functions - │ └── init.d/ # [hand-crafted] Runtime init scripts (one per service) - └── share/template-files/ # [hand-crafted] Config/data templates - ├── config/ - ├── data/ - └── defaults/ + ├── bin/ # [generated*] entrypoint.sh, pkmgr, symlink, copy, + │ # healthcheck + [hand-crafted] app-specific scripts + └── etc/docker/ + ├── env/ # [hand-crafted] build/runtime env fragments (optional) + ├── functions/ + │ └── entrypoint.sh # [generated] entrypoint function library + └── init.d/ # [hand-crafted] runtime init scripts (one per service) ``` -**`[generated]`** — safe to overwrite with `gen-dockerfile --update`; changes will be lost on next regeneration. -**`[hand-crafted]`** — must not be overwritten by gen-dockerfile; customised per container. +`[generated]` — safe to regenerate; local edits will be lost. +`[generated*]` — regenerated from the template, EXCEPT files carrying repo-specific +content (`05-custom.sh` with a real body, extra bin scripts, a hand-crafted README) — +those follow the hand-crafted rules in PARTs 5 and 6. +`[hand-crafted]` — never overwritten by the template system. + +App repos may additionally carry project files (`IDEA.md`, `CLAUDE.md`, `TODO.AI.md`) +per the global project conventions — they are repo-owned and never touched by tooling. + +## rootfs top-level policy + +The only valid directories at the `rootfs/` root are `root/`, `tmp/`, and `usr/`. +Anything else is a leftover from old patterns. Migration map: + +| Old rootfs path | Correct rootfs path | +|-----------------|---------------------| +| `rootfs/etc/{path}` | `rootfs/tmp/etc/{path}` | +| `rootfs/config/{path}` | `rootfs/tmp/etc/{path}` | +| `rootfs/data/{path}` | `rootfs/tmp/var/{path}` | +| `rootfs/var/{path}` | `rootfs/tmp/var/{path}` | +| `rootfs/opt/{path}` | `rootfs/tmp/opt/{path}` | +| `rootfs/share/{path}` | `rootfs/usr/local/share/{path}` | + +`rootfs/usr/local/share/template-files/` is retired — the `DEFAULT_TEMPLATE_DIR`, +`DEFAULT_FILE_DIR`, `DEFAULT_DATA_DIR`, and `DEFAULT_CONF_DIR` variables were removed +from the template system; the entrypoint installs staged files from `rootfs/tmp/etc/` +at container start instead. + +## Repo type detection + +A repo is an **app** repo when no `Dockerfile.*` variant files exist: + +```bash +if find . -maxdepth 1 -name 'Dockerfile.*' -type f | grep -q -- .; then + REPO_TYPE="base" +else + REPO_TYPE="app" +fi +``` --- -## gen-dockerfile Tool +# PART 2: TEMPLATE SYSTEM REFERENCE -All containers are built using the **gen-dockerfile** tool. It generates standardised Dockerfiles, `.env.scripts`, workflow YAML, `pkmgr` scripts, and `rootfs/` scaffolding. - -### Usage +Templates ship with `gen-dockerfile`, installed at +`/usr/local/share/CasjaysDev/scripts/templates/dockerfiles/` +(`$CASJAYSDEVDIR/templates/dockerfiles/` in a dev checkout). To inspect what the current +templates produce, generate a fresh reference tree in a temp dir: ```bash -gen-dockerfile [options] [template] [Dockerfile] -gen-dockerfile --dir ./myapp alpine -gen-dockerfile --dir ./myapp --nginx --tag 1.25 -gen-dockerfile --dir ./existing-project --update -gen-dockerfile --dir ./myapp actions +gen-dockerfile /tmp/gen-dockerfile/{org}/{repo} {distro} ``` -### Templates (positional argument or `--template`) +See `gen-dockerfile --help` for supported distros/types. Keep this PART in sync whenever +the templates change. -| Template | Description | Pull source (build stage) | -|----------|-------------|--------------------------| -| `alpine` | Alpine Linux (default) | `alpine` (Docker Hub official) | -| `arch` / `archlinux` | Arch Linux ARM | `menci/archlinuxarm` | -| `debian` | Debian | `debian` | -| `ubuntu` | Ubuntu | `ubuntu` | -| `rhel` / `almalinux` / `rockylinux` / `centos` / `oraclelinux` / `redhat` | AlmaLinux/RHEL family | `almalinux` | -| `web` | Adds `xorg` + `x11-apps` packages on top of the build stage; scratch final image | `casjaysdev/web` (exists) — override via `ENV_PULL_URL` | -| `xorg` | Adds `xorg` + `x11-apps` packages on top of the build stage; scratch final image | `casjaysdev/xorg` (**does not exist**) — must set `ENV_PULL_URL` | -| `scratch` | Scratch final image only (pair with any build template) | N/A | +## Template inventory -> **Note:** The pull source is the base image pulled for the **build stage**. All templates produce a `FROM scratch` final stage. For standard distros (`alpine`, `debian`, `ubuntu`, `rhel`, `arch`), the pull source is the official upstream image. For `web` and `xorg`, gen-dockerfile defaults to `casjaysdev/