diff --git a/.gitea/workflows/docker.yaml b/.gitea/workflows/docker.yaml index 71ed7ea..ac88b51 100644 --- a/.gitea/workflows/docker.yaml +++ b/.gitea/workflows/docker.yaml @@ -1,6 +1,8 @@ name: gitea -on: push +on: + push: + workflow_dispatch: jobs: release-gitea: @@ -65,4 +67,3 @@ jobs: 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 }} - diff --git a/AI.md b/AI.md index a8bab1c..d3303e2 100644 --- a/AI.md +++ b/AI.md @@ -19,18 +19,18 @@ This file defines the standards that procedure enforces. # PART INDEX -| 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 | -| 9 | Examples from real repos | +| 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 | +| 9 | Examples from real repos | --- @@ -38,10 +38,10 @@ This file defines the standards that procedure enforces. ## Org mapping -| System | Org | Example | -|--------|-----|---------| -| GitHub (source) | `casjaysdevdocker` | `https://github.com/casjaysdevdocker/{name}` | -| Docker Hub (push) | `casjaysdevdocker` | `casjaysdevdocker/{name}` | +| 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 @@ -124,14 +124,14 @@ per the global project conventions — they are repo-owned and never touched by 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}` | +| 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 @@ -171,15 +171,15 @@ the templates change. The template name selects the base OS family; for an app repo the resulting pull URL is always the matching `casjaysdev/*` image: -| Template | Final stage | Init / PID 1 | App pulls FROM | -|----------|-------------|--------------|----------------| -| `alpine.template` | `scratch.template` | tini | `casjaysdev/alpine` | -| `debian.template` | `scratch.template` | tini | `casjaysdev/debian` | -| `ubuntu.template` | `scratch.template` | tini | `casjaysdev/ubuntu` | -| `rhel.template` | `scratch.template` | tini | `casjaysdev/almalinux` | -| `archlinux.template` | `scratch.template` | tini | `casjaysdev/archlinux` (multi-arch manifest) | -| `web.template` | `systemd.template` | `/sbin/init` | `casjaysdev/web` | -| `xorg.template` | `systemd.template` | `/sbin/init` | `casjaysdev/xorg` | +| Template | Final stage | Init / PID 1 | App pulls FROM | +| -------------------- | ------------------ | ------------ | -------------------------------------------- | +| `alpine.template` | `scratch.template` | tini | `casjaysdev/alpine` | +| `debian.template` | `scratch.template` | tini | `casjaysdev/debian` | +| `ubuntu.template` | `scratch.template` | tini | `casjaysdev/ubuntu` | +| `rhel.template` | `scratch.template` | tini | `casjaysdev/almalinux` | +| `archlinux.template` | `scratch.template` | tini | `casjaysdev/archlinux` (multi-arch manifest) | +| `web.template` | `systemd.template` | `/sbin/init` | `casjaysdev/web` | +| `xorg.template` | `systemd.template` | `/sbin/init` | `casjaysdev/xorg` | Default template for app repos is `alpine` unless the application needs systemd, a GUI stack, or a distro-specific package. @@ -187,10 +187,12 @@ stack, or a distro-specific package. ## Final-stage templates `scratch.template` — all non-GUI templates. + - `ENTRYPOINT [ "tini", "-p", "SIGTERM","--", "/usr/local/bin/entrypoint.sh" ]` - `STOPSIGNAL SIGRTMIN+3` `systemd.template` — `web` and `xorg` (systemd is PID 1; tini is redundant). + - `ENTRYPOINT [ "/sbin/init" ]` - `STOPSIGNAL SIGRTMIN+3` - No `tini_provider` stage, no `COPY --from=tini_provider` line. @@ -225,14 +227,15 @@ generated `Dockerfile`. Resolved values for a `casjaysdevdocker` repo pushing to Docker Hub: -| Label | Value | -|-------|-------| -| `url` | `https://hub.docker.com/r/casjaysdevdocker/{name}` — browsable Hub page; `gen-dockerfile` derives it from the registry host (`docker.io` → `hub.docker.com/r/`) | -| `source` | `https://github.com/casjaysdevdocker/{name}` | -| `documentation` | `https://github.com/casjaysdevdocker/{name}` | +| Label | Value | +| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `url` | `https://hub.docker.com/r/casjaysdevdocker/{name}` — browsable Hub page; `gen-dockerfile` derives it from the registry host (`docker.io` → `hub.docker.com/r/`) | +| `source` | `https://github.com/casjaysdevdocker/{name}` | +| `documentation` | `https://github.com/casjaysdevdocker/{name}` | Older app repos may still carry `url="https://docker.io/casjaysdevdocker/{name}"` — that is the stale form; regeneration corrects it. Removed labels (never re-add): + - `org.opencontainers.image.base.name` — belongs on the base image, not this image - `org.opencontainers.image.schema-version` — non-spec; redundant with `version` - Any duplicate `authors` or `source` entries @@ -307,22 +310,22 @@ variable overrides. Usage: gen-dockerfile [options] [dir] [template] [repo-name] [git-repo-url] ``` -| Flag | Meaning | -|------|---------| -| `--update` | Rewrite `.env.scripts` (add/drop vars against the current template) and update ARG/LABEL lines in the `Dockerfile`. Touches no other file. | -| `--nogit` | Do not init or commit a git repo — required inside an existing repo. | -| `--dir PATH` | Operate on / write output to PATH instead of `$PWD`. | -| `--template NAME` | Template to use (`alpine`, `debian`, `ubuntu`, `rhel`, `archlinux`, `scratch`, `web`, `xorg`). Defaults to `alpine`. | -| `--repo NAME` | Registry repo name (image basename). Defaults to the directory name. | -| `--org NAME` | Registry owner / GitHub org (`--user` is an alias). Prefix `git:` or `reg:` to scope to one system; bare value sets both. For app repos both are `casjaysdevdocker`. | -| `--registry URL` | Registry provider URL (e.g. `https://docker.io`). | -| `--tag VERSION` | Image version tag (default `latest`). | -| `--add-tags TAGS` | Comma-separated additional tags (`USE_DATE` = auto date tag). | -| `--distro-name IMG` | Base image pull URL (overrides `ENV_PULL_URL`). | -| `--distro-version T` | Base image tag (overrides `ENV_DISTRO_TAG`). | -| `--startup FILE` | Generate an init.d service script at `rootfs/usr/local/etc/docker/init.d/FILE` via `gen-script other/start-service`. | -| `--dockerfile` | Regenerate the Dockerfile only. | -| `--force` | Overwrite existing files without prompting. | +| Flag | Meaning | +| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--update` | Rewrite `.env.scripts` (add/drop vars against the current template) and update ARG/LABEL lines in the `Dockerfile`. Touches no other file. | +| `--nogit` | Do not init or commit a git repo — required inside an existing repo. | +| `--dir PATH` | Operate on / write output to PATH instead of `$PWD`. | +| `--template NAME` | Template to use (`alpine`, `debian`, `ubuntu`, `rhel`, `archlinux`, `scratch`, `web`, `xorg`). Defaults to `alpine`. | +| `--repo NAME` | Registry repo name (image basename). Defaults to the directory name. | +| `--org NAME` | Registry owner / GitHub org (`--user` is an alias). Prefix `git:` or `reg:` to scope to one system; bare value sets both. For app repos both are `casjaysdevdocker`. | +| `--registry URL` | Registry provider URL (e.g. `https://docker.io`). | +| `--tag VERSION` | Image version tag (default `latest`). | +| `--add-tags TAGS` | Comma-separated additional tags (`USE_DATE` = auto date tag). | +| `--distro-name IMG` | Base image pull URL (overrides `ENV_PULL_URL`). | +| `--distro-version T` | Base image tag (overrides `ENV_DISTRO_TAG`). | +| `--startup FILE` | Generate an init.d service script at `rootfs/usr/local/etc/docker/init.d/FILE` via `gen-script other/start-service`. | +| `--dockerfile` | Regenerate the Dockerfile only. | +| `--force` | Overwrite existing files without prompting. | Resolution order when a value is not given by a flag: flags → git remote → project dirs → defaults. @@ -336,14 +339,14 @@ the existing `Dockerfile` (PART 7). App repos have no versioned `build.{ver}.yml Usage: gen-script [options] [template] [filename] ``` -| Flag / env var | Meaning | -|----------------|---------| -| `--dir PATH` | Write the generated file to `PATH/filename`. | -| `-n` / `--name VALUE` | Service name substituted into the template — fills `REPLACE_SERVICE_NAME` in `other/start-service`, pre-populating `SERVICE_NAME=` without a sed step. | -| `GEN_SCRIPT_OVERWRITE="Y"` | Overwrite the output without prompting (default `"A"` = ask). Required when the target exists, even with `GEN_SCRIPT_EDITFILE="N"`. | -| `GEN_SCRIPT_EDITFILE="N"` | Suppress the interactive editor after generation. `-e`/`--no` sets BOTH this AND `GEN_SCRIPT_OVERWRITE="Y"`; the env var alone does not. | -| `other/start-service` | Template path — positional arg 1, slash-joined words, matching the `@@Template` header. | -| `filename` | Output basename — positional arg 2, combined with `--dir`. | +| Flag / env var | Meaning | +| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `--dir PATH` | Write the generated file to `PATH/filename`. | +| `-n` / `--name VALUE` | Service name substituted into the template — fills `REPLACE_SERVICE_NAME` in `other/start-service`, pre-populating `SERVICE_NAME=` without a sed step. | +| `GEN_SCRIPT_OVERWRITE="Y"` | Overwrite the output without prompting (default `"A"` = ask). Required when the target exists, even with `GEN_SCRIPT_EDITFILE="N"`. | +| `GEN_SCRIPT_EDITFILE="N"` | Suppress the interactive editor after generation. `-e`/`--no` sets BOTH this AND `GEN_SCRIPT_OVERWRITE="Y"`; the env var alone does not. | +| `other/start-service` | Template path — positional arg 1, slash-joined words, matching the `@@Template` header. | +| `filename` | Output basename — positional arg 2, combined with `--dir`. | Other flags: `-k`/`--keep` (never overwrite), `--replace` (new header replaces old), `-d`/`--desc` (header description), `-p`/`--prev` (copy header metadata from a file). @@ -357,39 +360,39 @@ repos carry exactly one. It is a pure `KEY="value"` file — no logic. ## Variables -| Variable | Purpose | -|----------|---------| -| `ENV_DOCKERFILE` | Dockerfile to build (`Dockerfile`) | -| `ENV_REGISTRY_REPO` | Image name in the registry (`{name}`) | -| `ENV_REGISTRY_ORG` | Registry namespace — `casjaysdevdocker` for app repos | -| `ENV_REGISTRY_URL` | Registry base URL (`https://docker.io`) — pull/push host, never a label URL | -| `ENV_REGISTRY_PUSH` | Full push path `org/repo` (`casjaysdevdocker/{name}`) | -| `ENV_ADD_IMAGE_PUSH` | Extra push destinations | -| `ENV_GIT_REPO_URL` | Full Git repo URL — `https://github.com/casjaysdevdocker/{name}`; feeds the `source`/`documentation` labels, so a wrong value here regresses labels on regeneration | -| `ENV_USE_TEMPLATE` | Template name (`alpine`, `debian`, …) — the authoritative record of which base family the app builds on | -| `ENV_PULL_URL` | Base image to pull FROM (`casjaysdev/`) | -| `ENV_DISTRO_TAG` | Tag for the pull image (`latest`) | -| `ENV_IMAGE_TAG` | Default image tag (`latest`) | -| `ENV_ADD_TAGS` | Additional comma-separated tags; `USE_DATE` auto-generates a date tag | -| `ENV_PACKAGES` | Space-separated package list | -| `ENV_VENDOR` / `ENV_AUTHOR` / `ENV_MAINTAINER` | Label metadata | -| `SERVICE_PORT` | Primary exposed port — apps normally set this | -| `EXPOSE_PORTS` | Additional exposed ports | -| `PHP_VERSION` / `NODE_VERSION` / `NODE_MANAGER` | Runtime versions (`system` default) | -| `WWW_ROOT_DIR` | Web root (`/usr/local/share/httpd/default`) | -| `DOCKER_ENTYPOINT_PORTS_WEB` / `DOCKER_ENTYPOINT_PORTS_SRV` | Ports passed to the entrypoint | -| `DOCKER_ENTYPOINT_HEALTH_APPS` / `DOCKER_ENTYPOINT_HEALTH_ENDPOINTS` | Healthcheck targets | +| Variable | Purpose | +| -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ENV_DOCKERFILE` | Dockerfile to build (`Dockerfile`) | +| `ENV_REGISTRY_REPO` | Image name in the registry (`{name}`) | +| `ENV_REGISTRY_ORG` | Registry namespace — `casjaysdevdocker` for app repos | +| `ENV_REGISTRY_URL` | Registry base URL (`https://docker.io`) — pull/push host, never a label URL | +| `ENV_REGISTRY_PUSH` | Full push path `org/repo` (`casjaysdevdocker/{name}`) | +| `ENV_ADD_IMAGE_PUSH` | Extra push destinations | +| `ENV_GIT_REPO_URL` | Full Git repo URL — `https://github.com/casjaysdevdocker/{name}`; feeds the `source`/`documentation` labels, so a wrong value here regresses labels on regeneration | +| `ENV_USE_TEMPLATE` | Template name (`alpine`, `debian`, …) — the authoritative record of which base family the app builds on | +| `ENV_PULL_URL` | Base image to pull FROM (`casjaysdev/`) | +| `ENV_DISTRO_TAG` | Tag for the pull image (`latest`) | +| `ENV_IMAGE_TAG` | Default image tag (`latest`) | +| `ENV_ADD_TAGS` | Additional comma-separated tags; `USE_DATE` auto-generates a date tag | +| `ENV_PACKAGES` | Space-separated package list | +| `ENV_VENDOR` / `ENV_AUTHOR` / `ENV_MAINTAINER` | Label metadata | +| `SERVICE_PORT` | Primary exposed port — apps normally set this | +| `EXPOSE_PORTS` | Additional exposed ports | +| `PHP_VERSION` / `NODE_VERSION` / `NODE_MANAGER` | Runtime versions (`system` default) | +| `WWW_ROOT_DIR` | Web root (`/usr/local/share/httpd/default`) | +| `DOCKER_ENTYPOINT_PORTS_WEB` / `DOCKER_ENTYPOINT_PORTS_SRV` | Ports passed to the entrypoint | +| `DOCKER_ENTYPOINT_HEALTH_APPS` / `DOCKER_ENTYPOINT_HEALTH_ENDPOINTS` | Healthcheck targets | ## Legacy variable auto-migration `gen-dockerfile` calls `__migrate_env_script` on every run, renaming old variables: -| Old name | Current name | -|----------|-------------| +| 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` | +| `ENV_HUB_BASE` | `ENV_REGISTRY_URL` | +| `ENV_ORG_NAME` | `ENV_REGISTRY_ORG` | Never use the old names in new files. Retired variables that must not reappear anywhere: `DEFAULT_TEMPLATE_DIR`, `DEFAULT_FILE_DIR`, `DEFAULT_DATA_DIR`, `DEFAULT_CONF_DIR`. @@ -402,16 +405,16 @@ Never use the old names in new files. Retired variables that must not reappear a Run in order inside the build stage: -| Script | Role | -|--------|------| -| `00-init.sh` | Initialize base directory structure and environment | -| `01-system.sh` | Repos, locales, timezone, system settings | -| `02-packages.sh` | App-specific packages, package managers, language runtimes | -| `03-files.sh` | Install staged files (`rootfs/tmp/etc/*` → `/etc/*`), permissions, symlinks | -| `04-users.sh` | Create service users/groups | -| `05-custom.sh` | Application install logic — the heart of an app repo | -| `06-post.sh` | Post-install configuration | -| `07-cleanup.sh` | Remove build deps, caches, temp files | +| Script | Role | +| ---------------- | --------------------------------------------------------------------------- | +| `00-init.sh` | Initialize base directory structure and environment | +| `01-system.sh` | Repos, locales, timezone, system settings | +| `02-packages.sh` | App-specific packages, package managers, language runtimes | +| `03-files.sh` | Install staged files (`rootfs/tmp/etc/*` → `/etc/*`), permissions, symlinks | +| `04-users.sh` | Create service users/groups | +| `05-custom.sh` | Application install logic — the heart of an app repo | +| `06-post.sh` | Post-install configuration | +| `07-cleanup.sh` | Remove build deps, caches, temp files | **`05-custom.sh` ownership:** the upstream template ships an empty stub. An app repo's `05-custom.sh` carries the application install (download/build, users, default config) — @@ -490,19 +493,19 @@ USER_FILE_PREFIX="/config/secure/auth/user" The `start-service` template generates all outer hooks fully implemented — customise via the matching `*_local()` stub, which each outer hook calls automatically if defined: -| Outer hook (do not redefine) | Customise via | -|------------------------------|---------------| -| `__run_precopy` | `__run_precopy_local` | -| `__execute_prerun` | `__execute_prerun_local` | -| `__run_pre_execute_checks` | `__run_pre_execute_checks_local` | -| `__update_conf_files` | `__update_conf_files_local` | -| `__pre_execute` | `__pre_execute_local` | -| `__post_execute` | `__post_execute_local` | -| `__pre_message` | `__pre_message_local` | -| `__update_ssl_conf` | `__update_ssl_conf_local` | -| `__create_service_env` | — | -| `__run_start_script` | — | -| `__run_secure_function` | — | +| Outer hook (do not redefine) | Customise via | +| ---------------------------- | -------------------------------- | +| `__run_precopy` | `__run_precopy_local` | +| `__execute_prerun` | `__execute_prerun_local` | +| `__run_pre_execute_checks` | `__run_pre_execute_checks_local` | +| `__update_conf_files` | `__update_conf_files_local` | +| `__pre_execute` | `__pre_execute_local` | +| `__post_execute` | `__post_execute_local` | +| `__pre_message` | `__pre_message_local` | +| `__update_ssl_conf` | `__update_ssl_conf_local` | +| `__create_service_env` | — | +| `__run_start_script` | — | +| `__run_secure_function` | — | ## PID sentinel guard @@ -744,8 +747,8 @@ ACT_VERSIONS="$(curl -q --connect-timeout 30 --max-time 45 -LSsf \ # Fall back to pinned version if API is unreachable [ -z "$ACT_VERSIONS" ] && ACT_VERSIONS="$ACT_RUNNER_FALLBACK_VERSION" if [ -z "$GITEA_VERSION" ] || [ "$GITEA_VERSION" = "latest" ]; then - _latest_url="$(curl -4sfL -o /dev/null -w '%{url_effective}' https://github.com/go-gitea/gitea/releases/latest 2>/dev/null)" - GITEA_VERSION="$(printf '%s\n' "$_latest_url" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')" + _latest_url="$(curl -4sfL -o /dev/null -w '%{url_effective}' https://github.com/go-gitea/gitea/releases/latest 2>/dev/null)" + GITEA_VERSION="$(printf '%s\n' "$_latest_url" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')" fi GITEA_URL="https://github.com/go-gitea/gitea/releases/download/v${GITEA_VERSION}/gitea-${GITEA_VERSION}-linux-${ARCH}" ``` @@ -814,11 +817,11 @@ the template function body: ```bash # function to run before executing __pre_execute() { - local exitCode=0 - ... - # allow custom functions - if builtin type -t __pre_execute_local | grep -q 'function'; then __pre_execute_local; fi - return $exitCode + local exitCode=0 + ... + # allow custom functions + if builtin type -t __pre_execute_local | grep -q 'function'; then __pre_execute_local; fi + return $exitCode } ``` diff --git a/README.md b/README.md index a874f10..b94d1ab 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ docker run -d \ --privileged \ --restart always \ --tty \ - --cgroupns private \ + --cgroupns=private \ --hostname git.example.com \ --domainname example.com \ --network bridge \ @@ -55,11 +55,12 @@ services: tty: true restart: always logging: *default-logging - cgroupns_mode: private + cgroup: private cap_add: - CHOWN - SYS_TIME - SYS_ADMIN + - CAP_MKNOD environment: TZ: ${TZ:-America/New_York} CONTAINER_NAME: casjaysdevdocker-forgejo-latest @@ -86,87 +87,87 @@ networks: **General** -| Variable | Default | Description | -|----------|---------|-------------| -| `TZ` | `America/New_York` | Timezone | -| `DEBUGGER` | _(empty)_ | Set to `on` to enable shell-level debug tracing | +| Variable | Default | Description | +| ---------- | ------------------ | ----------------------------------------------- | +| `TZ` | `America/New_York` | Timezone | +| `DEBUGGER` | _(empty)_ | Set to `on` to enable shell-level debug tracing | **Server / domain** -| Variable | Default | Description | -|----------|---------|-------------| -| `FORGEJO_SERVER` | `hostname -f` | Public FQDN — sets ROOT\_URL, DOMAIN, SSH\_DOMAIN, and all email addresses. **Always set this in production.** | -| `FORGEJO_HOSTNAME` | _(empty)_ | Alias for `FORGEJO_SERVER` | -| `FULL_DOMAIN_NAME` | _(empty)_ | Fallback FQDN used when neither `FORGEJO_SERVER` nor `FORGEJO_HOSTNAME` is set | -| `DOMAIN` | _(empty)_ | Overrides the domain used in email addresses (takes precedence over `FORGEJO_SERVER`) | -| `FORGEJO_PROTO` | `http` | Protocol used in ROOT\_URL (`http` or `https`) | -| `FORGEJO_PORT` | `80` | Internal port Forgejo listens on | -| `FORGEJO_NAME` | `SelfHosted GIT Server` | Site title shown in the UI | -| `FORGEJO_TZ` | `$TZ` | Override timezone for Forgejo specifically | -| `FORGEJO_WORK_DIR` | `/data/forgejo` | Override Forgejo's work path | +| Variable | Default | Description | +| ------------------ | ----------------------- | -------------------------------------------------------------------------------------------------------------- | +| `FORGEJO_SERVER` | `hostname -f` | Public FQDN — sets ROOT\_URL, DOMAIN, SSH\_DOMAIN, and all email addresses. **Always set this in production.** | +| `FORGEJO_HOSTNAME` | _(empty)_ | Alias for `FORGEJO_SERVER` | +| `FULL_DOMAIN_NAME` | _(empty)_ | Fallback FQDN used when neither `FORGEJO_SERVER` nor `FORGEJO_HOSTNAME` is set | +| `DOMAIN` | _(empty)_ | Overrides the domain used in email addresses (takes precedence over `FORGEJO_SERVER`) | +| `FORGEJO_PROTO` | `http` | Protocol used in ROOT\_URL (`http` or `https`) | +| `FORGEJO_PORT` | `80` | Internal port Forgejo listens on | +| `FORGEJO_NAME` | `SelfHosted GIT Server` | Site title shown in the UI | +| `FORGEJO_TZ` | `$TZ` | Override timezone for Forgejo specifically | +| `FORGEJO_WORK_DIR` | `/data/forgejo` | Override Forgejo's work path | **Users** -| Variable | Default | Description | -|----------|---------|-------------| +| Variable | Default | Description | +| ------------------------ | --------- | ----------------------------------------------------- | | `FORGEJO_ROOT_USER_NAME` | _(empty)_ | Initial admin account username (created on first run) | -| `FORGEJO_ROOT_PASS_WORD` | _(empty)_ | Initial admin account password | -| `FORGEJO_USER_NAME` | _(empty)_ | Initial normal user username | -| `FORGEJO_USER_PASS_WORD` | _(empty)_ | Initial normal user password | +| `FORGEJO_ROOT_PASS_WORD` | _(empty)_ | Initial admin account password | +| `FORGEJO_USER_NAME` | _(empty)_ | Initial normal user username | +| `FORGEJO_USER_PASS_WORD` | _(empty)_ | Initial normal user password | **Mail** -| Variable | Default | Description | -|----------|---------|-------------| -| `FORGEJO_ADMIN` | `administrator@` | Admin contact / mailer FROM address | -| `FORGEJO_EMAIL_RELAY` | `172.17.0.1` | SMTP relay host | -| `FORGEJO_EMAIL_CONFIRM` | `false` | Set to `yes` to require email confirmation and enable the mailer | +| Variable | Default | Description | +| ----------------------- | -------------------------------- | ---------------------------------------------------------------- | +| `FORGEJO_ADMIN` | `administrator@` | Admin contact / mailer FROM address | +| `FORGEJO_EMAIL_RELAY` | `172.17.0.1` | SMTP relay host | +| `FORGEJO_EMAIL_CONFIRM` | `false` | Set to `yes` to require email confirmation and enable the mailer | **Database** -| Variable | Default | Description | -|----------|---------|-------------| -| `FORGEJO_SQL_TYPE` | `sqlite3` | Database type (`sqlite3`, `mysql`, `postgres`) | -| `FORGEJO_SQL_HOST` | `localhost` | Database host (external DB only) | -| `FORGEJO_SQL_DB_HOST` | `$FORGEJO_SQL_HOST` | Alternate database host variable | -| `FORGEJO_SQL_USER` | _(empty)_ | Database user (external DB only) | -| `FORGEJO_SQL_PASS` | _(empty)_ | Database password (external DB only) | -| `FORGEJO_SQL_NAME` | _(empty)_ | Database name (external DB only) | +| Variable | Default | Description | +| --------------------- | --------------------- | ---------------------------------------------------------------------------------------------------- | +| `FORGEJO_SQL_TYPE` | `sqlite3` | Database type (`sqlite3`, `mysql`, `postgres`) | +| `FORGEJO_SQL_HOST` | `localhost` | Database host (external DB only) | +| `FORGEJO_SQL_DB_HOST` | `$FORGEJO_SQL_HOST` | Alternate database host variable | +| `FORGEJO_SQL_USER` | _(empty)_ | Database user (external DB only) | +| `FORGEJO_SQL_PASS` | _(empty)_ | Database password (external DB only) | +| `FORGEJO_SQL_NAME` | _(empty)_ | Database name (external DB only) | | `DATABASE_DIR_SQLITE` | `$DATA_DIR/db/sqlite` | Override the SQLite database directory (mount a separate volume here to keep the DB outside `/data`) | **act\_runner** -| Variable | Default | Description | -|----------|---------|-------------| -| `RUNNERS_START` | `5` | Number of act\_runner instances to register | -| `RUNNER_CACHE_PORT` | `44015` | Port for the act\_runner cache server | -| `RUNNER_IP_ADDRESS` | container IP | IP address act\_runner registers with Forgejo | -| `RUNNER_DEFAULT_HOME` | `/config/act_runner/forgejo` | Directory where runner registration state is stored | -| `RUNNER_CONFIG_NAME` | `act_runner.yaml` | Runner config filename inside `RUNNER_DEFAULT_HOME` | -| `ACT_RUNNER_FALLBACK_VERSION` | `v13.1.0` | Pinned act\_runner version used if code.forgejo.org is unreachable during build | +| Variable | Default | Description | +| ----------------------------- | ---------------------------- | ------------------------------------------------------------------------------- | +| `RUNNERS_START` | `5` | Number of act\_runner instances to register | +| `RUNNER_CACHE_PORT` | `44015` | Port for the act\_runner cache server | +| `RUNNER_IP_ADDRESS` | container IP | IP address act\_runner registers with Forgejo | +| `RUNNER_DEFAULT_HOME` | `/config/act_runner/forgejo` | Directory where runner registration state is stored | +| `RUNNER_CONFIG_NAME` | `act_runner.yaml` | Runner config filename inside `RUNNER_DEFAULT_HOME` | +| `ACT_RUNNER_FALLBACK_VERSION` | `v13.1.0` | Pinned act\_runner version used if code.forgejo.org is unreachable during build | **Runner labels** are set automatically based on the host architecture. All jobs run inside Docker containers — no bare-metal execution. -| Host arch | Labels registered | -|-----------|------------------| -| `x86_64` | `amd64:docker://ubuntu:latest`, `linux:docker://ubuntu:latest`, `linux/amd64:docker://ubuntu:latest`, + language images | +| Host arch | Labels registered | +| --------- | ----------------------------------------------------------------------------------------------------------------------- | +| `x86_64` | `amd64:docker://ubuntu:latest`, `linux:docker://ubuntu:latest`, `linux/amd64:docker://ubuntu:latest`, + language images | | `aarch64` | `arm64:docker://ubuntu:latest`, `linux:docker://ubuntu:latest`, `linux/arm64:docker://ubuntu:latest`, + language images | Language image labels available on both architectures: `node` (14/16/18/20/22/latest), `perl`, `ruby`, `python`/`python3`, `php`/`php7`/`php8`, `alpine`, `debian`, `ubuntu`, `almalinux`/`rhel`/`redhat`, `ubuntu-latest`. ### Volumes -| Path | Purpose | -|------|---------| -| `/data` | Repositories, SQLite database, LFS objects, attachments, indexes | +| Path | Purpose | +| --------- | ---------------------------------------------------------------------------------- | +| `/data` | Repositories, SQLite database, LFS objects, attachments, indexes | | `/config` | `app.ini`, SSH host keys, act\_runner config — persisted across container restarts | ### Ports -| Port | Protocol | Purpose | -|------|----------|---------| -| `80` | TCP | Forgejo web UI and API | -| `22` (internal) / `7833` (default external) | TCP | Git over SSH — host port 22 is typically taken by sshd; map container port 22 to an available host port and set `SSH_PORT` to match | +| Port | Protocol | Purpose | +| ------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| `80` | TCP | Forgejo web UI and API | +| `22` (internal) / `7833` (default external) | TCP | Git over SSH — host port 22 is typically taken by sshd; map container port 22 to an available host port and set `SSH_PORT` to match | ### Notes @@ -217,6 +218,7 @@ act_runner register \ ``` Label format: `name:type:image` — all jobs run inside Docker containers, never directly on the host. + - `arm64:docker://ubuntu:latest` — dispatched to this runner, job runs in a native arm64 Ubuntu container - `linux/arm64:docker://ubuntu:latest` — OCI-style label for the same runner - Docker must be installed and running on the host machine diff --git a/rootfs/tmp/etc/docker/daemon.json b/rootfs/tmp/etc/docker/daemon.json index b89966b..519c7ed 100644 --- a/rootfs/tmp/etc/docker/daemon.json +++ b/rootfs/tmp/etc/docker/daemon.json @@ -5,11 +5,14 @@ "experimental": true, "pidfile": "/tmp/docker.pid", "cgroup-parent": "/docker", - "storage-driver": "fuse-overlayfs", + "storage-driver": "vfs", + "insecure-registries": ["localhost"], + "features": { + "containerd-snapshotter": false + }, "default-address-pools": [ - {"base": "172.17.0.0/12", "size": 24}, - {"base": "192.168.0.0/16", "size": 24}, - {"base": "10.0.0.0/8", "size": 24} - ], - "insecure-registries": ["localhost"] + { "base": "172.17.0.0/12", "size": 24 }, + { "base": "192.168.0.0/16", "size": 24 }, + { "base": "10.0.0.0/8", "size": 24 } + ] } diff --git a/rootfs/tmp/etc/forgejo/app.ini b/rootfs/tmp/etc/forgejo/app.ini index 65e1655..b0e46c4 100644 --- a/rootfs/tmp/etc/forgejo/app.ini +++ b/rootfs/tmp/etc/forgejo/app.ini @@ -222,7 +222,7 @@ DEFAULT_MAX_BLOB_SIZE = 10485760 SKIP_TLS_VERIFY = true ALLOWED_DOMAINS = BLOCKED_DOMAINS = -ALLOW_LOCALNETWORKS = false +ALLOW_LOCALNETWORKS = true ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; [git.config] http.sslVerify = false @@ -380,4 +380,4 @@ ENABLED = false RUN_AT_START = false ENABLE_SUCCESS_NOTICE = true SCHEDULE = @every 168h -HTTP_ENDPOINT = https://dl.gitea.com/gitea/version.json +DOMAIN_ENDPOINT = release.forgejo.org