normalize image naming: fhirworx/<svc>:<sha> everywhere, registry prefix only in push commands

This commit is contained in:
kert
2026-02-28 23:36:48 -05:00
parent 9776915b50
commit 4664c7fe14
7 changed files with 113 additions and 52 deletions

24
.dockerignore Normal file
View File

@@ -0,0 +1,24 @@
# Docs Dockerfile uses repo root context — exclude heavy/sensitive dirs
zotero/
notebooks/
.git/
.env
*.duckdb
*.duckdb.wal
__pycache__/
dist/
*.egg-info/
logs/
tuva/
dev/
tests/
grafana/
prometheus/
loki/
trino/
traefik/
nginx/
gitea/
css/
.woodpecker/
.claude/

View File

@@ -3,6 +3,14 @@
# builds, scans, and pushes container images, then updates the # builds, scans, and pushes container images, then updates the
# host working copy and restarts all changed services. # host working copy and restarts all changed services.
# Only runs on pushes to main (i.e. after PR merge). # Only runs on pushes to main (i.e. after PR merge).
#
# Image naming:
# fhirworx/<service>:<short-sha> (local tag, used by compose)
# localhost:3000/fhirworx/<service>:* (registry push only)
#
# The deploy step writes COMMIT_SHA=<short-sha> into .env so
# compose.yml resolves fhirworx/<svc>:${COMMIT_SHA:-latest} to
# the exact image just built.
when: when:
- event: push - event: push
@@ -13,7 +21,6 @@ steps:
- name: build-package - name: build-package
image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim image: ghcr.io/astral-sh/uv:python3.13-bookworm-slim
commands: commands:
# Stamp a unique version using Woodpecker pipeline number
- BASE=$(grep '^version' pyproject.toml | head -1 | sed 's/.*"\(.*\)"/\1/') - BASE=$(grep '^version' pyproject.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
- uv version "$BASE.dev${CI_PIPELINE_NUMBER}" --no-sync - uv version "$BASE.dev${CI_PIPELINE_NUMBER}" --no-sync
- uv build --out-dir dist/ - uv build --out-dir dist/
@@ -37,8 +44,9 @@ steps:
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- docker build -t localhost:3000/homelab/notebooks:${CI_COMMIT_SHA:0:8} ./notebooks - TAG=${CI_COMMIT_SHA:0:8}
- docker tag localhost:3000/homelab/notebooks:${CI_COMMIT_SHA:0:8} localhost:3000/homelab/notebooks:latest - docker build -t fhirworx/notebooks:$TAG ./notebooks
- docker tag fhirworx/notebooks:$TAG fhirworx/notebooks:latest
when: when:
- path: "notebooks/**" - path: "notebooks/**"
@@ -47,8 +55,9 @@ steps:
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- trivy image --severity HIGH,CRITICAL --exit-code 0 --format table localhost:3000/homelab/notebooks:${CI_COMMIT_SHA:0:8} - TAG=${CI_COMMIT_SHA:0:8}
- trivy image --severity HIGH,CRITICAL --format json -o notebooks-scan.json localhost:3000/homelab/notebooks:${CI_COMMIT_SHA:0:8} - trivy image --severity HIGH,CRITICAL --exit-code 0 --format table fhirworx/notebooks:$TAG
- trivy image --severity HIGH,CRITICAL --format json -o notebooks-scan.json fhirworx/notebooks:$TAG
depends_on: depends_on:
- build-notebooks - build-notebooks
when: when:
@@ -64,9 +73,12 @@ steps:
REGISTRY_PASS: REGISTRY_PASS:
from_secret: registry_pass from_secret: registry_pass
commands: commands:
- TAG=${CI_COMMIT_SHA:0:8}
- echo "$REGISTRY_PASS" | docker login localhost:3000 -u "$REGISTRY_USER" --password-stdin - echo "$REGISTRY_PASS" | docker login localhost:3000 -u "$REGISTRY_USER" --password-stdin
- docker push localhost:3000/homelab/notebooks:${CI_COMMIT_SHA:0:8} - docker tag fhirworx/notebooks:$TAG localhost:3000/fhirworx/notebooks:$TAG
- docker push localhost:3000/homelab/notebooks:latest - docker push localhost:3000/fhirworx/notebooks:$TAG
- docker tag fhirworx/notebooks:latest localhost:3000/fhirworx/notebooks:latest
- docker push localhost:3000/fhirworx/notebooks:latest
depends_on: depends_on:
- scan-notebooks - scan-notebooks
when: when:
@@ -78,8 +90,9 @@ steps:
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- docker build -t localhost:3000/homelab/zotero:${CI_COMMIT_SHA:0:8} ./zotero - TAG=${CI_COMMIT_SHA:0:8}
- docker tag localhost:3000/homelab/zotero:${CI_COMMIT_SHA:0:8} localhost:3000/homelab/zotero:latest - docker build -t fhirworx/zotero:$TAG ./zotero
- docker tag fhirworx/zotero:$TAG fhirworx/zotero:latest
when: when:
- path: "zotero/**" - path: "zotero/**"
@@ -88,8 +101,9 @@ steps:
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- trivy image --severity HIGH,CRITICAL --exit-code 0 --format table localhost:3000/homelab/zotero:${CI_COMMIT_SHA:0:8} - TAG=${CI_COMMIT_SHA:0:8}
- trivy image --severity HIGH,CRITICAL --format json -o zotero-scan.json localhost:3000/homelab/zotero:${CI_COMMIT_SHA:0:8} - trivy image --severity HIGH,CRITICAL --exit-code 0 --format table fhirworx/zotero:$TAG
- trivy image --severity HIGH,CRITICAL --format json -o zotero-scan.json fhirworx/zotero:$TAG
depends_on: depends_on:
- build-zotero - build-zotero
when: when:
@@ -105,9 +119,12 @@ steps:
REGISTRY_PASS: REGISTRY_PASS:
from_secret: registry_pass from_secret: registry_pass
commands: commands:
- TAG=${CI_COMMIT_SHA:0:8}
- echo "$REGISTRY_PASS" | docker login localhost:3000 -u "$REGISTRY_USER" --password-stdin - echo "$REGISTRY_PASS" | docker login localhost:3000 -u "$REGISTRY_USER" --password-stdin
- docker push localhost:3000/homelab/zotero:${CI_COMMIT_SHA:0:8} - docker tag fhirworx/zotero:$TAG localhost:3000/fhirworx/zotero:$TAG
- docker push localhost:3000/homelab/zotero:latest - docker push localhost:3000/fhirworx/zotero:$TAG
- docker tag fhirworx/zotero:latest localhost:3000/fhirworx/zotero:latest
- docker push localhost:3000/fhirworx/zotero:latest
depends_on: depends_on:
- scan-zotero - scan-zotero
when: when:
@@ -119,8 +136,9 @@ steps:
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- docker build -t localhost:3000/homelab/docs:${CI_COMMIT_SHA:0:8} -f docs/Dockerfile . - TAG=${CI_COMMIT_SHA:0:8}
- docker tag localhost:3000/homelab/docs:${CI_COMMIT_SHA:0:8} localhost:3000/homelab/docs:latest - docker build -t fhirworx/docs:$TAG -f docs/Dockerfile .
- docker tag fhirworx/docs:$TAG fhirworx/docs:latest
- name: push-docs - name: push-docs
image: docker:cli image: docker:cli
@@ -132,9 +150,12 @@ steps:
REGISTRY_PASS: REGISTRY_PASS:
from_secret: registry_pass from_secret: registry_pass
commands: commands:
- TAG=${CI_COMMIT_SHA:0:8}
- echo "$REGISTRY_PASS" | docker login localhost:3000 -u "$REGISTRY_USER" --password-stdin - echo "$REGISTRY_PASS" | docker login localhost:3000 -u "$REGISTRY_USER" --password-stdin
- docker push localhost:3000/homelab/docs:${CI_COMMIT_SHA:0:8} - docker tag fhirworx/docs:$TAG localhost:3000/fhirworx/docs:$TAG
- docker push localhost:3000/homelab/docs:latest - docker push localhost:3000/fhirworx/docs:$TAG
- docker tag fhirworx/docs:latest localhost:3000/fhirworx/docs:latest
- docker push localhost:3000/fhirworx/docs:latest
depends_on: depends_on:
- build-docs - build-docs
@@ -174,25 +195,19 @@ steps:
- path: "zotero/**" - path: "zotero/**"
# ── Deploy: pull latest code + restart services ──────────────── # ── Deploy: pull latest code + restart services ────────────────
# Runs AFTER all image builds/pushes complete. Updates the host
# repo to the commit that triggered this pipeline, pulls any new
# registry images, and restarts changed services.
- name: deploy - name: deploy
image: docker:cli image: docker:cli
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
- /home/kert/stack:/home/kert/stack - /home/kert/stack:/home/kert/stack
commands: commands:
# Install git so we can update the host working copy
- apk add --no-cache git - apk add --no-cache git
- cd /home/kert/stack - cd /home/kert/stack
# Fetch the exact commit via HTTP (public repo, intrastack)
# and hard-reset the deploy dir to match it. Untracked files
# (duckdb, zotero data, etc.) are untouched.
- git fetch http://gitea:3000/homelab/stack.git main - git fetch http://gitea:3000/homelab/stack.git main
- git reset --hard FETCH_HEAD - git reset --hard FETCH_HEAD
# Pull new images from registry, restart changed services # Pin compose to the exact images just built
- docker compose pull --ignore-buildable - TAG=${CI_COMMIT_SHA:0:8}
- sed -i "s/^COMMIT_SHA=.*/COMMIT_SHA=$TAG/" .env 2>/dev/null || echo "COMMIT_SHA=$TAG" >> .env
- docker compose up -d --remove-orphans - docker compose up -d --remove-orphans
depends_on: depends_on:
- publish-package - publish-package

View File

@@ -28,8 +28,8 @@ steps:
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- docker build -t ci-test/notebooks:${CI_COMMIT_SHA:0:8} ./notebooks - docker build -t ci-test/fhirworx/notebooks:${CI_COMMIT_SHA:0:8} ./notebooks
- docker rmi ci-test/notebooks:${CI_COMMIT_SHA:0:8} - docker rmi ci-test/fhirworx/notebooks:${CI_COMMIT_SHA:0:8}
depends_on: depends_on:
- hadolint-notebooks - hadolint-notebooks
when: when:
@@ -48,8 +48,8 @@ steps:
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- docker build -t ci-test/zotero:${CI_COMMIT_SHA:0:8} ./zotero - docker build -t ci-test/fhirworx/zotero:${CI_COMMIT_SHA:0:8} ./zotero
- docker rmi ci-test/zotero:${CI_COMMIT_SHA:0:8} - docker rmi ci-test/fhirworx/zotero:${CI_COMMIT_SHA:0:8}
depends_on: depends_on:
- hadolint-zotero - hadolint-zotero
when: when:
@@ -68,8 +68,8 @@ steps:
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- docker build -t ci-test/docs:${CI_COMMIT_SHA:0:8} -f docs/Dockerfile . - docker build -t ci-test/fhirworx/docs:${CI_COMMIT_SHA:0:8} -f docs/Dockerfile .
- docker rmi ci-test/docs:${CI_COMMIT_SHA:0:8} - docker rmi ci-test/fhirworx/docs:${CI_COMMIT_SHA:0:8}
depends_on: depends_on:
- hadolint-docs - hadolint-docs
when: when:

View File

@@ -7,30 +7,41 @@ steps:
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- docker build -t localhost:3000/homelab/notebooks:${CI_COMMIT_SHA:0:8} ./notebooks - TAG=${CI_COMMIT_SHA:0:8}
- docker tag localhost:3000/homelab/notebooks:${CI_COMMIT_SHA:0:8} localhost:3000/homelab/notebooks:latest - docker build -t fhirworx/notebooks:$TAG ./notebooks
- docker tag fhirworx/notebooks:$TAG fhirworx/notebooks:latest
- name: build-zotero - name: build-zotero
image: docker:cli image: docker:cli
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- docker build -t localhost:3000/homelab/zotero:${CI_COMMIT_SHA:0:8} ./zotero - TAG=${CI_COMMIT_SHA:0:8}
- docker tag localhost:3000/homelab/zotero:${CI_COMMIT_SHA:0:8} localhost:3000/homelab/zotero:latest - docker build -t fhirworx/zotero:$TAG ./zotero
- docker tag fhirworx/zotero:$TAG fhirworx/zotero:latest
- name: build-docs
image: docker:cli
volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock
commands:
- TAG=${CI_COMMIT_SHA:0:8}
- docker build -t fhirworx/docs:$TAG -f docs/Dockerfile .
- docker tag fhirworx/docs:$TAG fhirworx/docs:latest
- name: scan-notebooks - name: scan-notebooks
image: aquasec/trivy:latest image: aquasec/trivy:latest
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- trivy image --severity HIGH,CRITICAL --exit-code 0 --format table localhost:3000/homelab/notebooks:${CI_COMMIT_SHA:0:8} - trivy image --severity HIGH,CRITICAL --exit-code 0 --format table fhirworx/notebooks:${CI_COMMIT_SHA:0:8}
- name: scan-zotero - name: scan-zotero
image: aquasec/trivy:latest image: aquasec/trivy:latest
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
commands: commands:
- trivy image --severity HIGH,CRITICAL --exit-code 0 --format table localhost:3000/homelab/zotero:${CI_COMMIT_SHA:0:8} - trivy image --severity HIGH,CRITICAL --exit-code 0 --format table fhirworx/zotero:${CI_COMMIT_SHA:0:8}
- name: push-images - name: push-images
image: docker:cli image: docker:cli
@@ -42,16 +53,22 @@ steps:
REGISTRY_PASS: REGISTRY_PASS:
from_secret: registry_pass from_secret: registry_pass
commands: commands:
- TAG=${CI_COMMIT_SHA:0:8}
- echo "$REGISTRY_PASS" | docker login localhost:3000 -u "$REGISTRY_USER" --password-stdin - echo "$REGISTRY_PASS" | docker login localhost:3000 -u "$REGISTRY_USER" --password-stdin
- docker push localhost:3000/homelab/notebooks:${CI_COMMIT_SHA:0:8} - for SVC in notebooks zotero docs; do
- docker push localhost:3000/homelab/notebooks:latest - docker tag fhirworx/$SVC:$TAG localhost:3000/fhirworx/$SVC:$TAG
- docker push localhost:3000/homelab/zotero:${CI_COMMIT_SHA:0:8} - docker push localhost:3000/fhirworx/$SVC:$TAG
- docker push localhost:3000/homelab/zotero:latest - docker tag fhirworx/$SVC:latest localhost:3000/fhirworx/$SVC:latest
- docker push localhost:3000/fhirworx/$SVC:latest
- done
- name: deploy - name: deploy
image: docker:cli image: docker:cli
volumes: volumes:
- /run/user/1000/docker.sock:/var/run/docker.sock - /run/user/1000/docker.sock:/var/run/docker.sock
- /home/kert/stack:/home/kert/stack
commands: commands:
- docker compose pull - cd /home/kert/stack
- docker compose up -d - TAG=${CI_COMMIT_SHA:0:8}
- sed -i "s/^COMMIT_SHA=.*/COMMIT_SHA=$TAG/" .env 2>/dev/null || echo "COMMIT_SHA=$TAG" >> .env
- docker compose up -d --remove-orphans

View File

@@ -44,7 +44,7 @@ services:
restart: unless-stopped restart: unless-stopped
rustfs: rustfs:
image: localhost:3000/homelab/rustfs:latest image: fhirworx/rustfs:${COMMIT_SHA:-latest}
container_name: rustfs container_name: rustfs
user: "10001:10001" user: "10001:10001"
networks: networks:
@@ -61,7 +61,7 @@ services:
restart: unless-stopped restart: unless-stopped
postgres: postgres:
image: localhost:3000/homelab/postgresql:latest image: fhirworx/postgresql:${COMMIT_SHA:-latest}
container_name: postgres container_name: postgres
networks: networks:
- storage - storage
@@ -176,7 +176,7 @@ services:
restart: unless-stopped restart: unless-stopped
notebooks: notebooks:
image: localhost:3000/homelab/notebooks:latest image: fhirworx/notebooks:${COMMIT_SHA:-latest}
container_name: notebooks container_name: notebooks
networks: networks:
- gateway - gateway
@@ -201,7 +201,7 @@ services:
restart: unless-stopped restart: unless-stopped
zotero: zotero:
image: localhost:3000/homelab/zotero:latest image: fhirworx/zotero:${COMMIT_SHA:-latest}
container_name: zotero container_name: zotero
networks: networks:
- gateway - gateway
@@ -341,7 +341,7 @@ services:
restart: unless-stopped restart: unless-stopped
docs: docs:
image: localhost:3000/homelab/docs:latest image: fhirworx/docs:${COMMIT_SHA:-latest}
container_name: docs container_name: docs
networks: networks:
- gateway - gateway

View File

@@ -10,9 +10,9 @@ COPY docs/scripts/ docs/scripts/
# Extract API docs via griffe (pure AST, no imports) # Extract API docs via griffe (pure AST, no imports)
RUN uv run --with griffe python docs/scripts/extract_docs.py RUN uv run --with griffe python docs/scripts/extract_docs.py
# Export bibliography (needs bib deps from src/) # Export bibliography (gracefully handles missing bib.sqlite)
COPY data/bib.sqlite data/bib.sqlite
COPY pyproject.toml . COPY pyproject.toml .
COPY data/bib.sqlit[e] data/
RUN uv run python docs/scripts/export_library.py RUN uv run python docs/scripts/export_library.py
@@ -23,7 +23,8 @@ WORKDIR /docs
# Install dependencies # Install dependencies
COPY docs/package.json docs/package-lock.json* ./ COPY docs/package.json docs/package-lock.json* ./
RUN npm ci # hadolint ignore=DL3016
RUN npm install
# Copy Docusaurus config and source # Copy Docusaurus config and source
COPY docs/docusaurus.config.js docs/sidebars.js docs/babel.config.js docs/tsconfig.json ./ COPY docs/docusaurus.config.js docs/sidebars.js docs/babel.config.js docs/tsconfig.json ./

View File

@@ -10,6 +10,10 @@ const config = {
onBrokenLinks: "warn", onBrokenLinks: "warn",
onBrokenMarkdownLinks: "warn", onBrokenMarkdownLinks: "warn",
markdown: {
format: "detect",
},
i18n: { i18n: {
defaultLocale: "en", defaultLocale: "en",
locales: ["en"], locales: ["en"],