commit 134db61c1840bd33be6ab2d8a2fe2dd8a2c3948f Author: casjay Date: Fri Jun 26 14:10:54 2026 -0400 ๐Ÿฆˆ๐Ÿ ๐Ÿœโ— Initial Commit โ—๐Ÿœ๐Ÿฆˆ๐Ÿ  diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..71c00b7 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,17 @@ +# Files to ignore +# Tell docker to ignore .gitkeep +.gitkeep +# Tell docker to ignore .gitignore +.gitignore +# Tell docker to ignore node_modules/** +node_modules/** +# Tell docker to ignore .node_modules/** +.node_modules/** +# Tell docker to ignore **/.gitkeep +**/.gitkeep +# Tell docker to ignore **/.gitignore +**/.gitignore +# Tell docker to ignore **/node_modules/** +**/node_modules/** +# Tell docker to ignore **/.node_modules/** +**/.node_modules/** diff --git a/.env.scripts b/.env.scripts new file mode 100644 index 0000000..c404ea2 --- /dev/null +++ b/.env.scripts @@ -0,0 +1,80 @@ +# - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202606261156-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : WTFPL +# @@Copyright : Copyright 2026 CasjaysDev +# @@Created : Fri Jun 26 11:56:35 AM EDT 2026 +# @@File : .env.scripts +# @@Description : Variables for gen-dockerfile and buildx scripts +# @@Changelog : newScript +# @@TODO : Refactor code +# @@Other : N/A +# @@Resource : N/A +# @@Terminal App : yes +# @@sudo/root : yes +# @@Template : templates/dockerfiles/dotenv.template +# - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1001,SC1003,SC2001,SC2003,SC2016,SC2031,SC2090,SC2115,SC2120,SC2155,SC2199,SC2229,SC2317,SC2329 +# - - - - - - - - - - - - - - - - - - - - - - - - - +# entrypoint Settings +DOCKER_ENTYPOINT_PORTS_WEB="80" +DOCKER_ENTYPOINT_PORTS_SRV="${DOCKER_ENTYPOINT_PORTS_SRV}" +DOCKER_ENTYPOINT_HEALTH_APPS="nginx" +DOCKER_ENTYPOINT_HEALTH_ENDPOINTS="http://localhost/" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Dockerfile info +ENV_DOCKERFILE="Dockerfile" +# ENV_REGISTRY_REPO: Registry repository/image name +ENV_REGISTRY_REPO="super-productivity" +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/super-productivity" +# ENV_REGISTRY_URL: Registry provider base URL (for example https://docker.io) +ENV_REGISTRY_URL="https://docker.io" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Push Configuration +# ENV_REGISTRY_PUSH: Complete push destination derived from registry/org/repo +ENV_REGISTRY_PUSH="casjaysdevdocker/super-productivity" +# 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}" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Env +SERVICE_PORT="80" +EXPOSE_PORTS="80" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# IF using a lanuage such as go, php, rust, ruby, etc set the version here. +LANG_VERSION="" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Versions +PHP_VERSION="system" +NODE_VERSION="system" +NODE_MANAGER="system" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Default directories +WWW_ROOT_DIR="/usr/local/share/httpd/default" +# - - - - - - - - - - - - - - - - - - - - - - - - - +ENV_PACKAGES="nginx jq curl" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# ex: ts=2 sw=2 et filetype=sh +# - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..0861c5d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,86 @@ +# Template generated on Sun May 24 11:58:45 AM EDT 2026 from https://github.com/alexkaratarakis/gitattributes" +# Common settings that generally should always be used with your language specific settings +# Auto detect text files and perform LF normalization +* text=auto +# The above will handle all files NOT found below +# Documents +*.bibtex text diff=bibtex +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain +*.md text diff=markdown +*.mdx text diff=markdown +*.tex text diff=tex +*.adoc text +*.textile text +*.mustache text +*.csv text eol=crlf +*.tab text +*.tsv text +*.txt text +*.sql text +*.epub diff=astextplain +# Graphics +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.tif binary +*.tiff binary +*.ico binary +# SVG treated as text by default. +*.svg text +# If you want to treat it as binary, +# use the following line instead. +# *.svg binary +*.eps binary +# Scripts +*.bash text eol=lf +*.fish text eol=lf +*.ksh text eol=lf +*.sh text eol=lf +*.zsh text eol=lf +# These are explicitly windows files and should use crlf +*.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf +# Serialisation +*.json text +*.toml text +*.xml text +*.yaml text +*.yml text +# Archives +*.7z binary +*.bz binary +*.bz2 binary +*.bzip2 binary +*.gz binary +*.lz binary +*.lzma binary +*.rar binary +*.tar binary +*.taz binary +*.tbz binary +*.tbz2 binary +*.tgz binary +*.tlz binary +*.txz binary +*.xz binary +*.Z binary +*.zip binary +*.zst binary +# Text files where line endings should be preserved +*.patch -text +# Exclude files from exporting +.gitattributes export-ignore +.gitignore export-ignore +.gitkeep export-ignore + diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..efef31c --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,86 @@ +name: Build and Push + +on: + push: + branches: [main] + schedule: + - cron: '0 2 1 * *' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 + + - name: Compute build metadata + id: meta + run: | + echo "build_date=$(date -u +%Y%m%d%H%M)" >> "$GITHUB_OUTPUT" + echo "tag_yymm=$(date -u +%y%m)" >> "$GITHUB_OUTPUT" + echo "git_commit=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" + echo "registry_host=$(echo '${{ github.server_url }}' | sed 's|https://||')" >> "$GITHUB_OUTPUT" + + # โ”€โ”€ Always: login to Gitea (GITEA_TOKEN is auto-provided) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + - name: Login to Gitea registry + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 + with: + registry: ${{ steps.meta.outputs.registry_host }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GITEA_TOKEN }} + + # โ”€โ”€ Optional: login to external registry when vars.DOCKER_USERNAME is set โ”€โ”€ + # vars.DOCKER_REGISTRY defaults to docker.io; set it to push elsewhere. + # Login uses vars.DOCKER_USERNAME; secrets.DOCKER_PASSWORD is passed only + # via with: and never touches a shell. + - name: Login to Docker Hub + if: vars.DOCKER_USERNAME != '' + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 + with: + registry: ${{ vars.DOCKER_REGISTRY || 'docker.io' }} + username: ${{ vars.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + # โ”€โ”€ Build once, push to all logged-in registries โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + # Image namespace uses vars.DOCKER_ORG when set, falls back to vars.DOCKER_USERNAME. + # yymm tag pushed first; latest pushed last so registries show :latest as current. + - name: Build and push + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ${{ steps.meta.outputs.registry_host }}/${{ github.repository }}:${{ steps.meta.outputs.tag_yymm }} + ${{ vars.DOCKER_USERNAME != '' && format('{0}/{1}/{2}:{3}', vars.DOCKER_REGISTRY || 'docker.io', vars.DOCKER_ORG || vars.DOCKER_USERNAME, github.event.repository.name, steps.meta.outputs.tag_yymm) || '' }} + ${{ steps.meta.outputs.registry_host }}/${{ github.repository }}:latest + ${{ vars.DOCKER_USERNAME != '' && format('{0}/{1}/{2}:{3}', vars.DOCKER_REGISTRY || 'docker.io', vars.DOCKER_ORG || vars.DOCKER_USERNAME, github.event.repository.name, 'latest') || '' }} + build-args: | + BUILD_DATE=${{ steps.meta.outputs.build_date }} + GIT_COMMIT=${{ steps.meta.outputs.git_commit }} + BUILD_VERSION=${{ steps.meta.outputs.tag_yymm }} + annotations: | + org.opencontainers.image.created=${{ steps.meta.outputs.build_date }} + org.opencontainers.image.version=latest + org.opencontainers.image.revision=${{ steps.meta.outputs.git_commit }} + org.opencontainers.image.title=${{ github.event.repository.name }} + org.opencontainers.image.description=Containerized version of ${{ github.event.repository.name }} + org.opencontainers.image.vendor=CasjaysDev + org.opencontainers.image.authors=CasjaysDev + org.opencontainers.image.licenses=WTFPL + org.opencontainers.image.url=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.documentation=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.vcs-type=Git + com.github.containers.toolbox=false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d16ea5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,242 @@ +# gitignore created on 06/26/26 at 11:56 +# Disable reminder in prompt +ignoredirmessage + +# ignore .build_failed files +**/.build_failed* + +# OS generated files + +### Linux ### +# Backup files left by editors +*~ + +# Temporary files left when a process holds an open handle to a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# NFS stale file handles +.nfs* + +### macOS ### +.DS_Store +.DS_Store? +.AppleDouble +.LSOverride + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# iCloud generated files +*.icloud + +### Windows ### +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Crash dump files +*.stackdump + +# Core dumps (Linux/macOS) +core +core.* +vgcore.* + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Editors ### +# Visual Studio Code +.vscode/ +!.vscode/extensions.json + +# JetBrains IDEs (IntelliJ, GoLand, RustRover, PyCharm, etc.) +.idea/ +*.iml +*.iws +*.ipr + +# Vim / Neovim +*.swp +*.swo +.netrwhist +Session.vim +.vim/ + +# Sublime Text +*.sublime-workspace +*.sublime-project + +# Eclipse / generic Java IDEs +.project +.classpath +.factorypath +.settings/ + +### AI tool local configs (personal settings, never commit) ### +# Claude Code +.claude/settings.local.json +.claude/*.lock + +# Cursor +.cursor/ +.cursorignore +.cursorindexingignore + +# GitHub Copilot +.copilot/ + +# Codeium +.codeium/ + +# Tabnine +.tabnine/ + +# Aider +.aider/ +.aider.conf.yml +.aider.model.settings.yml +.aiderignore + +# General AI assistant local state +.ai/ +.ai.local/ + +### Environment and secrets ### +# Local env overrides โ€” never commit credentials +.env +.env.local +.env.*.local + +# Private keys and certificates +*.pem +*.key +*.p12 +*.pfx + +### Build artifacts ### +build/ +dist/ +out/ + +# Rust +target/ + +# C / C++ / compiled objects +*.o +*.a +*.so +*.dylib +*.dll +*.exe + +### Dependency directories ### +# Node +node_modules/ + +# Go (vendored deps are sometimes committed intentionally, so gitignore only the cache) +# vendor/ + +# Python +__pycache__/ +*.pyc +*.pyo +*.pyd +.Python +*.egg-info/ +.eggs/ +.venv/ +venv/ +env/ + +### Logs ### +*.log +logs/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +### Temporary and cache ### +tmp/ +.tmp/ +*.tmp +*.cache +.cache/ + +### Test and coverage ### +coverage/ +.coverage +*.cover +*.coverprofile +htmlcov/ +.nyc_output/ +.pytest_cache/ +.tox/ + +### Misc โ€” always allow ### +!*/README* +!inc/main.bash + +### Project-specific patterns ### +# ignore commit message files +**/.gitcommit + +# ignore backup files +**/*.bak + +# ignore .no_push files +**/.no_push +**/.nopush + +# ignore .no_git files +**/.no_git + +# ignore .installed marker files +**/.installed + +# ignore work-in-progress rewrite/refactor scripts +**/*.rewrite.sh +**/*.refactor.sh + +# ignore local override scripts and configs +**/*.local.sh +**/*.local.conf +**/*.local.yaml +**/*.local.yml + diff --git a/AI.md b/AI.md new file mode 100644 index 0000000..6c1e27b --- /dev/null +++ b/AI.md @@ -0,0 +1,844 @@ +# Docker Container Repository Specification + +## Repository Overview + +**Repository:** casjaysdevdocker +**Maintainer:** CasjaysDev +**License:** WTFPL / MIT +**Purpose:** Collection of containerized applications using standardized Alpine-based templates + +--- + +## Repository Structure + +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 +``` + +--- + +## Standard Project Structure + +Each project directory contains: + +``` +project-name/ +โ”œโ”€โ”€ .dockerignore # [generated] Docker build exclusions +โ”œโ”€โ”€ .env.scripts # [generated] Environment variables for gen-dockerfile +โ”œโ”€โ”€ .git/ # Git repository +โ”œโ”€โ”€ .gitattributes # [generated] Git attributes +โ”œโ”€โ”€ .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 + โ””โ”€โ”€ 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/ +``` + +**`[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. + +--- + +## gen-dockerfile Tool + +All containers are built using the **gen-dockerfile** tool. 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 | 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 | + +> **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/