From 6b13cc90750669df4051a3f06766be4f71cca3ff Mon Sep 17 00:00:00 2001 From: casjay Date: Fri, 26 Jun 2026 12:32:07 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Update=20AI.md=20to=20match=20cu?= =?UTF-8?q?rrent=20gen-dockerfile=20tool=20=F0=9F=93=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrote the specification to reflect the actual current gen-dockerfile behaviour, template system, and generated file structures. Key changes: - .env.scripts: Replace all old variable names (ENV_IMAGE_NAME, ENV_IMAGE_PUSH, ENV_HUB_BASE, ENV_ORG_NAME) with current names (ENV_REGISTRY_REPO, ENV_REGISTRY_PUSH, ENV_REGISTRY_URL, ENV_REGISTRY_ORG); add legacy migration table - Add complete gen-dockerfile CLI flags reference - Add template types table (alpine/arch/debian/ubuntu/almalinux/web/xorg/scratch) - Document `gen-dockerfile actions` subcommand (generates build.yml) - Document `gen-dockerfile --update` mode - Document --org/--user/--repo scope prefix syntax (git: / reg:) - Document template resolution order (user config dir > scripts tree) - Fix workflow filename: .gitea/workflows/docker.yaml (example) vs build.yml (gen-dockerfile actions output) - Replace example workflow skeleton with the actual docker.yaml content - Add full build argument table from the actual generated Dockerfile - Document all eight required hook functions for init.d scripts - Clarify PID sentinel: /run/.start_init_scripts.pid (dot prefix) - Remove stale hard-coded project count ("71") - Expand directory variable documentation for init.d scripts - AI.md: .github/AI.md: rewrite based on current tool and templates AI.md --- AI.md | 685 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 449 insertions(+), 236 deletions(-) diff --git a/AI.md b/AI.md index bc3204e..97b20dc 100644 --- a/AI.md +++ b/AI.md @@ -11,7 +11,7 @@ ## Repository Structure -This repository contains **71 Docker container projects** organized as subdirectories. Each project follows a consistent structure and naming convention. +This repository contains multiple Docker container projects organised as subdirectories. Each project follows a consistent structure and naming convention. ### Directory Layout @@ -21,30 +21,21 @@ casjaysdevdocker/ ├── apprise/ # Notification service ├── aria2/ # Download manager ├── bind/ # DNS server -├── blueonyx/ # Server management -├── buildah/ # Container build tool ├── bun/ # JavaScript runtime ├── caddy/ # Web server -├── cherokee/ # Web server ├── code/ # VS Code server -├── commitment/ # Git commit tool -├── coolify/ # Self-hosting platform ├── couchdb/ # NoSQL database ├── ddns/ # Dynamic DNS client ├── deno/ # JavaScript runtime -├── dictd/ # Dictionary server ├── docker/ # Docker-in-Docker ├── enclosed/ # Encrypted note sharing ├── forgejo/ # Git forge ├── gitea/ # Git service -├── gohttpserver/ # HTTP file server ├── gotify/ # Push notification server ├── i2pd/ # I2P router ├── icecast/ # Audio streaming ├── ifconfig/ # IP info service -├── inn/ # NNTP server ├── jekyll/ # Static site generator -├── lenpaste/ # Pastebin service ├── lighttpd/ # Web server ├── mailman/ # Mailing list manager ├── mariadb/ # SQL database @@ -65,22 +56,14 @@ casjaysdevdocker/ ├── podman/ # Container runtime ├── postfix/ # Mail server ├── postgres/ # SQL database -├── proftp/ # FTP server ├── proftpd/ # FTP server ├── python/ # Python runtime -├── rarbg/ # Torrent indexer ├── redis/ # In-memory database -├── remotely/ # Remote desktop ├── soft-serve/ # Git server ├── sqlite/ # SQL database -├── squidguard/ # Web content filter ├── ssl-ca/ # SSL certificate authority -├── stikked/ # Pastebin ├── tftpd/ # TFTP server -├── theHarvester/ # OSINT tool -├── tools/ # Shared tools & scripts ├── tor/ # Tor relay -├── tor-browser/ # Tor browser ├── traefik/ # Reverse proxy ├── transmission/ # BitTorrent client ├── valkey/ # Redis fork @@ -90,7 +73,8 @@ casjaysdevdocker/ ├── wttr/ # Weather service ├── xfce4/ # Desktop environment ├── ympd/ # MPD web client -└── youtube-dl/ # Video downloader +├── youtube-dl/ # Video downloader +└── tools/ # Shared tools & scripts ``` --- @@ -106,9 +90,9 @@ project-name/ ├── .git/ # Git repository ├── .gitattributes # Git attributes ├── .gitea/workflows/ # CI/CD workflows (Gitea Actions) +│ └── docker.yaml # Build and push workflow ├── .gitignore # Git ignore patterns ├── Dockerfile # Container build definition -├── Jenkinsfile # Jenkins CI pipeline (legacy) ├── LICENSE.md # License information ├── README.md # Project documentation └── rootfs/ # Container filesystem overlay @@ -128,7 +112,7 @@ project-name/ ├── etc/docker/ │ ├── functions/ │ │ └── entrypoint.sh # Entrypoint functions - │ └── init.d/ # Init scripts + │ └── init.d/ # Runtime init scripts └── share/template-files/ ├── config/ # Configuration templates ├── data/ # Default data @@ -137,24 +121,253 @@ project-name/ --- -## Dockerfile Template System +## gen-dockerfile Tool -All containers are built using the **gen-dockerfile** tool, which generates standardized multi-stage Dockerfiles based on Alpine Linux. +All containers are built using the **gen-dockerfile** tool (`bin/gen-dockerfile` in casjay-dotfiles). It generates standardised Dockerfiles, `.env.scripts`, workflow YAML, `pkmgr` scripts, and `rootfs/` scaffolding. + +### Usage + +```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 +``` + +### Templates (positional argument or `--template`) + +| Template | Description | Base image | +|----------|-------------|------------| +| `alpine` | Default Alpine Linux (default) | `casjaysdev/alpine` | +| `arch` / `archlinux` | Arch Linux | `menci/archlinuxarm` | +| `debian` | Debian | `debian` | +| `ubuntu` | Ubuntu | `ubuntu` | +| `rhel` / `almalinux` / `rockylinux` / `centos` | AlmaLinux/RHEL family | `almalinux` | +| `web` | Alpine + xorg + x11-apps | scratch/web template | +| `xorg` | Alpine + xorg | xorg template | +| `scratch` | Scratch-based | scratch template | + +### CLI Flags + +| Flag | Description | +|------|-------------| +| `--dir ` | Working directory (default: `$PWD`) | +| `--template ` | Override template type | +| `--registry ` | Registry provider URL (e.g. `https://docker.io`) | +| `--org <[git\|reg:]name>` | Override org/namespace — prefix `git:` or `reg:` to scope to one system, bare value sets both | +| `--user <[git\|reg:]name>` | Alias for `--org` | +| `--repo <[git\|reg:]name>` | Override repo/image name — same scope prefix rules | +| `--tag ` | Image version tag (default: `latest`) | +| `--add-tags ` | Comma-separated additional tags (or `USE_DATE` for auto date tag) | +| `--distro-name ` | Base image pull URL (overrides `ENV_PULL_URL`) | +| `--distro-version ` | Base image tag (overrides `ENV_DISTRO_TAG`) | +| `--startup` | Create a container start script only | +| `--nogit` | Skip `git init` in the new project dir | +| `--dockerfile` | Regenerate Dockerfile only — skip other files | +| `--update` | Re-run gen-dockerfile on an existing project to regenerate files | +| `--init` | Init mode | +| `--x11` | Enable X11/xorg support | +| `--ports ` | Additional EXPOSE ports | +| `--pkmgr` | Generate `pkmgr` script only and exit | +| `--apache` | Add Apache2 packages + setup | +| `--nginx` | Add nginx packages + setup | +| `--mysql` / `--mariadb` | Add MariaDB packages + setup | +| `--postgres` | Add PostgreSQL packages + setup | +| `--php` | Add PHP packages + setup | +| `--application ` | Add a templatemgr application install step | +| `--alpine` / `--almalinux` / `--archlinux` / `--debian` / `--ubuntu` | Shortcut distro flags | +| `--force` | Overwrite existing files without prompting | +| `--silent` | Suppress non-error output | +| `--debug` | Enable `set -x` tracing | +| `--no-color` | Disable colour output | + +### Special Subcommands + +```bash +gen-dockerfile --dir ./myapp actions +``` + +Creates `.gitea/workflows/build.yml` (or `build.$version.yml` for versioned tags) from the existing `Dockerfile`. The example workflow in `.github/example/.gitea/workflows/docker.yaml` is the canonical reference pattern for the legacy hand-written style; `gen-dockerfile actions` generates `build.yml` with the same structure. + +### Template Resolution + +Templates are loaded from the first match: + +1. `$GEN_DOCKERFILE_CONFIG_DIR/templates/.template` (user override) +2. `$CASJAYSDEVDIR/templates/dockerfiles/.template` (installed scripts tree) + +`template_options.source` is sourced after `__set_variables` runs, allowing template-specific variable overrides. + +--- + +## `.env.scripts` File + +Generated at project root; sourced by gen-dockerfile and by the CI workflow at build time. + +### Current Variable Names + +```bash +# - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202601291955-git +# ... +# - - - - - - - - - - - - - - - - - - - - - - - - - + +# Entrypoint Settings +DOCKER_ENTYPOINT_PORTS_WEB="${DOCKER_ENTYPOINT_PORTS_WEB}" +DOCKER_ENTYPOINT_PORTS_SRV="${DOCKER_ENTYPOINT_PORTS_SRV}" +DOCKER_ENTYPOINT_HEALTH_APPS="$DOCKER_ENTYPOINT_HEALTH_APPS" +DOCKER_ENTYPOINT_HEALTH_ENDPOINTS="$DOCKER_ENTYPOINT_HEALTH_ENDPOINTS" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Dockerfile info +ENV_DOCKERFILE="Dockerfile" +# ENV_REGISTRY_REPO: Registry repository/image name +ENV_REGISTRY_REPO="myapp" +ENV_USE_TEMPLATE="alpine" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Maintainer info +ENV_REGISTRY_ORG="casjaysdevdocker" +ENV_VENDOR="CasjaysDev" +ENV_AUTHOR="CasjaysDev" +ENV_MAINTAINER="CasjaysDev " +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Repository URLs (Full URLs) +# ENV_GIT_REPO_URL: Complete Git repository URL for source code +ENV_GIT_REPO_URL="https://github.com/casjaysdevdocker/myapp" +# ENV_REGISTRY_URL: Registry provider base URL +ENV_REGISTRY_URL="https://docker.io" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Push Configuration +# ENV_REGISTRY_PUSH: Complete push destination (registry/org/repo) +ENV_REGISTRY_PUSH="casjaysdevdocker/myapp" +# ENV_IMAGE_TAG: Default tag for the image +ENV_IMAGE_TAG="latest" +# ENV_ADD_TAGS: Additional tags, comma-separated (USE_DATE = auto date tag) +ENV_ADD_TAGS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional push destinations (if needed) +ENV_ADD_IMAGE_PUSH="" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Pull Configuration +# ENV_PULL_URL: Source image to pull from (base image) +ENV_PULL_URL="casjaysdev/alpine" +# ENV_DISTRO_TAG: Tag for the pull source image +ENV_DISTRO_TAG="${IMAGE_VERSION}" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Port exposure +SERVICE_PORT="" +EXPOSE_PORTS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Language runtime version (go, php, rust, ruby, etc) +LANG_VERSION="" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Runtime versions +PHP_VERSION="system" +NODE_VERSION="system" +NODE_MANAGER="system" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Default directories (passed as ARGs into Dockerfile) +WWW_ROOT_DIR="/usr/local/share/httpd/default" +DEFAULT_FILE_DIR="/usr/local/share/template-files" +DEFAULT_DATA_DIR="/usr/local/share/template-files/data" +DEFAULT_CONF_DIR="/usr/local/share/template-files/config" +DEFAULT_TEMPLATE_DIR="/usr/local/share/template-files/defaults" +# - - - - - - - - - - - - - - - - - - - - - - - - - +ENV_PACKAGES="" +``` + +### Variable Reference + +| Variable | Purpose | +|----------|---------| +| `ENV_REGISTRY_REPO` | Image name in the registry | +| `ENV_REGISTRY_ORG` | Organisation/namespace in the registry | +| `ENV_REGISTRY_URL` | Registry base URL (e.g. `https://docker.io`) | +| `ENV_REGISTRY_PUSH` | Full push path `org/repo` (registry host prepended if not `docker.io`) | +| `ENV_ADD_IMAGE_PUSH` | Extra push destinations | +| `ENV_GIT_REPO_URL` | Full Git repository URL | +| `ENV_USE_TEMPLATE` | Template name to use (alpine, debian, etc.) | +| `ENV_PULL_URL` | Base image to pull from | +| `ENV_DISTRO_TAG` | Tag for the base image | +| `ENV_IMAGE_TAG` | Default image tag (default: `latest`) | +| `ENV_ADD_TAGS` | Additional comma-separated tags; `USE_DATE` auto-generates a `YYMM` tag | +| `ENV_PACKAGES` | Space-separated package list to install | +| `ENV_VENDOR` / `ENV_AUTHOR` / `ENV_MAINTAINER` | Label metadata | +| `SERVICE_PORT` | Primary exposed port | +| `EXPOSE_PORTS` | Additional exposed ports | +| `PHP_VERSION` / `NODE_VERSION` / `NODE_MANAGER` | Runtime versions | +| `DOCKER_ENTYPOINT_PORTS_WEB` | Web ports passed to entrypoint | +| `DOCKER_ENTYPOINT_PORTS_SRV` | Service ports passed to entrypoint | +| `DOCKER_ENTYPOINT_HEALTH_APPS` | Apps to health-check | +| `DOCKER_ENTYPOINT_HEALTH_ENDPOINTS` | Endpoints to health-check | + +### Legacy Variable Auto-Migration + +`gen-dockerfile --update` (and on every run) calls `__migrate_env_script` which automatically renames old variable names to the current ones. Old names that are no longer used: + +| Old Name | Current Name | +|----------|-------------| +| `ENV_IMAGE_NAME` | `ENV_REGISTRY_REPO` | +| `ENV_IMAGE_PUSH` | `ENV_REGISTRY_PUSH` | +| `ENV_HUB_BASE` | `ENV_REGISTRY_URL` | +| `ENV_ORG_NAME` | `ENV_REGISTRY_ORG` | + +Never use the old names in new `.env.scripts` files. + +--- + +## Dockerfile Template Structure + +### Build Arguments + +| Argument | Description | Default | +|----------|-------------|---------| +| `IMAGE_NAME` | Container name | (from `ENV_REGISTRY_REPO`) | +| `IMAGE_REPO` | Full push path `org/repo` | (computed) | +| `IMAGE_VERSION` | Image version | `latest` | +| `BUILD_DATE` | Build timestamp | YYYYMMDDHHMM | +| `BUILD_VERSION` | Build version (same as BUILD_DATE) | YYYYMMDDHHMM | +| `GIT_COMMIT` | Git SHA at build time | (from CI) | +| `LANGUAGE` | System locale | `en_US.UTF-8` | +| `TIMEZONE` | System timezone | `America/New_York` | +| `SERVICE_PORT` | Primary service port | (from `.env.scripts`) | +| `EXPOSE_PORTS` | Additional ports | (from `.env.scripts`) | +| `PHP_VERSION` | PHP version | `system` | +| `NODE_VERSION` | Node.js version | `system` | +| `NODE_MANAGER` | Node manager | `system` | +| `PULL_URL` | Base image | `casjaysdev/alpine` | +| `DISTRO_VERSION` | Base image tag | `${IMAGE_VERSION}` | +| `WWW_ROOT_DIR` | Web root | `/usr/local/share/httpd/default` | +| `DEFAULT_FILE_DIR` | Template files dir | `/usr/local/share/template-files` | ### Generated Dockerfile Structure #### Stage 1: Build Stage + ```dockerfile FROM tianon/gosu:latest AS gosu -FROM alpine:latest AS build +FROM ${PULL_URL}:${DISTRO_VERSION} AS build -# Install packages -RUN pkmgr install ${PACK_LIST} +# ... ARG declarations ... -# Run setup scripts in order: +ENV SHELL="/bin/sh" +ENV PATH="${PATH}" +ENV TZ="${TIMEZONE}" +ENV LANG="${LANGUAGE}" +ENV TERM="xterm-256color" +ENV HOSTNAME="casjaysdevdocker-${IMAGE_NAME}" + +COPY ./rootfs/. / +RUN pkmgr update; pkmgr install bash + +ENV SHELL="/bin/bash" +SHELL ["/bin/bash", "-c"] +COPY --from=gosu /usr/local/bin/gosu /usr/local/bin/gosu + +# Setup scripts run in order: # 00-init.sh - Initialize base system # 01-system.sh - Configure system settings -# 02-packages.sh - Install/configure packages +# 02-packages.sh - Install/configure packages (after PACK_LIST install) # 03-files.sh - Copy/modify files # 04-users.sh - Create users/groups # 05-custom.sh - Custom application setup @@ -163,53 +376,57 @@ RUN pkmgr install ${PACK_LIST} ``` #### Stage 2: Final Image + ```dockerfile FROM scratch +# ... ARG and LABEL declarations ... + +ENV SHELL="/bin/bash" +ENV TZ="${TIMEZONE}" +ENV LANG="${LANGUAGE}" +ENV TERM="xterm-256color" +ENV PORT="${SERVICE_PORT}" +ENV HOSTNAME="casjaysdev-${IMAGE_NAME}" +ENV CONTAINER_NAME="${IMAGE_NAME}" + COPY --from=build /. / VOLUME [ "/config", "/data" ] EXPOSE ${SERVICE_PORT} ${ENV_PORTS} +STOPSIGNAL SIGRTMIN+3 ENTRYPOINT [ "tini", "-p", "SIGTERM", "--", "/usr/local/bin/entrypoint.sh" ] -HEALTHCHECK CMD [ "/usr/local/bin/entrypoint.sh", "healthcheck" ] +HEALTHCHECK --start-period=10m --interval=5m --timeout=15s \ + CMD [ "/usr/local/bin/entrypoint.sh", "healthcheck" ] ``` -### Standard Build Arguments +### Container Labels -| Argument | Description | Default | -|----------|-------------|---------| -| `IMAGE_NAME` | Container name | (varies) | -| `BUILD_DATE` | Build timestamp | YYYYMMDDHHMM | -| `LANGUAGE` | System locale | en_US.UTF-8 | -| `TIMEZONE` | System timezone | America/New_York | -| `SERVICE_PORT` | Primary service port | (varies) | -| `EXPOSE_PORTS` | Additional ports | (varies) | -| `PHP_VERSION` | PHP version | system | -| `NODE_VERSION` | Node.js version | system | -| `PULL_URL` | Base image | casjaysdev/alpine | -| `DISTRO_VERSION` | Alpine version | latest | +All containers include OpenContainers standard labels: -### Standard Environment Variables - -```bash -ENV SHELL="/bin/bash" -ENV TZ="${TIMEZONE}" -ENV LANG="${LANGUAGE}" -ENV TERM="xterm-256color" -ENV HOSTNAME="casjaysdev-${IMAGE_NAME}" -ENV WWW_ROOT_DIR="/usr/local/share/httpd/default" +```dockerfile +LABEL maintainer="CasjaysDev " +LABEL org.opencontainers.image.vendor="CasjaysDev" +LABEL org.opencontainers.image.authors="CasjaysDev" +LABEL org.opencontainers.image.description="Containerized version of ${IMAGE_NAME}" +LABEL org.opencontainers.image.title="${IMAGE_NAME}" +LABEL org.opencontainers.image.created="${BUILD_DATE}" +LABEL org.opencontainers.image.version="${BUILD_VERSION}" +LABEL org.opencontainers.image.source="https://github.com/casjaysdevdocker/${IMAGE_NAME}" +LABEL org.opencontainers.image.documentation="https://github.com/casjaysdevdocker/${IMAGE_NAME}" +LABEL org.opencontainers.image.revision="${GIT_COMMIT}" ``` --- ## Common Package List -Standard packages included in most containers: +Standard packages included in most containers (Alpine template): ``` -bash-completion git curl wget sudo unzip iproute2 ssmtp openssl jq tzdata -mailcap ncurses util-linux pciutils usbutils coreutils binutils findutils -grep rsync zip tini py3-pip procps net-tools sed gawk attr readline lsof +bash-completion git curl wget sudo unzip iproute2 ssmtp openssl jq tzdata +mailcap ncurses util-linux pciutils usbutils coreutils binutils findutils +grep rsync zip tini py3-pip procps net-tools sed gawk attr readline lsof less shadow certbot ca-certificates ``` @@ -217,13 +434,15 @@ less shadow certbot ca-certificates ## Setup Scripts Convention +Build-time scripts in `rootfs/root/docker/setup/` run inside the Docker build layer. + ### 00-init.sh - Initialize base directory structure - Set up template directories - Create initial environment ### 01-system.sh -- Configure APK repositories +- Configure APK/apt/yum repositories - Set up system settings - Configure locales and timezone @@ -263,12 +482,12 @@ less shadow certbot ca-certificates ### Entrypoint Script Flow -```bash +``` /usr/local/bin/entrypoint.sh -├─ Load functions from /usr/local/etc/docker/functions/ -├─ Set up environment variables +├─ Load functions from /usr/local/etc/docker/functions/entrypoint.sh +├─ Set up environment variables (sources /root/env.sh, /usr/local/etc/docker/env/*.sh, /config/env/*.sh) ├─ Create /config and /data volumes -├─ Run ALL init scripts from /usr/local/etc/docker/init.d/ (sorted order) +├─ Run ALL init scripts from /usr/local/etc/docker/init.d/ (sorted order) via __start_init_scripts ├─ Handle healthcheck command └─ Execute main application ``` @@ -278,28 +497,80 @@ less shadow certbot ca-certificates **Each service in a repo gets its own numbered init.d script. Never merge or remove them.** - `__start_init_scripts` iterates and sources **every** `*.sh` file in `init.d/` in sort order. -- Multi-process repos have **one script per service**. Example for `bind`: +- Multi-process repos have **one script per service**. Example for a repo running three daemons: ``` - init.d/01-tor.sh — Tor relay - init.d/02-named.sh — BIND/named DNS server - init.d/03-nginx.sh — nginx web front-end - init.d/04-php-fpm.sh — PHP-FPM for web UI + init.d/01-named.sh — BIND/named DNS server + init.d/02-nginx.sh — nginx web front-end + init.d/03-php-fpm.sh — PHP-FPM for web UI ``` - **Migration task = UPDATE each script to the canonical pattern, never delete services.** -- The canonical pattern is `/.github/example/rootfs/usr/local/etc/docker/init.d/04-example.sh`. -- Key checks every script must have: - - Correct PID sentinel: `if [ ! -f "/run/.start_init_scripts.pid" ]` (dot prefix, no double underscore) - - Source functions file before using any framework functions - - All hook functions defined: `__run_precopy`, `__execute_prerun`, `__run_pre_execute_checks`, - `__update_conf_files`, `__pre_execute`, `__post_execute`, `__pre_message`, - `__update_ssl_conf`, `__create_service_env`, `__run_start_script`, `__run_secure_function` - - `SERVICE_USES_PID='yes'` for long-running daemons, `'no'` for config-only steps - - `EXEC_CMD_BIN` set to the daemon binary path +- The canonical pattern is `.github/example/rootfs/usr/local/etc/docker/init.d/04-example.sh`. + +### Required Variables in Every Init.d Script + +```bash +SERVICE_NAME="myapp" # used for PID files, log dirs, config dirs +EXEC_CMD_BIN='myapp' # daemon binary (single-quoted — expanded later) +EXEC_CMD_ARGS='' # daemon arguments (single-quoted) +EXEC_PRE_SCRIPT='' # pre-start script (single-quoted) +SERVICE_USES_PID='' # '' for long-running daemons; 'no' for config-only steps +IS_WEB_SERVER="no" # 'yes' sets RESET_ENV and default port 80 +IS_DATABASE_SERVICE="no" +USES_DATABASE_SERVICE="no" +DATABASE_SERVICE_TYPE="sqlite" # custom|sqlite|redis|postgres|mariadb|mysql|couchdb|mongodb|supabase +RUNAS_USER="root" +``` + +### Required Hook Functions in Every Init.d Script + +All eight must be defined (even if they just `return 0`): + +```bash +__run_precopy() # runs before copying /config to /etc +__execute_prerun() # runs before service starts +__run_pre_execute_checks() # validation before exec; non-zero aborts start +__update_conf_files() # update config files (sed replacements, etc.) +__pre_execute() # final setup before exec +__post_execute() # background post-start tasks +__pre_message() # message to show before exec +__update_ssl_conf() # SSL certificate setup +__create_service_env() # generates /config/env/$SERVICE_NAME.sh template +__run_start_script() # builds and runs the exec script +__run_secure_function() # chmod 600 on credential files +``` + +### PID Sentinel Check (CRITICAL) + +Every init.d script **must** guard on the correct sentinel file: + +```bash +# Correct — dot prefix, no double underscore +if [ ! -f "/run/.start_init_scripts.pid" ]; then + echo "__start_init_scripts function hasn't been Initialized" >&2 + SERVICE_IS_RUNNING="no" + __script_exit 1 +fi +``` + +The file is `/run/.start_init_scripts.pid` — a leading dot, no underscores in the filename portion. Any other form silently skips the guard. + +### Directory Variables + +```bash +DATA_DIR="/data/$SERVICE_NAME" # persistent data +CONF_DIR="/config/$SERVICE_NAME" # persistent config +ETC_DIR="/etc/$SERVICE_NAME" # runtime etc (synced from CONF_DIR) +LOG_DIR="/data/logs/$SERVICE_NAME" # logs +TMP_DIR="/tmp/$SERVICE_NAME" +RUN_DIR="/run/$SERVICE_NAME" +ROOT_FILE_PREFIX="/config/secure/auth/root" +USER_FILE_PREFIX="/config/secure/auth/user" +``` ### Volume Mounts -- `/config` - Persistent configuration files -- `/data` - Persistent application data +- `/config` — Persistent configuration files +- `/data` — Persistent application data --- @@ -307,35 +578,83 @@ less shadow certbot ca-certificates ### Gitea Actions Workflow -Located at `.gitea/workflows/docker.yaml`: +Located at `.gitea/workflows/docker.yaml` (canonical example). Key structure: ```yaml -name: Build and Push Docker Image -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] +name: example +on: push jobs: - build: - runs-on: ubuntu-latest + release-example: + runs-on: act_runner + container: + image: catthehacker/ubuntu:act-latest + env: + RUNNER_TOOL_CACHE: /toolcache steps: - name: Checkout - - name: Setup Docker Buildx - - name: Login to Registry - - name: Build and Push + uses: actions/checkout@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Get Meta + id: meta + run: | + repo_version="$(git describe --tags --always)" + repo_version="${repo_version#v}" + docker_org="${GITHUB_REPOSITORY%%/*}" + repo_name="${GITHUB_REPOSITORY#*/}" + repo_name="${repo_name#docker-}" + docker_tag="${DOCKER_TAG:-latest}" + docker_hub="${DOCKER_HUB:-docker.io}" + printf 'DATE_TAG=%s\n' "$(date +'%y%m')" >> "$GITHUB_OUTPUT" + printf 'REPO_VERSION=%s\n' "$repo_version" >> "$GITHUB_OUTPUT" + printf 'DOCKER_ORG=%s\n' "$docker_org" >> "$GITHUB_OUTPUT" + printf 'DOCKER_TAG=%s\n' "$docker_tag" >> "$GITHUB_OUTPUT" + printf 'DOCKER_HUB=%s\n' "$docker_hub" >> "$GITHUB_OUTPUT" + printf 'REPO_NAME=%s\n' "$repo_name" >> "$GITHUB_OUTPUT" + + - name: Set up Docker BuildX + uses: docker/setup-buildx-action@v2 + + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKER_USERNAME }} + registry: ${{ steps.meta.outputs.DOCKER_HUB }} + + - name: Build and push + uses: docker/build-push-action@v4 + with: + context: . + file: ./Dockerfile + platforms: | + linux/amd64 + linux/arm64 + push: true + build-args: | + IMAGE_NAME=${{ steps.meta.outputs.REPO_NAME }} + BUILD_DATE=$(date -u +'%Y%m%d%H%M') + BUILD_VERSION=$(date -u +'%Y%m%d%H%M') + GIT_COMMIT=${{ github.sha }} + TIMEZONE=America/New_York + LANGUAGE=en_US.UTF-8 + LICENSE=WTFPL + TZ=America/New_York + tags: | + ${{ steps.meta.outputs.DOCKER_HUB }}/${{ steps.meta.outputs.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.DATE_TAG }} + ${{ steps.meta.outputs.DOCKER_HUB }}/${{ steps.meta.outputs.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.DOCKER_TAG }} ``` -### Jenkins Pipeline (Legacy) - -Some projects include `Jenkinsfile` for Jenkins CI integration. +`gen-dockerfile actions` regenerates this as `.gitea/workflows/build.yml` (or `build.$version.yml`) from the existing Dockerfile. --- ## Package Manager Wrapper (pkmgr) -The `pkmgr` script provides a unified interface for package management: +The `pkmgr` script in `rootfs/usr/local/bin/pkmgr` provides a unified interface: ```bash pkmgr update # Update package lists @@ -344,84 +663,54 @@ pkmgr remove # Remove packages pkmgr clean # Clean package cache ``` -Automatically detects and uses the appropriate package manager (apk, apt, yum, etc.) +Automatically detects and uses the appropriate package manager (apk, apt-get, dnf, pacman). --- -## Generated Alpine Template Example +## Development Workflow -The `gen-dockerfile` tool was executed with: +### Creating a New Container ```bash -gen-dockerfile --dir /tmp/fjwuenfng/alpine alpine +# 1. Generate scaffolding +gen-dockerfile --dir ./myapp alpine + +# 2. Customise .env.scripts (set ENV_REGISTRY_REPO, ENV_REGISTRY_ORG, ports, etc.) + +# 3. Customise setup scripts in rootfs/root/docker/setup/ + +# 4. Add init.d runtime script (copy from .github/example) + +# 5. Build and test +docker build -t myapp . +docker run -it myapp + +# 6. Commit and push to trigger CI/CD ``` -### Generated Files +### Updating an Existing Container -``` -/tmp/fjwuenfng/alpine/ -├── .dockerignore -├── .env.scripts -├── .gitattributes -├── .gitea/workflows/docker.yaml -├── .gitignore -├── Dockerfile -├── LICENSE.md -├── README.md -└── rootfs/ - ├── root/docker/setup/ - │ ├── 00-init.sh - │ ├── 01-system.sh - │ ├── 02-packages.sh - │ ├── 03-files.sh - │ ├── 04-users.sh - │ ├── 05-custom.sh - │ ├── 06-post.sh - │ └── 07-cleanup.sh - └── usr/local/ - ├── bin/ - │ ├── entrypoint.sh - │ └── pkmgr - ├── etc/docker/ - │ ├── functions/entrypoint.sh - │ └── init.d/ - └── share/template-files/ - ├── config/env/ - │ ├── default.sample - │ └── examples/alpine/ - ├── data/ - └── defaults/ +```bash +# Regenerate Dockerfile and related files from current .env.scripts +gen-dockerfile --dir ./myapp --update + +# Regenerate workflow file only +gen-dockerfile --dir ./myapp actions ``` -### Key Dockerfile Features +### Adding a New Container from Scratch -1. **Multi-stage build** - Separates build from runtime -2. **Bash shell** - Replaces default sh with bash -3. **Tini init** - Proper signal handling -4. **Health checks** - Built-in container health monitoring -5. **Security** - Uses gosu for proper privilege dropping -6. **Reproducibility** - All setup scripted and versioned - ---- - -## Container Labels - -All containers include OpenContainers standard labels: - -```dockerfile -LABEL org.opencontainers.image.vendor="CasjaysDev" -LABEL org.opencontainers.image.authors="CasjaysDev" -LABEL org.opencontainers.image.description="Containerized version of ${IMAGE_NAME}" -LABEL org.opencontainers.image.source="https://github.com/casjaysdevdocker/${IMAGE_NAME}" -LABEL org.opencontainers.image.documentation="https://github.com/casjaysdevdocker/${IMAGE_NAME}" -``` +1. `gen-dockerfile --dir /path/to/new-container --nogit alpine` +2. Edit `.env.scripts` — set `ENV_REGISTRY_REPO`, `ENV_REGISTRY_PUSH`, `ENV_GIT_REPO_URL` +3. Copy `04-example.sh` from `.github/example/` as the starting point for init.d scripts +4. Add application-specific setup in `rootfs/root/docker/setup/05-custom.sh` --- ## Project Categories ### Web Servers -- nginx, lighttpd, caddy, cherokee +- nginx, lighttpd, caddy ### Databases - mysql, mariadb, postgres, mongodb, couchdb, redis, valkey, sqlite @@ -430,7 +719,7 @@ LABEL org.opencontainers.image.documentation="https://github.com/casjaysdevdocke - code, neovim, vim, nodejs, python, php, deno, bun ### Container Tools -- docker, podman, buildah +- docker, podman ### Git Services - gitea, forgejo, soft-serve, opengist @@ -445,93 +734,17 @@ LABEL org.opencontainers.image.documentation="https://github.com/casjaysdevdocke - mailman, postfix, gotify, ntfy, apprise ### Cloud Services -- nextcloud, coolify, opencloud, wordpress - -### Security -- ssl-ca +- nextcloud, wordpress ### Utilities -- tools, transmission, aria2, tftpd, dictd, stikked, lenpaste, pastebin, commitment, enclosed, theHarvester, rarbg, squidguard, webmin, wttr, xfce4 - ---- - -## Development Workflow - -### Creating a New Container - -1. Run gen-dockerfile: - ```bash - gen-dockerfile --dir ./myapp myapp - ``` - -2. Customize setup scripts in `rootfs/root/docker/setup/` - -3. Add application-specific configuration - -4. Build and test: - ```bash - docker build -t myapp . - docker run -it myapp - ``` - -5. Commit and push to trigger CI/CD - ---- - -## Environment Variable Configuration - -Each container supports configuration via `.env.scripts`: - -```bash -# Versions -##@Version : 202601291955-git - -# Entrypoint Settings -DOCKER_ENTYPOINT_PORTS_WEB="" -DOCKER_ENTYPOINT_PORTS_SRV="" -DOCKER_ENTYPOINT_HEALTH_APPS="" -DOCKER_ENTYPOINT_HEALTH_ENDPOINTS="" - -# Application specific vars -# ... -``` - ---- - -## Common Issues and Solutions - -### Bash Integration -All containers replace `/bin/sh` with bash for consistency and feature support. - -### Package Management -The `pkmgr` wrapper abstracts differences between Alpine (apk), Debian (apt), and RedHat (yum). - -### Init System -Tini is used as PID 1 to handle zombie processes and signal forwarding properly. - -### Permissions -Gosu is used instead of su/sudo for proper privilege dropping without TTY issues. - ---- - -## Repository Statistics - -- **Total Projects:** 71 -- **Total Files/Directories (depth 2-3):** 2,419 -- **Base Image:** Alpine Linux -- **Template Tool:** gen-dockerfile -- **CI/CD:** Gitea Actions + Jenkins (legacy) -- **Registry:** hub.docker.com/casjaysdevdocker +- tools, transmission, aria2, tftpd, ssl-ca, wttr, xfce4, webmin --- ## Resources -- **Docker Hub:** https://hub.docker.com/casjaysdevdocker/ -- **Git Repository:** https://github.com/casjaysdevdocker/ -- **gen-dockerfile Tool:** /usr/local/bin/gen-dockerfile -- **Template Source:** /usr/local/share/CasjaysDev/scripts/templates/dockerfiles/ - ---- - -*This specification was generated based on repository analysis and the gen-dockerfile alpine template.* +- **Docker Hub:** +- **Git Repository:** +- **gen-dockerfile Tool:** `/usr/local/bin/gen-dockerfile` (source: `casjay-dotfiles/scripts/bin/gen-dockerfile`) +- **Template Source:** `casjay-dotfiles/scripts/templates/dockerfiles/` +- **Example Project:** `.github/example/`