84 lines
4.6 KiB
Markdown
84 lines
4.6 KiB
Markdown
# Build networking, cache and CI
|
|
|
|
### Build networking and cache
|
|
|
|
The runtime uses an official Python 3.14 Alpine 3.24 image pinned by digest,
|
|
locked Python dependencies, and `font-noto-cjk` for Chinese rendering. APK
|
|
repository signatures and offline wheel SHA256 checks remain enabled.
|
|
Production uses `scripts/build-verify.sh`; CI uses `scripts/ci-compose-verify.py`.
|
|
Both build the same Dockerfile with BuildKit and `docker compose build --pull`.
|
|
|
|
`ALPINE_MIRROR` accepts a mirror host (without scheme or path), defaulting to
|
|
`dl-cdn.alpinelinux.org`. For mainland-China builds:
|
|
|
|
```sh
|
|
. ./deploy/build-cn.env
|
|
./scripts/build-verify.sh
|
|
```
|
|
|
|
CI uses this profile; the Gitea `ALPINE_MIRROR` repository variable can override
|
|
it. APK upgrades available packages during a fresh dependency-layer build.
|
|
Use `docker compose build --pull --no-cache` to refresh OS packages explicitly.
|
|
|
|
Layer order is pinned base → APK/fonts → requirements → Python dependencies
|
|
→ application source → metadata. BuildKit caches pip downloads separately for
|
|
musl and architecture. Optional `build-cache/wheels/` must contain compatible
|
|
musllinux wheels and their SHA256 manifest; empty-cache builds work normally.
|
|
Do not reuse Debian/manylinux wheels on Alpine. Caches are disposable builder
|
|
resources and are not runtime mounts or dependencies.
|
|
|
|
### CI with a host Docker socket
|
|
|
|
Run `python scripts/ci-compose-verify.py` after loading the build mirror profile.
|
|
The script derives a temporary Compose document from production settings, with
|
|
an absolute client-side build context, a UUID project name, a unique CI image
|
|
tag, and project-scoped `data` / `config` named volumes. It removes production
|
|
bind mounts, the fixed container name, host ports, and the production `.env`
|
|
reference. A fresh test token, mock driver, and disabled device writes are
|
|
explicitly configured. Docker initializes empty named volumes from the image's
|
|
owned `/data` and `/config` directories; the service remains UID/GID 10333.
|
|
|
|
Build contexts are sent by the Docker client, so the job workspace can remain
|
|
inside the job container. Runtime storage is managed by the daemon; no matching
|
|
NAS host `/workspace` directory is needed. HTTP readiness and the unmodified
|
|
nine-endpoint smoke script run inside the service with `compose exec -T`.
|
|
Restart is followed by another readiness check and the same smoke test.
|
|
|
|
A `finally` block removes the test containers, network, volumes, and unique
|
|
image tag on success or failure. The workflow records the private temporary
|
|
Compose path in `GITHUB_ENV` and repeats cleanup in an `always()` step, covering
|
|
normal cancellation/interruption. Failed cleanup retains the manifest so the
|
|
fallback can retry. Abrupt host/daemon loss or a forcibly terminated entire job
|
|
can prevent both cleanup paths; no CI script can guarantee cleanup in that case.
|
|
No global prune or production resource removal is performed. Keep builder
|
|
caches: only the run-specific image tag is removed.
|
|
|
|
### CI Job pip indexes versus Docker build indexes
|
|
|
|
The Job bootstrap runs `python scripts/ci-install.py` before Ruff/mypy/tests.
|
|
It needs only the Python standard library, so it runs before PyYAML or tooling
|
|
is installed. `CI_PIP_INDEX_URL` and `CI_PIP_FALLBACK_INDEX_URL` are optional
|
|
Gitea repository variables. Defaults are the TUNA HTTPS PyPI simple endpoint
|
|
and official `https://pypi.org/simple`. Each is attempted separately; the
|
|
fallback repeats the unchanged editable `.[test]` installation, including
|
|
PEP 517 build isolation and `setuptools>=75`. No simultaneous extra index is
|
|
used, no build dependency is removed, and both failures fail CI.
|
|
|
|
Logs show inherited index/config/proxy hosts and the selected index host for
|
|
each attempt, with URL credentials and query strings removed. Bootstrap
|
|
disables inherited pip config files via `PIP_CONFIG_FILE=/dev/null`, explicitly
|
|
sets the selected index, and clears no-index/extra-index/find-links, insecure
|
|
trusted-host, and no-build-isolation environment settings. Constraints, TLS
|
|
certificate environment settings, and proxy settings remain in effect.
|
|
|
|
These `CI_PIP_*` settings apply only to the Job's pip install. They are not
|
|
passed into Docker build arguments or persisted into the production image.
|
|
The Dockerfile keeps its own cached/offline dependency installation and logs
|
|
the Docker pip index host for online installs. The Alpine mirror variable affects
|
|
APK only and are loaded later in the Docker verification step.
|
|
|
|
If dependency installation fails, the always() cleanup step still executes.
|
|
It skips the Python/PyYAML cleanup script when no CI Compose manifest exists,
|
|
as no Docker verification resources have been created at that point.
|
|
|