2476667510
The owner copies infra/pi/ to the Kvitt Pi and runs it there (D-100); nothing
on the Mac connects to the Pis. compose stack of SPEC §10.2 with images
${KVITT_REGISTRY}/kvitt-{server,cert-sync,backup}, Caddyfile §10.5.2 verbatim,
.env.example with the OQ-3 values as CHANGE_ME placeholders, install.sh,
deploy.sh (backup before every deploy), bootstrap.sh, backup-now.sh,
install-apk.sh. cert-sync image and sync.sh (§10.5.1, tar stream for both
authorized_keys variants); backup.sh uploads with rclone copy --immutable and
deletes local files once both are confirmed on Drive (D-002); both sidecars
schedule with supercronic because busybox crond runs no jobs as non-root;
backup runs as uid 10001. .gitea/workflows/build-images.yaml from the owner's
example (not yet run); infra/build-images.sh and infra/publish-apk.sh (R8
mapping kept, version per §10.6) on the Mac; README checklist and RESTORE.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
105 lines
4.5 KiB
YAML
105 lines
4.5 KiB
YAML
# Kvitt image build on Gitea Actions (SPEC §10.3, D-104). NOT YET RUN (written 2026-10-18 from the owner's working
|
|
# example workflow and the Gitea Actions documentation; the first run is an owner step, infra/README.md).
|
|
#
|
|
# Runner: act_runner with the label `host` on the owner's Raspberry Pi (Alpine-based host, docker builds on the
|
|
# Pi itself). Pushes three linux/arm64 images to the Gitea container registry of the same instance (gitea.lan,
|
|
# plain HTTP), each tagged with the version vMAJOR.MINOR.PATCH and `latest`, then pushes the git tag of that version.
|
|
# On the Kvitt Pi: /opt/kvitt/deploy.sh <version>.
|
|
#
|
|
# Secret: `kvitt_cicd`, a repository secret holding a Gitea access token (scopes write:package, and
|
|
# write:repository for the tag push) of the user that pushes (owner step, infra/README.md).
|
|
#
|
|
# RISK: the runner is a Raspberry Pi 3 with 1 GB RAM and the server image compiles about 232 Rust crates
|
|
# (aws-lc-sys's C code included). The build passes CARGO_BUILD_JOBS=1 to keep memory down; server/Dockerfile must
|
|
# declare `ARG CARGO_BUILD_JOBS` in its build stage for it to take effect (contract request in the M2c-pi report;
|
|
# until then buildx warns that the argument is unused and cargo uses every core). The Dockerfile already keeps
|
|
# the cargo registry and the target directory in BuildKit cache mounts, which persist in the reused builder
|
|
# `local-http-builder`, so later builds are incremental. First-build duration on the Pi: unknown.
|
|
# Fallback: infra/build-images.sh on the Mac.
|
|
name: Build Kvitt images
|
|
env:
|
|
MAJOR: 1
|
|
MINOR: 0
|
|
|
|
defaults:
|
|
run:
|
|
shell: sh
|
|
|
|
on:
|
|
push:
|
|
paths:
|
|
- "server/**"
|
|
- "infra/cert-sync/**"
|
|
- "infra/backup/**"
|
|
- ".gitea/workflows/**"
|
|
workflow_dispatch: {}
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: host
|
|
steps:
|
|
- name: Install Git and Docker CLI
|
|
run: apk add --no-cache git docker-cli docker-cli-buildx
|
|
- name: Log in to Gitea Container Registry
|
|
run: echo "${{ secrets.kvitt_cicd }}" | docker login gitea.lan -u ${{ github.actor }} --password-stdin
|
|
- name: Create Custom Buildx Builder for HTTP
|
|
run: |
|
|
# 1. Write a configuration rule forcing plain HTTP for the local registry
|
|
echo '[registry."gitea.lan"]' > buildkitd.toml
|
|
echo ' http = true' >> buildkitd.toml
|
|
# 2. Create the builder once and reuse it, so its BuildKit cache (cargo registry, target) survives runs
|
|
if docker buildx inspect local-http-builder >/dev/null 2>&1; then
|
|
docker buildx use local-http-builder
|
|
else
|
|
docker buildx create --use --name local-http-builder --config buildkitd.toml
|
|
fi
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
# Tells the action to use the local 'git' binary installed above
|
|
set-safe-directory: 'true'
|
|
fetch-depth: 0
|
|
- name: Determine Version
|
|
run: |
|
|
LATEST_TAG=$(git tag -l "v${{ env.MAJOR }}.${{ env.MINOR }}.*" | sort -V | tail -n 1)
|
|
if [ -z "$LATEST_TAG" ]; then
|
|
VERSION="v${{ env.MAJOR }}.${{ env.MINOR }}.0"
|
|
else
|
|
# Strip the 'v' and get the patch version
|
|
PATCH=$(echo "$LATEST_TAG" | sed 's/v//' | cut -d'.' -f3)
|
|
NEW_PATCH=$((PATCH + 1))
|
|
VERSION="v${{ env.MAJOR }}.${{ env.MINOR }}.$NEW_PATCH"
|
|
fi
|
|
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
|
|
- name: Build cert-sync image
|
|
run: |
|
|
docker buildx build \
|
|
--platform linux/arm64 \
|
|
-t gitea.lan/jacobh2/kvitt-cert-sync:${{ env.VERSION }} \
|
|
-t gitea.lan/jacobh2/kvitt-cert-sync:latest \
|
|
./infra/cert-sync \
|
|
--push
|
|
- name: Build backup image
|
|
run: |
|
|
docker buildx build \
|
|
--platform linux/arm64 \
|
|
-t gitea.lan/jacobh2/kvitt-backup:${{ env.VERSION }} \
|
|
-t gitea.lan/jacobh2/kvitt-backup:latest \
|
|
./infra/backup \
|
|
--push
|
|
- name: Build server image
|
|
run: |
|
|
# Context server/: server/Dockerfile copies the Cargo workspace from its own directory.
|
|
docker buildx build \
|
|
--platform linux/arm64 \
|
|
--build-arg CARGO_BUILD_JOBS=1 \
|
|
-f ./server/Dockerfile \
|
|
-t gitea.lan/jacobh2/kvitt-server:${{ env.VERSION }} \
|
|
-t gitea.lan/jacobh2/kvitt-server:latest \
|
|
./server \
|
|
--push
|
|
- name: Tag and Push Version
|
|
run: |
|
|
git tag "$VERSION"
|
|
git push origin "$VERSION"
|