Publikovat image do registru balíčků Gitey #15
No files matched your search
@@ -0,0 +1,85 @@
|
||||
# Postaví kontejnerový image a zkusí ho spustit. Nikam ho neposílá.
|
||||
#
|
||||
# Dockerfile by se jinak rozbil až ve chvíli, kdy se tagne release — tohle ho
|
||||
# ohlídá nad každým pull requestem.
|
||||
#
|
||||
# Publikuje se jinde: .github/workflows/image.yml. Zdejší runner běží v LXC,
|
||||
# kde nejde zaregistrovat binfmt, takže arm64 by se tu postavit nedalo.
|
||||
# Registrace je vlastnost jádra hostitele a to je produkční stroj, do kterého
|
||||
# se kvůli počitadlu kostek vrtat nebude.
|
||||
#
|
||||
# Staví se nativní amd64 obyčejným `docker build`, žádný buildx ani emulace.
|
||||
name: image
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
ZKOUSKA_PORT: "18000"
|
||||
|
||||
jobs:
|
||||
image:
|
||||
runs-on: homelab
|
||||
|
||||
steps:
|
||||
- name: Zdrojáky
|
||||
env:
|
||||
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
git init -q .
|
||||
git remote remove origin 2>/dev/null || true
|
||||
git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
|
||||
git config http.extraheader "Authorization: token ${TOKEN}"
|
||||
git fetch -q --depth 1 origin "${GITHUB_REF}"
|
||||
git config --unset http.extraheader
|
||||
git checkout -qf FETCH_HEAD
|
||||
git clean -qfd
|
||||
|
||||
- name: Předpoklady
|
||||
run: |
|
||||
command -v docker >/dev/null \
|
||||
|| { echo "Docker na runneru není." >&2; exit 1; }
|
||||
docker version --format '{{.Server.Version}}'
|
||||
|
||||
- name: Stavba
|
||||
run: |
|
||||
docker build -f deploy/Dockerfile \
|
||||
--build-arg VERSION="zkouska-${GITHUB_SHA:0:7}" \
|
||||
-t dice-counter:zkouska .
|
||||
|
||||
- name: Zkouška
|
||||
run: |
|
||||
trap 'docker rm -f dice-counter-zkouska >/dev/null 2>&1 || true' EXIT
|
||||
|
||||
# Port musí být stejný uvnitř i venku: appka poslouchá na DICE_PORT,
|
||||
# takže mapovat ho na jiný by znamenalo mířit do prázdna.
|
||||
# Adresa se vnucuje, ať zkouška nezávisí na síti runneru a dá se
|
||||
# ověřit, co přesně tabule nabídne.
|
||||
docker run -d --name dice-counter-zkouska --init \
|
||||
-p "${ZKOUSKA_PORT}:${ZKOUSKA_PORT}" -e DICE_HOST=127.0.0.1 \
|
||||
-e DICE_PORT="${ZKOUSKA_PORT}" dice-counter:zkouska
|
||||
|
||||
for _ in $(seq 30); do
|
||||
curl -sf -o /dev/null "http://127.0.0.1:${ZKOUSKA_PORT}/" && break
|
||||
sleep 1
|
||||
done
|
||||
|
||||
curl -sf -o /dev/null "http://127.0.0.1:${ZKOUSKA_PORT}/" || {
|
||||
echo "Kontejner se nerozeběhl." >&2
|
||||
docker logs dice-counter-zkouska >&2
|
||||
exit 1; }
|
||||
curl -sf -o /dev/null "http://127.0.0.1:${ZKOUSKA_PORT}/static/style.css"
|
||||
curl -sf "http://127.0.0.1:${ZKOUSKA_PORT}/board" | grep -q "127.0.0.1:${ZKOUSKA_PORT}"
|
||||
curl -sf -o /dev/null "http://127.0.0.1:${ZKOUSKA_PORT}/export"
|
||||
|
||||
# Verze se musí do image opravdu dostat, ne se hlásit jako neznámá.
|
||||
docker run --rm dice-counter:zkouska python web.py --version
|
||||
! docker run --rm dice-counter:zkouska python web.py --version | grep -q "neznámá"
|
||||
|
||||
docker logs dice-counter-zkouska
|
||||
echo "Image jede."
|
||||
|
||||
- name: Úklid
|
||||
if: always()
|
||||
run: docker rmi dice-counter:zkouska >/dev/null 2>&1 || true
|
||||
@@ -0,0 +1,79 @@
|
||||
# Publikuje kontejnerový image do registru balíčků Gitey, pro amd64 i arm64.
|
||||
#
|
||||
# Proč zrovna odsud: domácí runner běží v LXC, kde nejde zaregistrovat binfmt
|
||||
# — je to vlastnost jádra hostitele a ten je produkční. Běhouni GitHubu jsou
|
||||
# plnohodnotné virtuály, kde emulace funguje bez řečí.
|
||||
#
|
||||
# Doma se image přesto staví a zkouší nad každým pull requestem
|
||||
# (.gitea/workflows/image.yml), jen se nikam neposílá. Stejná dělba jako
|
||||
# u binárek: doma se hlídá, tady se vydává.
|
||||
name: image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ["v*"]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: gitea.spacilovi.eu
|
||||
IMAGE: david-spacil/dice-counter
|
||||
PLATFORMS: linux/amd64,linux/arm64
|
||||
|
||||
jobs:
|
||||
publikace:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# Přesná verze, ne plovoucí značka — viz binarky.yml.
|
||||
- uses: actions/checkout@v7.0.1
|
||||
|
||||
- name: QEMU pro arm64
|
||||
run: |
|
||||
# Bez hotové akce z marketplace, ať není co udržovat. Běhoun je
|
||||
# virtuál, takže privilegovaný kontejner smí zapisovat do binfmt
|
||||
# a registrace platí pro celé jádro.
|
||||
docker run --privileged --rm tonistiigi/binfmt --install arm64
|
||||
|
||||
- name: Builder
|
||||
run: |
|
||||
# Výchozí ovladač Dockeru multiplatformní stavbu neumí.
|
||||
docker buildx create --name dice-counter --driver docker-container --use
|
||||
docker buildx inspect --bootstrap
|
||||
|
||||
# Bez tohohle by stavba spadla až na konci a hláška by nic neřekla.
|
||||
PLATFORMY=$(docker buildx inspect)
|
||||
echo "$PLATFORMY" | grep -q "linux/arm64" || {
|
||||
echo "Buildkit nevidí linux/arm64, emulace se nezaregistrovala." >&2
|
||||
exit 1; }
|
||||
|
||||
- name: Publikace
|
||||
env:
|
||||
TOKEN: ${{ secrets.PACKAGE_TOKEN }}
|
||||
# Uživatel v Gitee, ne na GitHubu. Shodou okolností je to totéž.
|
||||
VLASTNIK: david-spacil
|
||||
run: |
|
||||
# Spouští se to i ručně, a to klidně nad větví. Bez tagu není z čeho
|
||||
# udělat verzi a `:latest` by ukazoval na rozdělanou práci.
|
||||
[ "$GITHUB_REF_TYPE" = tag ] || {
|
||||
echo "Publikovat jde jen z tagu, tohle je ${GITHUB_REF_TYPE} ${GITHUB_REF_NAME}." >&2
|
||||
exit 1; }
|
||||
|
||||
# Automatický token na balíčky nestačí ani u Gitey samotné, natož
|
||||
# odsud — musí to být osobní token s oprávněním write:package.
|
||||
[ -n "$TOKEN" ] || { echo "Chybí secret PACKAGE_TOKEN." >&2; exit 1; }
|
||||
echo "$TOKEN" | docker login "$REGISTRY" -u "$VLASTNIK" --password-stdin
|
||||
trap 'docker logout "$REGISTRY" >/dev/null 2>&1 || true' EXIT
|
||||
|
||||
# Značka bez počátečního "v": v repozitáři je v1.2.0, u image se
|
||||
# čeká 1.2.0. Verze vypálená do image ale zůstává s "v", ať --version
|
||||
# hlásí totéž co binárky.
|
||||
VERZE="${GITHUB_REF_NAME#v}"
|
||||
|
||||
docker buildx build --platform "$PLATFORMS" --push \
|
||||
-f deploy/Dockerfile \
|
||||
--build-arg VERSION="${GITHUB_REF_NAME}" \
|
||||
-t "$REGISTRY/$IMAGE:$VERZE" \
|
||||
-t "$REGISTRY/$IMAGE:latest" .
|
||||
|
||||
echo "Publikováno: $REGISTRY/$IMAGE:$VERZE a :latest"
|
||||
docker buildx imagetools inspect "$REGISTRY/$IMAGE:$VERZE"
|
||||
@@ -192,13 +192,28 @@ Je idempotentní; druhé spuštění jen vymění binárku za nejnovější.
|
||||
|
||||
### Docker
|
||||
|
||||
Stačí jeden soubor, repozitář k tomu potřeba není:
|
||||
|
||||
```bash
|
||||
cd deploy && docker compose up -d
|
||||
curl -fsSLO https://gitea.spacilovi.eu/david-spacil/dice-counter/raw/branch/main/deploy/docker-compose.yaml
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Staví se ze zdrojáků, takže image jde sestavit pro amd64 i arm64 a nezávisí
|
||||
na tom, jestli release pro danou architekturu proběhl. Databáze leží
|
||||
v pojmenovaném svazku, appka běží pod nerootovým uživatelem.
|
||||
Image se stáhne hotový z registru Gitey, pro amd64 i arm64 — Docker si vybere
|
||||
svoji variantu sám. Databáze leží v pojmenovaném svazku, appka běží pod
|
||||
nerootovým uživatelem.
|
||||
|
||||
Aktualizace na novější vydání:
|
||||
|
||||
```bash
|
||||
docker compose pull && docker compose up -d
|
||||
```
|
||||
|
||||
Kdo si ho radši postaví ze zdrojáků, přebije ten stažený stejnou značkou:
|
||||
|
||||
```bash
|
||||
docker build -f deploy/Dockerfile -t gitea.spacilovi.eu/david-spacil/dice-counter:latest .
|
||||
```
|
||||
|
||||
**Pozor na síť.** Compose schválně používá `network_mode: host`. V bridge
|
||||
režimu kontejner uvnitř vidí adresu jako `172.17.0.2`, tabule ji poctivě
|
||||
@@ -207,9 +222,9 @@ Kdo bridge potřebuje, musí nastavit `DICE_HOST` na adresu hostitele v LAN.
|
||||
|
||||
| | LXC | Docker |
|
||||
|---|---|---|
|
||||
| Odkud | vydaná binárka z releasu | zdrojáky |
|
||||
| Odkud | vydaná binárka z releasu | image z registru |
|
||||
| Databáze | `/var/lib/kostky/dice.db` | svazek `kostky-data` |
|
||||
| Aktualizace | `pve-kostky.sh update <ctid>` | `docker compose build --pull` |
|
||||
| Aktualizace | `update` uvnitř kontejneru | `docker compose pull` |
|
||||
| Adresa a QR | funguje samo | potřeba síť hostitele |
|
||||
|
||||
## Když se telefon nepřipojí
|
||||
@@ -248,7 +263,7 @@ při remíze na prvním místě se hraje dál.
|
||||
| `console.py` | aby čeština prošla i windowsovou konzolí |
|
||||
| `version.py` | která verze to je — z gitu, nebo z binárky |
|
||||
| `build.sh`, `kostky.spec` | stavba binárky |
|
||||
| `.gitea/workflows/` | testy a linuxová binárka doma |
|
||||
| `.gitea/workflows/` | testy, linuxová binárka a zkouška image doma |
|
||||
| `.github/workflows/` | binárky pro Windows a macOS |
|
||||
| `deploy/` | nasazení na server: Proxmox LXC a Docker |
|
||||
|
||||
@@ -331,6 +346,7 @@ Otagovaný commit spustí stavbu na obou stranách:
|
||||
|---|---|---|
|
||||
| vlastní runner u Gitey | Linux x86-64 | `.gitea/workflows/binarka.yml` |
|
||||
| GitHub Actions | Windows, macOS ×2, Linux ARM64 | `.github/workflows/binarky.yml` |
|
||||
| GitHub Actions | image amd64 + arm64 | `.github/workflows/image.yml` |
|
||||
|
||||
```bash
|
||||
git tag v1.0.0 && git push origin v1.0.0
|
||||
@@ -353,7 +369,14 @@ ověřit:
|
||||
sha256sum -c kostky-linux-x86_64.sha256 # na macOS: shasum -a 256 -c
|
||||
```
|
||||
|
||||
Nad pull requesty se Linux staví taky, jen se nikam nevěší.
|
||||
Nad pull requesty se Linux staví taky, jen se nikam nevěší. Totéž platí pro
|
||||
kontejnerový image — doma se nad každým PR postaví a zkusí nastartovat
|
||||
(`.gitea/workflows/image.yml`), publikuje se ale až z tagu na GitHubu.
|
||||
|
||||
Image se schválně nevydává doma: tamní runner běží v LXC, kde nejde
|
||||
zaregistrovat emulaci pro arm64 — je to vlastnost jádra hostitele a ten je
|
||||
produkční stroj. Běhouni GitHubu jsou plnohodnotné virtuály, kde to funguje
|
||||
bez zásahu do čehokoli.
|
||||
|
||||
## Testy
|
||||
|
||||
|
||||
+5
-5
@@ -5,7 +5,7 @@
|
||||
# proběhl. Závislosti jsou zamčené v requirements.txt, takže je sestavení
|
||||
# opakovatelné.
|
||||
#
|
||||
# docker build -f deploy/Dockerfile -t kostky .
|
||||
# docker build -f deploy/Dockerfile -t gitea.spacilovi.eu/david-spacil/dice-counter:latest .
|
||||
#
|
||||
# Sestavuje se z kořene repozitáře, ne z deploy/.
|
||||
FROM python:3.11-slim
|
||||
@@ -13,7 +13,7 @@ FROM python:3.11-slim
|
||||
# Verze se jinak nemá kde vzít — v image není git ani zabalená binárka.
|
||||
ARG VERSION=neznámá
|
||||
|
||||
RUN useradd --system --uid 1000 --home-dir /app --shell /usr/sbin/nologin kostky
|
||||
RUN useradd --system --uid 1000 --home-dir /app --shell /usr/sbin/nologin dice-counter
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@@ -29,15 +29,15 @@ RUN echo "$VERSION" > verze.txt
|
||||
|
||||
# Adresář pro databázi musí vzniknout už tady a patřit správnému uživateli —
|
||||
# svazek, který Docker založí sám, by jinak patřil rootovi a appka běžící pod
|
||||
# kostky by do něj nezapsala.
|
||||
RUN install -d -o kostky -g kostky /data
|
||||
# dice-counter by do něj nezapsala.
|
||||
RUN install -d -o dice-counter -g dice-counter /data
|
||||
VOLUME ["/data"]
|
||||
|
||||
ENV DICE_DB=/data/dice.db \
|
||||
DICE_PORT=8000
|
||||
|
||||
EXPOSE 8000
|
||||
USER kostky
|
||||
USER dice-counter
|
||||
|
||||
# Bez curlu, ten ve slim image není. Stačí, že stránka odpoví — sahá i do
|
||||
# databáze, takže se tím kontroluje i ta.
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
# Počitadlo kostek v Dockeru.
|
||||
#
|
||||
# cd deploy && docker compose up -d
|
||||
# curl -fsSLO https://gitea.spacilovi.eu/david-spacil/dice-counter/raw/branch/main/deploy/docker-compose.yaml
|
||||
# docker compose up -d
|
||||
#
|
||||
# Nic dalšího není potřeba — image se stáhne hotový, pro amd64 i arm64.
|
||||
# Kdo si ho chce postavit ze zdrojáků, přebije ten stažený stejnou značkou:
|
||||
#
|
||||
# docker build -f deploy/Dockerfile -t gitea.spacilovi.eu/david-spacil/dice-counter:latest .
|
||||
#
|
||||
# Počítá se s domácí sítí. Appka nemá přihlašování, tohle ji nijak
|
||||
# nezabezpečuje a do internetu nepatří.
|
||||
|
||||
services:
|
||||
kostky:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile
|
||||
args:
|
||||
VERSION: ${VERSION:-vlastní sestavení}
|
||||
image: kostky:latest
|
||||
container_name: kostky
|
||||
dice-counter:
|
||||
image: gitea.spacilovi.eu/david-spacil/dice-counter:latest
|
||||
container_name: dice-counter
|
||||
restart: unless-stopped
|
||||
|
||||
# Python jako PID 1 nesklízí osiřelé procesy a hůř reaguje na signály.
|
||||
@@ -38,8 +39,8 @@ services:
|
||||
DICE_DB: /data/dice.db
|
||||
|
||||
volumes:
|
||||
- kostky-data:/data
|
||||
- dice-counter-data:/data
|
||||
|
||||
volumes:
|
||||
# Zálohu si stáhneš rovnou z appky přes /export, takže se sem nemusí lézt.
|
||||
kostky-data:
|
||||
dice-counter-data:
|
||||
Reference in new issue
Block a user