mirror of
https://github.com/dockersrc/alpine
synced 2026-07-22 22:49:54 -04:00
6a19d9843b
Build and Push 3.14 / build (push) Has been cancelled
Build and Push 3.15 / build (push) Has been cancelled
Build and Push 3.16 / build (push) Has been cancelled
Build and Push 3.17 / build (push) Has been cancelled
Build and Push 3.18 / build (push) Has been cancelled
Build and Push 3.19 / build (push) Has been cancelled
Build and Push 3.20 / build (push) Has been cancelled
Build and Push 3.21 / build (push) Has been cancelled
Build and Push 3.22 / build (push) Has been cancelled
Build and Push 3.23 / build (push) Has been cancelled
Build and Push edge / build (push) Has been cancelled
Build and Push / build (push) Has been cancelled
- .env.scripts, .env.scripts.3.14 through .env.scripts.3.22, .env.scripts.3.23, .env.scripts.edge: fixed ENV_PULL_URL from the corrupted "casjaysdev/alpine" back to the correct upstream "alpine" (ENV_PULL_URL is authoritative and is baked directly into ARG PULL_URL in the generated Dockerfile, overriding --distro-name and GEN_DOCKERFILE_APP_DIR auto-detection) - Dockerfile, Dockerfile.3.14 through Dockerfile.3.22, Dockerfile.3.23, Dockerfile.edge, Dockerfile.testing: regenerated all 12 Dockerfile variants from the updated Dockerfile template — picks up ssmtp in PACK_LIST (SMTP server for out-of-the-box mail support), the new HOSTNAME format (casjaysdevdocker-$name), and the current template structure; PULL_URL now correctly resolves to "alpine" in every variant - AI.md: pre-existing working-tree edit updating install/compose path examples from /srv to /var/lib/srv (unrelated to the Dockerfile regeneration, included as part of this working tree's already-staged state) AI.md Dockerfile Dockerfile.3.14 Dockerfile.3.15 Dockerfile.3.16 Dockerfile.3.17 Dockerfile.3.18 Dockerfile.3.19 Dockerfile.3.20 Dockerfile.3.21 Dockerfile.3.22 Dockerfile.3.23 Dockerfile.edge Dockerfile.testing .env.scripts .env.scripts.3.14 .env.scripts.3.15 .env.scripts.3.16 .env.scripts.3.17 .env.scripts.3.18 .env.scripts.3.19 .env.scripts.3.20 .env.scripts.3.21 .env.scripts.3.22 .env.scripts.3.23 .env.scripts.edge
796 lines
28 KiB
Markdown
796 lines
28 KiB
Markdown
# AI.md — Docker Template Update Runbook
|
|
|
|
Run this whenever upstream templates in `casjay-dotfiles/scripts` are updated.
|
|
This file is **permanent** — do not delete it. It is the maintenance runbook for this repo.
|
|
|
|
---
|
|
|
|
## What This Runbook Does
|
|
|
|
The upstream Docker templates in `casjay-dotfiles/scripts` change over time. Generated files that
|
|
are left in place may call removed functions, source removed templates, or reference removed env
|
|
vars — causing runtime failures. This runbook brings every generated file in the repo up to date.
|
|
|
|
Files updated:
|
|
|
|
- `.env.scripts` — vars synced to current template (added/removed)
|
|
- `Dockerfile` / `Dockerfile.*` — removed ARG lines dropped, new ones added
|
|
- `rootfs/usr/local/bin/*` — all template-generated bin scripts replaced from temp dir
|
|
- `rootfs/usr/local/etc/docker/functions/entrypoint.sh` — replaced from temp dir
|
|
- `rootfs/usr/local/etc/docker/init.d/*.sh` — regenerated; app-specific values restored
|
|
- `rootfs/root/docker/setup/00-*.sh` through `07-*.sh` — replaced from temp dir
|
|
- `README.md` — rewritten to current standard layout
|
|
- Non-standard rootfs root-level directories — files migrated; stale dirs removed
|
|
|
|
---
|
|
|
|
## Template System Reference
|
|
|
|
This section documents the current state of `templates/dockerfiles/` and key
|
|
`bin/gen-dockerfile` variables. Keep it in sync whenever upstream templates change.
|
|
|
|
### Template inventory
|
|
|
|
| Template | Final stage | Init / PID 1 | Base OS |
|
|
|----------|-------------|--------------|---------|
|
|
| `alpine.template` | `scratch.template` | tini | Alpine |
|
|
| `debian.template` | `scratch.template` | tini | Debian |
|
|
| `ubuntu.template` | `scratch.template` | tini | Ubuntu |
|
|
| `rhel.template` | `scratch.template` | tini | AlmaLinux |
|
|
| `archlinux.template` | `scratch.template` | tini | Arch Linux (see multi-arch note) |
|
|
| `web.template` | `systemd.template` | `/sbin/init` | Debian |
|
|
| `xorg.template` | `systemd.template` | `/sbin/init` | Debian |
|
|
|
|
### Final-stage templates
|
|
|
|
`scratch.template` — used by all non-GUI templates.
|
|
- `ENTRYPOINT [ "tini", "-p", "SIGTERM","--", "/usr/local/bin/entrypoint.sh" ]`
|
|
- `STOPSIGNAL SIGRTMIN+3`
|
|
|
|
`systemd.template` — used by `web` and `xorg` (systemd runs as PID 1; tini is redundant).
|
|
- `ENTRYPOINT [ "/sbin/init" ]`
|
|
- `STOPSIGNAL SIGRTMIN+3`
|
|
- No `tini_provider` stage, no `COPY --from=tini_provider` line.
|
|
|
|
Both templates are identical apart from `ENTRYPOINT`. OCI labels, `ENV HOSTNAME`, and
|
|
`VOLUME`/`EXPOSE`/`HEALTHCHECK` are the same in both.
|
|
|
|
### OCI label standard
|
|
|
|
Both `scratch.template` and `systemd.template` emit these labels (no others):
|
|
|
|
```
|
|
LABEL maintainer="${GEN_DOCKERFILE_MAINTAINER}"
|
|
LABEL org.opencontainers.image.vendor="${GEN_DOCKERFILE_VENDOR:-CasjaysDev}"
|
|
LABEL org.opencontainers.image.authors="${GEN_DOCKERFILE_AUTHOR:-CasjaysDev}"
|
|
LABEL org.opencontainers.image.licenses="${LICENSE}"
|
|
LABEL org.opencontainers.image.title="${IMAGE_NAME}"
|
|
LABEL org.opencontainers.image.description="Containerized version of ${IMAGE_NAME}"
|
|
LABEL org.opencontainers.image.created="${BUILD_DATE}"
|
|
LABEL org.opencontainers.image.version="${BUILD_VERSION}"
|
|
LABEL org.opencontainers.image.revision="${GIT_COMMIT}"
|
|
LABEL org.opencontainers.image.url="${GEN_DOCKERFILE_HUB_REPO}"
|
|
LABEL org.opencontainers.image.source="${GEN_DOCKERFILE_GIT_REPO}"
|
|
LABEL org.opencontainers.image.documentation="${GEN_DOCKERFILE_GIT_REPO}"
|
|
LABEL org.opencontainers.image.vcs-type="Git"
|
|
LABEL com.github.containers.toolbox="false"
|
|
```
|
|
|
|
Shell-expanded values (no `\`) are evaluated at template-render time by
|
|
`gen-dockerfile`. Dollar-escaped values (`\${...}`) become literal Docker
|
|
`ARG`/`ENV` references in the generated `Dockerfile`.
|
|
|
|
Removed labels (do not re-add):
|
|
- `org.opencontainers.image.base.name` — belongs on the base image, not the app image
|
|
- `org.opencontainers.image.schema-version` — non-spec; redundant with `version`
|
|
- Any duplicate `authors` or `source` entries
|
|
|
|
### HOSTNAME convention
|
|
|
|
All templates set `ENV HOSTNAME="casjaysdevdocker-${IMAGE_NAME}"` in every stage
|
|
that declares it. The prefix is always `casjaysdevdocker-`, never `casjaysdev-`.
|
|
|
|
### `GEN_DOCKERFILE_APP_DIR` and pull URL logic
|
|
|
|
`GEN_DOCKERFILE_APP_DIR` is auto-detected in `bin/gen-dockerfile` from the parent
|
|
directory of `$PWD` (i.e. the GitHub org the project lives in):
|
|
|
|
```bash
|
|
GEN_DOCKERFILE_APP_DIR="${GEN_DOCKERFILE_APP_DIR:-$(basename -- "$(dirname -- "$PWD")")}"
|
|
```
|
|
|
|
It controls which base images `GEN_DOCKER_SPECIFY_IMAGE_SOURCE_*` default to:
|
|
|
|
```bash
|
|
if [ "${GEN_DOCKERFILE_APP_DIR}" = "casjaysdevdocker" ]; then
|
|
# Pull from pre-built casjaysdev/* base images on Docker Hub
|
|
GEN_DOCKER_SPECIFY_IMAGE_SOURCE_RHEL="${GEN_DOCKER_SPECIFY_IMAGE_SOURCE_RHEL:-casjaysdev/almalinux}"
|
|
GEN_DOCKER_SPECIFY_IMAGE_SOURCE_ALPINE="${GEN_DOCKER_SPECIFY_IMAGE_SOURCE_ALPINE:-casjaysdev/alpine}"
|
|
GEN_DOCKER_SPECIFY_IMAGE_SOURCE_DEBIAN="${GEN_DOCKER_SPECIFY_IMAGE_SOURCE_DEBIAN:-casjaysdev/debian}"
|
|
GEN_DOCKER_SPECIFY_IMAGE_SOURCE_UBUNTU="${GEN_DOCKER_SPECIFY_IMAGE_SOURCE_UBUNTU:-casjaysdev/ubuntu}"
|
|
GEN_DOCKER_SPECIFY_IMAGE_SOURCE_ARCHLINUX="${GEN_DOCKER_SPECIFY_IMAGE_SOURCE_ARCHLINUX:-casjaysdev/archlinux}"
|
|
else
|
|
# Pull from upstream official images (dockersrc/* builds its own base images)
|
|
GEN_DOCKER_SPECIFY_IMAGE_SOURCE_RHEL="${GEN_DOCKER_SPECIFY_IMAGE_SOURCE_RHEL:-almalinux}"
|
|
GEN_DOCKER_SPECIFY_IMAGE_SOURCE_ALPINE="${GEN_DOCKER_SPECIFY_IMAGE_SOURCE_ALPINE:-alpine}"
|
|
GEN_DOCKER_SPECIFY_IMAGE_SOURCE_DEBIAN="${GEN_DOCKER_SPECIFY_IMAGE_SOURCE_DEBIAN:-debian}"
|
|
GEN_DOCKER_SPECIFY_IMAGE_SOURCE_UBUNTU="${GEN_DOCKER_SPECIFY_IMAGE_SOURCE_UBUNTU:-ubuntu}"
|
|
GEN_DOCKER_SPECIFY_IMAGE_SOURCE_ARCHLINUX="${GEN_DOCKER_SPECIFY_IMAGE_SOURCE_ARCHLINUX:-archlinux}"
|
|
fi
|
|
```
|
|
|
|
Summary:
|
|
- `casjaysdevdocker/*` repos → `FROM casjaysdev/<distro>:latest` (already multi-arch)
|
|
- `dockersrc/*` and all other orgs → `FROM <distro>:latest` (upstream official images)
|
|
|
|
The Docker Hub push org (`casjaysdev`) is unchanged regardless of `GEN_DOCKERFILE_APP_DIR`.
|
|
|
|
### Arch Linux multi-arch (`archlinux.template`)
|
|
|
|
When `GEN_DOCKERFILE_APP_DIR != "casjaysdevdocker"` (i.e. building a base image in
|
|
`dockersrc/archlinux`), the template emits a three-stage FROM to support both
|
|
`linux/amd64` and `linux/arm64`:
|
|
|
|
```dockerfile
|
|
ARG TARGETARCH
|
|
ARG TARGETPLATFORM
|
|
FROM --platform=${TARGETPLATFORM} archlinux:latest AS base-amd64
|
|
FROM --platform=${TARGETPLATFORM} lopsided/archlinux-arm64v8:latest AS base-arm64
|
|
FROM base-${TARGETARCH} AS build
|
|
```
|
|
|
|
When `GEN_DOCKERFILE_APP_DIR = "casjaysdevdocker"`, `casjaysdev/archlinux` is a
|
|
multi-arch manifest so a single `FROM ${PULL_URL}:${DISTRO_VERSION} AS build` suffices.
|
|
|
|
### `web.template` packages
|
|
|
|
The `web` template installs the following systemd + noVNC stack in the build stage:
|
|
|
|
```
|
|
systemd systemd-sysv dbus dbus-x11 procps
|
|
tigervnc-standalone-server novnc openbox xdotool
|
|
```
|
|
|
|
Default ports: `SERVICE_PORT="5800"`, `EXPOSE_PORTS="5800 5900"`.
|
|
|
|
### `xorg.template` packages
|
|
|
|
The `xorg` template installs the following systemd + Xorg stack in the build stage:
|
|
|
|
```
|
|
systemd systemd-sysv dbus dbus-x11 procps
|
|
xserver-xorg x11-xserver-utils xinit
|
|
```
|
|
|
|
### `debian.template` / `ubuntu.template` — RUN continuation fix
|
|
|
|
The first `RUN` block must have `; \` after the `echo` line so
|
|
`export DEBIAN_FRONTEND=noninteractive` executes before `apt-get`:
|
|
|
|
```dockerfile
|
|
RUN set -e; \
|
|
echo "Updating the system"; \
|
|
export DEBIAN_FRONTEND=noninteractive; \
|
|
apt-get update && apt-get upgrade -yy && apt-get dist-upgrade -yy
|
|
```
|
|
|
|
Without the `; \` the export is a no-op and `apt-get` may prompt interactively.
|
|
|
|
---
|
|
|
|
## Tool Reference
|
|
|
|
### `gen-dockerfile`
|
|
|
|
```
|
|
Usage: gen-dockerfile [options] [dir] [template] [repo-name] [git-repo-url]
|
|
```
|
|
|
|
Flags used in this runbook:
|
|
|
|
| Flag | Meaning |
|
|
|------|---------|
|
|
| `--update` | Rewrite `.env.scripts` (add/drop vars against current template) and update ARG/LABEL lines in every `Dockerfile`/`Dockerfile.*`. Does not touch any other file. |
|
|
| `--nogit` | Do not init or commit a git repo — required when running inside an existing repo. |
|
|
| `--dir PATH` | Operate on / write output to PATH instead of `$PWD`. |
|
|
| `--template NAME` | Template to use (`alpine`, `debian`, `rhel`, `scratch`, `web`, `xorg`). Defaults to `alpine` if omitted. |
|
|
| `--repo NAME` | Registry repo name (image basename). Defaults to the directory name if omitted. |
|
|
| `--org NAME` | Alias for `--user`. Sets the registry owner / GitHub org. |
|
|
|
|
Resolution order when a value is not given by a flag: flags → git remote → project dirs → defaults.
|
|
|
|
### `gen-script`
|
|
|
|
```
|
|
Usage: gen-script [options] [template] [filename]
|
|
```
|
|
|
|
Flags and env vars used in this runbook:
|
|
|
|
| Flag / env var | Meaning |
|
|
|----------------|---------|
|
|
| `--dir PATH` | Write the generated file to PATH instead of `$PWD`. The output file is `PATH/filename`. |
|
|
| `-n` / `--name VALUE` | Sets the service name substituted into the generated file. In the `other/start-service` template this fills `REPLACE_SERVICE_NAME` — e.g. `--name nginx` pre-populates `SERVICE_NAME=nginx` in the output without a separate `sed` step. |
|
|
| `GEN_SCRIPT_OVERWRITE="Y"` | Overwrite the output file without prompting. Default is `"A"` (ask). Must be set when the target file already exists or gen-script will prompt even with `GEN_SCRIPT_EDITFILE="N"`. |
|
|
| `GEN_SCRIPT_EDITFILE="N"` | Suppress the interactive editor prompt after generation. Note: `-e`/`--no` sets BOTH this AND `GEN_SCRIPT_OVERWRITE="Y"` in one flag; setting this env var alone does NOT set OVERWRITE. |
|
|
| `other/start-service` | Template path — words joined by `/`, matching the `@@Template` header in the existing script. This arg is positional (first non-flag arg). |
|
|
| `filename` | Output file basename — second positional arg. Combined with `--dir` to form the full output path. |
|
|
|
|
Other available flags (for reference, not used in this runbook):
|
|
|
|
| Flag | Meaning |
|
|
|------|---------|
|
|
| `-k` / `--keep` | Do not overwrite an existing file. |
|
|
| `--replace` | Import and create a new header to replace an older one. |
|
|
| `-d` / `--desc` | Set the description in the generated file header. |
|
|
| `-p` / `--prev` | Set the header based on an existing file (copies its metadata). |
|
|
|
|
---
|
|
|
|
## Session Start
|
|
|
|
```bash
|
|
git status --porcelain
|
|
# If dirty:
|
|
git stash push -m "session-start auto-stash"
|
|
git pull
|
|
# If stashed:
|
|
git stash pop
|
|
# If stash pop conflicts: report the conflicting files and stop — never auto-resolve
|
|
```
|
|
|
|
If `git pull` fails (no remote, offline, diverged): report it and stop.
|
|
|
|
---
|
|
|
|
## Variables
|
|
|
|
```bash
|
|
name="$(basename "$PWD")"
|
|
SCRIPTS_DIR="${CASJAYSDEVDIR:-/usr/local/share/CasjaysDev/scripts}"
|
|
TEMPLATE_DIR="$SCRIPTS_DIR/templates"
|
|
|
|
# Detect repo type: base repos (dockersrc) have Dockerfile.* variant files
|
|
if find . -maxdepth 1 -name 'Dockerfile.*' -type f | grep -q -- .; then
|
|
REPO_TYPE="base"
|
|
org="dockersrc"
|
|
else
|
|
REPO_TYPE="app"
|
|
org="casjaysdevdocker"
|
|
fi
|
|
|
|
# GEN_DOCKERFILE_APP_DIR is auto-detected by gen-dockerfile from the parent of $PWD.
|
|
# For repos under casjaysdevdocker/: pull base from casjaysdev/* (pre-built multi-arch).
|
|
# For repos under dockersrc/ or any other org: pull from upstream official images.
|
|
# Override by setting GEN_DOCKERFILE_APP_DIR in the environment before calling gen-dockerfile.
|
|
```
|
|
|
|
---
|
|
|
|
## Step 1 — Sync `.env.scripts` and Dockerfile ARG lines
|
|
|
|
Run for **all** repos (both app and base):
|
|
|
|
```bash
|
|
gen-dockerfile --update --nogit --dir .
|
|
```
|
|
|
|
This rewrites `.env.scripts` against the current dotenv template: adds vars the template now
|
|
includes, drops vars it no longer includes (e.g. `DEFAULT_TEMPLATE_DIR`, `DEFAULT_FILE_DIR`,
|
|
`DEFAULT_DATA_DIR`, `DEFAULT_CONF_DIR`), and preserves all project-specific values
|
|
(`ENV_REGISTRY_REPO`, `ENV_USE_TEMPLATE`, `ENV_PACKAGES`, etc.).
|
|
|
|
It also updates ARG lines in every Dockerfile:
|
|
- App repos (`REPO_TYPE=app`): updates `Dockerfile` only — `ARG IMAGE_NAME=`, `ARG IMAGE_REPO=`,
|
|
`LABEL org.opencontainers.*`, and any removed ARG lines.
|
|
- Base repos (`REPO_TYPE=base`): same changes applied to `Dockerfile` AND all `Dockerfile.*`
|
|
variant files.
|
|
|
|
All other file content is untouched.
|
|
|
|
After running, capture the list of removed vars for use in Step 5:
|
|
|
|
```bash
|
|
removed_vars="$(git diff .env.scripts | grep -- '^-[A-Z_][A-Z0-9_]*=' | sed 's/^-//' | cut -d= -f1)"
|
|
printf 'Removed vars: %s\n' "$removed_vars"
|
|
```
|
|
|
|
---
|
|
|
|
## Step 2 — Regenerate all rootfs files from temp dir
|
|
|
|
Generate a complete fresh tree into a temp dir. Every file produced here is the authoritative
|
|
replacement for its counterpart in this repo — old copies may reference removed functions or
|
|
templates and will cause runtime failures if left in place.
|
|
|
|
```bash
|
|
tmpdir="$(mktemp -d "/tmp/gen-${name}-XXXXXX")"
|
|
|
|
if [ "$REPO_TYPE" = "app" ]; then
|
|
template="$(grep -- '^ENV_USE_TEMPLATE=' .env.scripts | cut -d= -f2 | tr -d '"')"
|
|
else
|
|
template="$(grep -- 'using the' Dockerfile | head -1 | sed 's/.*using the \([^ ]*\) template.*/\1/')"
|
|
fi
|
|
|
|
gen-dockerfile --dir "$tmpdir" --nogit --template "$template" --repo "$name" --org "$org"
|
|
```
|
|
|
|
Copy every file the temp dir produced that already exists in this repo — skip nothing:
|
|
|
|
```bash
|
|
find "$tmpdir/rootfs" -type f | while read -r src; do
|
|
rel="${src#"$tmpdir/rootfs/"}"
|
|
dest="rootfs/$rel"
|
|
if [ -f "$dest" ]; then
|
|
cp -f "$src" "$dest"
|
|
fi
|
|
done
|
|
|
|
rm -rf "$tmpdir"
|
|
```
|
|
|
|
This covers: `rootfs/usr/local/bin/entrypoint.sh`, `rootfs/usr/local/bin/pkmgr`,
|
|
`rootfs/usr/local/bin/symlink`, `rootfs/usr/local/bin/copy`, `rootfs/usr/local/bin/healthcheck`,
|
|
`rootfs/usr/local/etc/docker/functions/entrypoint.sh`,
|
|
`rootfs/root/docker/setup/00-*.sh` through `07-*.sh`, and every other file gen-dockerfile
|
|
generates. The copy condition (`-f "$dest"`) means files not already in this repo are not
|
|
added — only existing files are updated.
|
|
|
|
---
|
|
|
|
## Step 3 — Update app-specific bin scripts
|
|
|
|
Some repos have extra scripts in `rootfs/usr/local/bin/` that gen-dockerfile does not generate —
|
|
they are app-specific (e.g. `check-record`, `get_dns_record`). These were not touched in Step 2.
|
|
|
|
For each such script, read its `@@Template` header (line beginning `# @@Template`):
|
|
|
|
**Has `@@Template : shell/sh`**
|
|
Update boilerplate in-place from `$TEMPLATE_DIR/scripts/shell/sh`. Read the template, diff
|
|
against the existing script, apply only the boilerplate changes (version stamp, shellcheck
|
|
disable line, set line, trap lines). These are `#!/usr/bin/env sh` scripts — `set -e` is correct;
|
|
`-o pipefail` is a bashism and must NOT appear. The app-specific logic body is untouched.
|
|
|
|
**Has `@@Template : shell/bash`** (or another template path)
|
|
Same process, using the matching template file. These are `#!/usr/bin/env bash` scripts —
|
|
`set -eo pipefail` is required.
|
|
|
|
**No `@@Template` header**
|
|
Hand-written app logic. Do not modify it.
|
|
|
|
After each edit run the appropriate syntax check:
|
|
|
|
```bash
|
|
# sh scripts
|
|
sh -n "$script"
|
|
# bash scripts
|
|
bash -n "$script"
|
|
```
|
|
|
|
---
|
|
|
|
## Step 4 — Regenerate `init.d/*.sh`
|
|
|
|
`init.d/*.sh` scripts must be regenerated from the current template — never updated in-place.
|
|
Old copies may call functions that have since been removed from `entrypoint.sh`, causing failures.
|
|
Each script also contains app-specific content that must be preserved; extract it before
|
|
regenerating and restore it into the new file.
|
|
|
|
For each `*.sh` in `rootfs/usr/local/etc/docker/init.d/` with `@@Template : other/start-service`
|
|
in its header:
|
|
|
|
**1. Read the existing script AND `$TEMPLATE_DIR/scripts/other/start-service`.**
|
|
|
|
Diff the two. Every line or block present in the existing script but absent from the template is
|
|
app-specific content. Record all of it. It typically includes:
|
|
|
|
- `SERVICE_NAME=` value
|
|
- `EXEC_CMD_BIN=` value
|
|
- `EXEC_CMD_ARGS=` value
|
|
- `DATA_DIR=`, `CONF_DIR=`, `ETC_DIR=`, `TMP_DIR=`, `RUN_DIR=`, `LOG_DIR=` values
|
|
- `SERVICE_USER=` and `SERVICE_GROUP=` values
|
|
- Extra `export` or variable declarations for this service
|
|
- Service-specific env file sourcing (e.g. `. "/config/env/nginx.sh"`)
|
|
- Custom code inside function bodies (pre-start checks, post-start waits, etc.)
|
|
- App-specific functions defined at the top of the file (e.g. `__rndc_key`, `__tsig_key`)
|
|
|
|
**2. Regenerate from the template:**
|
|
|
|
```bash
|
|
init_d_dir="rootfs/usr/local/etc/docker/init.d"
|
|
filename="$(basename "$init_script")"
|
|
svcname="$(grep -- '^SERVICE_NAME=' "$init_script" | cut -d= -f2 | tr -d '"')"
|
|
# GEN_SCRIPT_OVERWRITE="Y" — overwrite the existing file without prompting (default is "A"/ask)
|
|
# GEN_SCRIPT_EDITFILE="N" — suppress the interactive editor after generation
|
|
# --dir — write the output file to init_d_dir/filename
|
|
# --name — pre-fills REPLACE_SERVICE_NAME in the template with the service name,
|
|
# so SERVICE_NAME= is correct in the generated file without a separate sed step
|
|
# other/start-service — template path (positional arg 1, slash-joined words)
|
|
# "$filename" — output file basename (positional arg 2); combined with --dir for full path
|
|
GEN_SCRIPT_OVERWRITE="Y" GEN_SCRIPT_EDITFILE="N" gen-script --dir "$init_d_dir" --name "$svcname" other/start-service "$filename"
|
|
```
|
|
|
|
The regenerated file is `#!/usr/bin/env bash` — it must use `set -eo pipefail`. If gen-script
|
|
emits `set -e` only, fix it:
|
|
|
|
```bash
|
|
sed -i 's/^set -e$/set -eo pipefail/' "$init_d_dir/$filename"
|
|
```
|
|
|
|
**3. Restore all app-specific content.**
|
|
|
|
`SERVICE_NAME` is already correct — `--name "$svcname"` pre-filled it during generation.
|
|
For all other app-specific `KEY=value` lines recorded in step 1:
|
|
|
|
```bash
|
|
sed -i "s|^EXEC_CMD_BIN=.*|EXEC_CMD_BIN=\"/usr/sbin/named\"|" "$init_d_dir/$filename"
|
|
sed -i "s|^EXEC_CMD_ARGS=.*|EXEC_CMD_ARGS=\"-f -u named\"|" "$init_d_dir/$filename"
|
|
```
|
|
|
|
For multi-line function bodies and custom functions, use Edit to splice them into the correct
|
|
location (same function or section they occupied before).
|
|
|
|
The final script must:
|
|
- Only call functions defined in the current `rootfs/usr/local/etc/docker/functions/entrypoint.sh`
|
|
or defined within the script itself
|
|
- Contain all app-specific variable values and custom logic from the old version
|
|
- Pass `bash -n "$init_d_dir/$filename"` with no errors
|
|
|
|
---
|
|
|
|
## Step 5 — Audit for dead variable and function references
|
|
|
|
After regeneration, app-specific code preserved in Steps 3 and 4 may still reference env vars
|
|
removed in Step 1 or functions no longer present in the current `entrypoint.sh`. Find and fix
|
|
every such reference before committing.
|
|
|
|
### 5a — Dead env var references
|
|
|
|
Use `$removed_vars` captured in Step 1. For each removed var, search all scripts:
|
|
|
|
```bash
|
|
for var in $removed_vars; do
|
|
grep -rn -- "\$$var\|\${$var" rootfs/ 2>/dev/null | grep -v -- '\.git'
|
|
done
|
|
```
|
|
|
|
Fix every hit based on context:
|
|
|
|
| Removed var | Replacement |
|
|
|-------------|-------------|
|
|
| `DEFAULT_TEMPLATE_DIR` | Remove the code that used it. The `template-files` directory no longer exists. If the code was copying default configs into `/config` or `/etc`, the entrypoint now handles that from `rootfs/tmp/etc/` at container start. |
|
|
| `DEFAULT_FILE_DIR` | Same as above — remove usages. |
|
|
| `DEFAULT_CONF_DIR` | Replace with `${CONF_DIR:-/etc/$SERVICE_NAME}` or the service-specific hardcoded path. |
|
|
| `DEFAULT_DATA_DIR` | Replace with `${DATA_DIR:-/var/$SERVICE_NAME}` or the service-specific path. |
|
|
| Any other removed var | Determine from context whether to remove the block or substitute the correct current var. |
|
|
|
|
Also search for `__copy_templates` calls — that function copied from `$DEFAULT_TEMPLATE_DIR`
|
|
and is now a no-op since the directory is gone. Remove any call to it in app-specific code:
|
|
|
|
```bash
|
|
grep -rn -- '__copy_templates' rootfs/usr/local/etc/docker/init.d/ rootfs/usr/local/bin/
|
|
```
|
|
|
|
### 5b — Dead function calls
|
|
|
|
The fresh `rootfs/usr/local/etc/docker/functions/entrypoint.sh` from Step 2 is the ground truth
|
|
for what functions are available at container runtime. Extract all defined names:
|
|
|
|
```bash
|
|
defined_fns="$(grep -oE -- '^__[a-zA-Z_]+' \
|
|
rootfs/usr/local/etc/docker/functions/entrypoint.sh | sort -u)"
|
|
```
|
|
|
|
For each script NOT fully replaced from the temp dir (init.d scripts, custom bin scripts), find
|
|
calls to functions that are neither in `$defined_fns` nor defined within the script itself:
|
|
|
|
```bash
|
|
for script in rootfs/usr/local/etc/docker/init.d/*.sh rootfs/usr/local/bin/*; do
|
|
[ -f "$script" ] || continue
|
|
local_fns="$(grep -oE -- '^__[a-zA-Z_]+' "$script" | sort -u)"
|
|
grep -oE -- '__[a-zA-Z_]+' "$script" | sort -u | while read -r fn; do
|
|
if ! printf '%s\n' $defined_fns $local_fns | grep -qx -- "$fn"; then
|
|
printf 'DEAD: %s in %s\n' "$fn" "$script"
|
|
fi
|
|
done
|
|
done
|
|
```
|
|
|
|
For each dead call found:
|
|
|
|
- Check whether the function was renamed in the current template (e.g. `__get_ip` → `__get_ip4`
|
|
or `__get_ip6`) and update the call.
|
|
- If the function was removed with no replacement, remove the call and any surrounding block
|
|
that only makes sense with it.
|
|
- When unsure, check `$TEMPLATE_DIR/scripts/` for the current equivalent.
|
|
|
|
Fix every dead reference before proceeding.
|
|
|
|
---
|
|
|
|
## Step 6 — Update README.md
|
|
|
|
Rewrite `README.md` to match the current state. Use the existing file as a base; update any stale
|
|
values (wrong image name, wrong org, wrong ports).
|
|
|
|
Read `SERVICE_PORT` from `.env.scripts` for the port value (app repos). Omit all `-p` and
|
|
`ports:` sections when `SERVICE_PORT` is empty or unset.
|
|
|
|
### App container layout (`casjaysdevdocker/{name}`)
|
|
|
|
```markdown
|
|
## 👋 Welcome to {name} 🚀
|
|
|
|
{name} README
|
|
|
|
|
|
## Install my system scripts
|
|
|
|
```shell
|
|
sudo bash -c "$(curl -q -LSsf "https://github.com/systemmgr/installer/raw/main/install.sh")"
|
|
sudo systemmgr --config && sudo systemmgr install scripts
|
|
```
|
|
|
|
## Automatic install/update
|
|
|
|
```shell
|
|
dockermgr update {name}
|
|
```
|
|
|
|
## Install and run container
|
|
|
|
```shell
|
|
dockerHome="/var/lib/srv/$USER/docker/casjaysdevdocker/{name}/{name}/latest/rootfs"
|
|
mkdir -p "/var/lib/srv/$USER/docker/{name}/rootfs"
|
|
git clone "https://github.com/dockermgr/{name}" "$HOME/.local/share/CasjaysDev/dockermgr/{name}"
|
|
cp -Rfva "$HOME/.local/share/CasjaysDev/dockermgr/{name}/rootfs/." "$dockerHome/"
|
|
docker run -d \
|
|
--restart always \
|
|
--privileged \
|
|
--name casjaysdevdocker-{name}-latest \
|
|
--hostname {name} \
|
|
-e TZ=${TIMEZONE:-America/New_York} \
|
|
-v "$dockerHome/data:/data:z" \
|
|
-v "$dockerHome/config:/config:z" \
|
|
-p {port}:{port} \
|
|
casjaysdevdocker/{name}:latest
|
|
```
|
|
|
|
## via docker-compose
|
|
|
|
```yaml
|
|
version: "2"
|
|
services:
|
|
ProjectName:
|
|
image: casjaysdevdocker/{name}
|
|
container_name: casjaysdevdocker-{name}
|
|
environment:
|
|
- TZ=America/New_York
|
|
- HOSTNAME={name}
|
|
volumes:
|
|
- "/var/lib/srv/$USER/docker/casjaysdevdocker/{name}/{name}/latest/rootfs/data:/data:z"
|
|
- "/var/lib/srv/$USER/docker/casjaysdevdocker/{name}/{name}/latest/rootfs/config:/config:z"
|
|
ports:
|
|
- {port}:{port}
|
|
restart: always
|
|
```
|
|
|
|
## Get source files
|
|
|
|
```shell
|
|
dockermgr download src casjaysdevdocker/{name}
|
|
```
|
|
|
|
OR
|
|
|
|
```shell
|
|
git clone "https://github.com/casjaysdevdocker/{name}" "$HOME/Projects/github/casjaysdevdocker/{name}"
|
|
```
|
|
|
|
## Build container
|
|
|
|
```shell
|
|
cd "$HOME/Projects/github/casjaysdevdocker/{name}"
|
|
buildx
|
|
```
|
|
|
|
## Authors
|
|
|
|
🤖 casjay: [Github](https://github.com/casjay) 🤖
|
|
⛵ casjaysdevdocker: [Github](https://github.com/casjaysdevdocker) [Docker](https://hub.docker.com/u/casjaysdevdocker) ⛵
|
|
```
|
|
|
|
### Base image layout (`dockersrc/{name}`)
|
|
|
|
```markdown
|
|
## 👋 Welcome to {name} 🚀
|
|
|
|
{name} README
|
|
|
|
|
|
## Install my system scripts
|
|
|
|
```shell
|
|
sudo bash -c "$(curl -q -LSsf "https://github.com/systemmgr/installer/raw/main/install.sh")"
|
|
sudo systemmgr --config && sudo systemmgr install scripts
|
|
```
|
|
|
|
## Automatic install/update
|
|
|
|
```shell
|
|
dockermgr update os {name}
|
|
```
|
|
|
|
## Install and run container
|
|
|
|
```shell
|
|
mkdir -p "/var/lib/srv/root/docker/casjaysdev/{name}/latest"
|
|
git clone "https://github.com/dockermgr/{name}" "$HOME/.local/share/CasjaysDev/dockermgr/{name}"
|
|
cp -Rfva "$HOME/.local/share/CasjaysDev/dockermgr/{name}/rootfs/." "/var/lib/srv/root/docker/casjaysdev/{name}/latest/"
|
|
docker run -d \
|
|
--restart always \
|
|
--privileged \
|
|
--name casjaysdev-{name}-latest \
|
|
--hostname {name} \
|
|
-e TZ=${TIMEZONE:-America/New_York} \
|
|
-v "/var/lib/srv/root/docker/casjaysdev/{name}/latest/data:/data:z" \
|
|
-v "/var/lib/srv/root/docker/casjaysdev/{name}/latest/config:/config:z" \
|
|
casjaysdev/{name}:latest
|
|
```
|
|
|
|
## via docker-compose
|
|
|
|
```yaml
|
|
version: "2"
|
|
services:
|
|
ProjectName:
|
|
image: casjaysdev/{name}
|
|
container_name: casjaysdev-{name}-latest
|
|
environment:
|
|
- TZ=America/New_York
|
|
- HOSTNAME={name}
|
|
volumes:
|
|
- "/var/lib/srv/root/docker/casjaysdev/{name}/latest/data:/data:z"
|
|
- "/var/lib/srv/root/docker/casjaysdev/{name}/latest/config:/config:z"
|
|
restart: always
|
|
```
|
|
|
|
## Get source files
|
|
|
|
```shell
|
|
dockermgr download src os {name}
|
|
```
|
|
|
|
## Build container
|
|
|
|
```shell
|
|
git clone "https://github.com/dockersrc/{name}" "$HOME/Projects/github/dockersrc/{name}"
|
|
cd "$HOME/Projects/github/dockersrc/{name}" && buildx all
|
|
```
|
|
|
|
## Authors
|
|
|
|
🤖 casjay: [Github](https://github.com/casjay) 🤖
|
|
⛵ casjaysdev: [Github](https://github.com/dockersrc) [Docker](https://hub.docker.com/u/casjaysdev) ⛵
|
|
```
|
|
|
|
---
|
|
|
|
## Step 7 — Clean up non-standard rootfs directories
|
|
|
|
The only valid directories at the `rootfs/` root level are `root/`, `tmp/`, and `usr/`. Any other
|
|
directory is a leftover from old patterns and must be cleaned up.
|
|
|
|
Find non-standard dirs:
|
|
|
|
```bash
|
|
find rootfs -maxdepth 1 -mindepth 1 -type d | grep -vE -- 'rootfs/(root|tmp|usr)$'
|
|
```
|
|
|
|
**If the directory contains only `.gitkeep` (empty placeholder):** remove it directly.
|
|
|
|
```bash
|
|
rm -rf "rootfs/{dir}"
|
|
```
|
|
|
|
**If the directory contains actual files:** migrate them to the correct location first, then remove.
|
|
|
|
Migration path 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}` |
|
|
|
|
Migration pattern (adapt `src_dir` and `dest_dir` per the table above):
|
|
|
|
```bash
|
|
src_dir="rootfs/etc"
|
|
dest_dir="rootfs/tmp/etc"
|
|
find "$src_dir" -type f | while read -r src; do
|
|
rel="${src#"$src_dir/"}"
|
|
dest="$dest_dir/$rel"
|
|
mkdir -p "$(dirname -- "$dest")"
|
|
mv "$src" "$dest"
|
|
done
|
|
rm -rf "$src_dir"
|
|
```
|
|
|
|
Also remove `rootfs/usr/local/share/template-files/` if it exists — the `DEFAULT_TEMPLATE_DIR`,
|
|
`DEFAULT_FILE_DIR`, `DEFAULT_DATA_DIR`, and `DEFAULT_CONF_DIR` variables were removed from the
|
|
template and this directory is no longer used at build time:
|
|
|
|
```bash
|
|
rm -rf rootfs/usr/local/share/template-files
|
|
```
|
|
|
|
---
|
|
|
|
## Step 8 — Verify
|
|
|
|
Run syntax checks on every script that was touched. Fix all failures before committing.
|
|
|
|
```bash
|
|
# bin scripts (check shebang to pick the right interpreter)
|
|
for f in rootfs/usr/local/bin/*; do
|
|
[ -f "$f" ] || continue
|
|
case "$(head -1 "$f")" in
|
|
*bash*) bash -n "$f" && printf 'OK: %s\n' "$f" || printf 'FAIL: %s\n' "$f" ;;
|
|
*sh*) sh -n "$f" && printf 'OK: %s\n' "$f" || printf 'FAIL: %s\n' "$f" ;;
|
|
esac
|
|
done
|
|
|
|
# entrypoint.sh and setup scripts are bash
|
|
bash -n rootfs/usr/local/etc/docker/functions/entrypoint.sh
|
|
|
|
for f in rootfs/root/docker/setup/0*.sh; do
|
|
[ -f "$f" ] || continue
|
|
bash -n "$f" && printf 'OK: %s\n' "$f" || printf 'FAIL: %s\n' "$f"
|
|
done
|
|
|
|
# init.d scripts are bash
|
|
for f in rootfs/usr/local/etc/docker/init.d/*.sh; do
|
|
[ -f "$f" ] || continue
|
|
bash -n "$f" && printf 'OK: %s\n' "$f" || printf 'FAIL: %s\n' "$f"
|
|
done
|
|
```
|
|
|
|
---
|
|
|
|
## Step 9 — Commit
|
|
|
|
Check what actually changed:
|
|
|
|
```bash
|
|
git status --porcelain
|
|
git diff --stat
|
|
```
|
|
|
|
Write `.git/COMMIT_MESS` listing only the files that actually changed per `git diff --stat`.
|
|
Subject line ≤64 chars. Body as `- path: change` bullets. Include only what changed in this run.
|
|
|
|
Example template (adjust bullets to match actual diff):
|
|
|
|
```
|
|
✨ Update to latest docker template revision ✨
|
|
|
|
- .env.scripts: synced vars to current template
|
|
- Dockerfile: removed stale ARG lines, updated IMAGE_NAME/REPO/LABEL
|
|
- rootfs/usr/local/bin/*: regenerated from current template via gen-dockerfile
|
|
- rootfs/usr/local/etc/docker/functions/entrypoint.sh: replaced from template
|
|
- rootfs/usr/local/etc/docker/init.d/*.sh: regenerated; app-specific values restored
|
|
- rootfs/root/docker/setup/: regenerated from current template
|
|
- README.md: updated to current standard layout
|
|
- rootfs/{old-dirs}: files migrated to rootfs/tmp/; stale directories removed
|
|
```
|
|
|
|
Then commit:
|
|
|
|
```bash
|
|
gitcommit --dir "$(git rev-parse --show-toplevel)" all
|
|
```
|