Compare commits
14
Commits
3c3805362f
...
v1.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96f2fc1028 | ||
|
|
826f243af7 | ||
|
|
b1b7d1fad1 | ||
|
|
b6066e2be8 | ||
|
|
9283a87a1e | ||
|
|
0bb2e0efab | ||
|
|
4faddc8b22 | ||
|
|
01d85594b2 | ||
|
|
fc2df8d86e | ||
|
|
83654fe6b5 | ||
|
|
861470da55 | ||
|
|
746916a755 | ||
|
|
eaa9c12ebc | ||
|
|
923fc03581 |
No files matched your search
@@ -0,0 +1,20 @@
|
|||||||
|
# Do image patří jen to, co appka za běhu potřebuje.
|
||||||
|
.git/
|
||||||
|
.github/
|
||||||
|
.gitea/
|
||||||
|
.venv/
|
||||||
|
.build/
|
||||||
|
.pytest_cache/
|
||||||
|
__pycache__/
|
||||||
|
dist/
|
||||||
|
tests/
|
||||||
|
deploy/
|
||||||
|
*.db
|
||||||
|
*.spec
|
||||||
|
build.sh
|
||||||
|
dice.py
|
||||||
|
verze.txt
|
||||||
|
README.md
|
||||||
|
requirements*.in
|
||||||
|
requirements-dev.txt
|
||||||
|
requirements-build.txt
|
||||||
@@ -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"
|
||||||
@@ -116,6 +116,117 @@ hlášku vysypal varování, že takhle se to nemá, a měl by pravdu.
|
|||||||
Počítá se s domácí sítí — appka nemá přihlašování a kdokoli na stejné WiFi
|
Počítá se s domácí sítí — appka nemá přihlašování a kdokoli na stejné WiFi
|
||||||
může zapisovat.
|
může zapisovat.
|
||||||
|
|
||||||
|
## Nasazení na server
|
||||||
|
|
||||||
|
Kdo nechce každý večer spouštět binárku na notebooku, může to nechat běžet
|
||||||
|
pořád. Obojí níž počítá **jen s domácí sítí** — appka nemá přihlašování
|
||||||
|
a ani jedno nasazení ji nijak nezabezpečuje. Do internetu to nepatří.
|
||||||
|
|
||||||
|
### Proxmox (LXC)
|
||||||
|
|
||||||
|
Jeden příkaz v terminálu uzlu Proxmoxu, jako root. Založí kontejner,
|
||||||
|
nastaví ho, stáhne poslední vydanou binárku, ověří kontrolní součet a zapne
|
||||||
|
službu:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash -c "$(curl -fsSL https://gitea.spacilovi.eu/david-spacil/dice-counter/raw/branch/main/deploy/pve-kostky.sh)"
|
||||||
|
```
|
||||||
|
|
||||||
|
Na konci vypíše adresu, na které počitadlo poslouchá. Výchozí nastavení je
|
||||||
|
1 jádro, 512 MB, 4 GB disku a Debian 13; úložiště si najde samo. Přebíjí se
|
||||||
|
proměnnými před příkazem:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
MEMORY=1024 STORAGE=local-zfs PORT=8080 bash -c "$(curl -fsSL ...)"
|
||||||
|
```
|
||||||
|
|
||||||
|
| Proměnná | Výchozí |
|
||||||
|
|---|---|
|
||||||
|
| `CTID` | první volné číslo |
|
||||||
|
| `CT_HOSTNAME` | `kostky` |
|
||||||
|
| `CORES`, `MEMORY`, `DISK` | `1`, `512`, `4` |
|
||||||
|
| `STORAGE` | první aktivní úložiště pro kontejnery |
|
||||||
|
| `TEMPLATE_STORAGE`, `BRIDGE` | `local`, `vmbr0` |
|
||||||
|
| `PORT` | `8000` |
|
||||||
|
| `UNPRIVILEGED`, `OSVERSION` | `1`, `13` |
|
||||||
|
| `NESTING` | `1` — systemd v Debianu 13 ho potřebuje |
|
||||||
|
| `AUTOLOGIN` | `1` — konzole ve webu Proxmoxu bez hesla |
|
||||||
|
| `VERSION` | poslední vydání |
|
||||||
|
|
||||||
|
Aktualizace na novější vydání se dá spustit dvěma způsoby. Buď zevnitř
|
||||||
|
kontejneru, kde na to stačí jedno slovo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
update
|
||||||
|
```
|
||||||
|
|
||||||
|
Nebo z uzlu Proxmoxu tím samým příkazem s číslem kontejneru:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CTID=123 MODE=update bash -c "$(curl -fsSL ...)"
|
||||||
|
```
|
||||||
|
|
||||||
|
Obojí vymění binárku za poslední vydání a službu restartuje; databáze zůstává.
|
||||||
|
Příkaz `update` si přitom obnoví i sám sebe — instalátor bere z větve `main`,
|
||||||
|
takže jede na nejnovější verzi skriptu, ne na té, se kterou se instalovalo.
|
||||||
|
|
||||||
|
Do konzole kontejneru se dostaneš přímo z webu Proxmoxu, **žádné jméno ani
|
||||||
|
heslo se nezadává** — kontejner root heslo nemá a konzole se přihlašuje sama.
|
||||||
|
Nová práva to nikomu nedává: kdo se dostane do webu Proxmoxu, má root na uzlu
|
||||||
|
tak jako tak. Komu se to nezdá, vypne to přes `AUTOLOGIN=0` a do kontejneru
|
||||||
|
pak leze přes `pct enter <ctid>`.
|
||||||
|
|
||||||
|
Podoba je odkoukaná od [community-scripts.org](https://community-scripts.org),
|
||||||
|
ale nic z jejich frameworku se nestahuje — jejich `build.func` si instalační
|
||||||
|
skript hledá natvrdo ve vlastním repozitáři, takže mimo něj nefunguje.
|
||||||
|
|
||||||
|
Instalátor, který běží uvnitř kontejneru, je ve skriptu vložený jako text —
|
||||||
|
přes rouru z curlu na disku hostitele žádný druhý soubor není. O Proxmoxu nic
|
||||||
|
neví, takže se dá použít i v kontejneru, který sis založil sám:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash pve-kostky.sh instalator > install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
curl -fsSLO https://gitea.spacilovi.eu/david-spacil/dice-counter/raw/branch/main/deploy/docker-compose.yaml
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
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ě
|
||||||
|
nabídne a vygeneruje na ni QR kód — jenže z telefonu je nedosažitelná.
|
||||||
|
Kdo bridge potřebuje, musí nastavit `DICE_HOST` na adresu hostitele v LAN.
|
||||||
|
|
||||||
|
| | LXC | Docker |
|
||||||
|
|---|---|---|
|
||||||
|
| Odkud | vydaná binárka z releasu | image z registru |
|
||||||
|
| Databáze | `/var/lib/kostky/dice.db` | svazek `kostky-data` |
|
||||||
|
| Aktualizace | `update` uvnitř kontejneru | `docker compose pull` |
|
||||||
|
| Adresa a QR | funguje samo | potřeba síť hostitele |
|
||||||
|
|
||||||
## Když se telefon nepřipojí
|
## Když se telefon nepřipojí
|
||||||
|
|
||||||
Adresy se hledají při každém načtení tabule, takže přechod z domácí WiFi na
|
Adresy se hledají při každém načtení tabule, takže přechod z domácí WiFi na
|
||||||
@@ -152,8 +263,9 @@ při remíze na prvním místě se hraje dál.
|
|||||||
| `console.py` | aby čeština prošla i windowsovou konzolí |
|
| `console.py` | aby čeština prošla i windowsovou konzolí |
|
||||||
| `version.py` | která verze to je — z gitu, nebo z binárky |
|
| `version.py` | která verze to je — z gitu, nebo z binárky |
|
||||||
| `build.sh`, `kostky.spec` | stavba 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 |
|
| `.github/workflows/` | binárky pro Windows a macOS |
|
||||||
|
| `deploy/` | nasazení na server: Proxmox LXC a Docker |
|
||||||
|
|
||||||
Terminálová verze zůstává funkční jako záloha:
|
Terminálová verze zůstává funkční jako záloha:
|
||||||
|
|
||||||
@@ -234,6 +346,7 @@ Otagovaný commit spustí stavbu na obou stranách:
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| vlastní runner u Gitey | Linux x86-64 | `.gitea/workflows/binarka.yml` |
|
| vlastní runner u Gitey | Linux x86-64 | `.gitea/workflows/binarka.yml` |
|
||||||
| GitHub Actions | Windows, macOS ×2, Linux ARM64 | `.github/workflows/binarky.yml` |
|
| GitHub Actions | Windows, macOS ×2, Linux ARM64 | `.github/workflows/binarky.yml` |
|
||||||
|
| GitHub Actions | image amd64 + arm64 | `.github/workflows/image.yml` |
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git tag v1.0.0 && git push origin v1.0.0
|
git tag v1.0.0 && git push origin v1.0.0
|
||||||
@@ -256,7 +369,14 @@ ověřit:
|
|||||||
sha256sum -c kostky-linux-x86_64.sha256 # na macOS: shasum -a 256 -c
|
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
|
## Testy
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# Počitadlo kostek jako kontejner.
|
||||||
|
#
|
||||||
|
# Staví se ze zdrojáků, ne z vydané binárky: image jde pak sestavit pro
|
||||||
|
# amd64 i arm64 a nezávisí na tom, jestli pro danou architekturu release
|
||||||
|
# proběhl. Závislosti jsou zamčené v requirements.txt, takže je sestavení
|
||||||
|
# opakovatelné.
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# 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 dice-counter
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Závislosti zvlášť a dřív než kód, ať se vrstva s pipem přestavuje jen tehdy,
|
||||||
|
# když se opravdu změnily.
|
||||||
|
COPY requirements.txt ./
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY console.py core.py net.py stats.py storage.py version.py web.py ./
|
||||||
|
COPY templates/ templates/
|
||||||
|
COPY static/ static/
|
||||||
|
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
|
||||||
|
# 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 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.
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
||||||
|
CMD python -c "import os,urllib.request; urllib.request.urlopen('http://127.0.0.1:' + os.environ.get('DICE_PORT','8000') + '/')"
|
||||||
|
|
||||||
|
CMD ["python", "web.py"]
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# Počitadlo kostek v Dockeru.
|
||||||
|
#
|
||||||
|
# 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:
|
||||||
|
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.
|
||||||
|
init: true
|
||||||
|
|
||||||
|
# Síť hostitele schválně. V bridge režimu kontejner uvnitř vidí adresu
|
||||||
|
# jako 172.17.0.2, tabule ji poctivě nabídne a vygeneruje na ni QR kód —
|
||||||
|
# jenže z telefonu je nedosažitelná. Se sítí hostitele appka najde tu
|
||||||
|
# adresu, na kterou se telefon opravdu dovolá.
|
||||||
|
#
|
||||||
|
# Kdo bridge potřebuje, ať zakomentuje řádek níž, odkomentuje ports
|
||||||
|
# a nastaví DICE_HOST na adresu hostitele v LAN:
|
||||||
|
#
|
||||||
|
# ports:
|
||||||
|
# - "8000:8000"
|
||||||
|
# environment:
|
||||||
|
# DICE_HOST: 192.168.1.10
|
||||||
|
network_mode: host
|
||||||
|
|
||||||
|
environment:
|
||||||
|
DICE_PORT: 8000
|
||||||
|
DICE_DB: /data/dice.db
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- dice-counter-data:/data
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
# Zálohu si stáhneš rovnou z appky přes /export, takže se sem nemusí lézt.
|
||||||
|
dice-counter-data:
|
||||||
Executable
+385
@@ -0,0 +1,385 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Založí na Proxmoxu LXC kontejner s počitadlem kostek.
|
||||||
|
#
|
||||||
|
# Pouští se v terminálu uzlu Proxmoxu jako root, jedním příkazem:
|
||||||
|
#
|
||||||
|
# bash -c "$(curl -fsSL https://gitea.spacilovi.eu/david-spacil/dice-counter/raw/branch/main/deploy/pve-kostky.sh)"
|
||||||
|
#
|
||||||
|
# Aktualizace stávajícího kontejneru na novější vydání:
|
||||||
|
#
|
||||||
|
# CTID=123 MODE=update bash -c "$(curl -fsSL .../pve-kostky.sh)"
|
||||||
|
#
|
||||||
|
# Ze staženého souboru jde i obojí postaru: `bash pve-kostky.sh` a
|
||||||
|
# `bash pve-kostky.sh update 123`.
|
||||||
|
#
|
||||||
|
# Podoba je odkoukaná od community-scripts.org, ale nic z jejich frameworku
|
||||||
|
# se tu nestahuje — jejich build.func si instalační skript hledá natvrdo ve
|
||||||
|
# vlastním repozitáři, takže mimo něj nefunguje.
|
||||||
|
#
|
||||||
|
# Počítá se s domácí sítí. Appka nemá přihlašování a tenhle skript ji nijak
|
||||||
|
# nezabezpečuje; do internetu ji nepouštěj.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
APP="Kostky"
|
||||||
|
GITEA="${GITEA:-https://gitea.spacilovi.eu}"
|
||||||
|
REPO="${REPO:-david-spacil/dice-counter}"
|
||||||
|
|
||||||
|
# Výchozí hodnoty. Všechny se dají přebít proměnnou prostředí, třeba:
|
||||||
|
# MEMORY=1024 STORAGE=local-zfs bash -c "$(curl -fsSL ...)"
|
||||||
|
CT_HOSTNAME="${CT_HOSTNAME:-kostky}"
|
||||||
|
CORES="${CORES:-1}"
|
||||||
|
MEMORY="${MEMORY:-512}"
|
||||||
|
DISK="${DISK:-4}"
|
||||||
|
STORAGE="${STORAGE:-}"
|
||||||
|
TEMPLATE_STORAGE="${TEMPLATE_STORAGE:-local}"
|
||||||
|
BRIDGE="${BRIDGE:-vmbr0}"
|
||||||
|
PORT="${PORT:-8000}"
|
||||||
|
UNPRIVILEGED="${UNPRIVILEGED:-1}"
|
||||||
|
OSVERSION="${OSVERSION:-13}"
|
||||||
|
NESTING="${NESTING:-1}"
|
||||||
|
AUTOLOGIN="${AUTOLOGIN:-1}" # konzole ve webu Proxmoxu bez hesla
|
||||||
|
VERSION="${VERSION:-}" # prázdné = poslední vydání
|
||||||
|
|
||||||
|
# --- výpisy ------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Bez tohohle Ctrl+C zabije jen rozdělaný podproces a skript jede vesele dál
|
||||||
|
# — třeba rovnou zakládat kontejner, na který se čekat nemá.
|
||||||
|
trap 'echo; echo -e "\e[1;31m ✗\e[0m Přerušeno." >&2; exit 130' INT TERM
|
||||||
|
|
||||||
|
msg() { echo -e "\e[1;34m →\e[0m $*"; }
|
||||||
|
ok() { echo -e "\e[1;32m ✓\e[0m $*"; }
|
||||||
|
die() { echo -e "\e[1;31m ✗\e[0m $*" >&2; exit 1; }
|
||||||
|
|
||||||
|
header() {
|
||||||
|
echo
|
||||||
|
echo -e "\e[1;36m $APP\e[0m — počitadlo kostek do LXC"
|
||||||
|
echo -e " \e[2m$GITEA/$REPO\e[0m"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- instalátor, který poběží uvnitř kontejneru ------------------------------
|
||||||
|
#
|
||||||
|
# Je tu jako text schválně. Skript se pouští i rourou z curlu, kdy na disku
|
||||||
|
# hostitele žádný soubor není a nebylo by co poslat dovnitř. Uvozovky kolem
|
||||||
|
# 'INSTALL' jsou podstatné: nic z toho se tady nesmí rozvinout, všechny
|
||||||
|
# proměnné patří až tomu, co poběží v kontejneru.
|
||||||
|
#
|
||||||
|
# Vypsat se dá i samostatně: `bash pve-kostky.sh instalator > install.sh`,
|
||||||
|
# což se hodí, když chceš appku dostat do kontejneru, který sis založil sám.
|
||||||
|
installer() {
|
||||||
|
cat <<'INSTALL'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Instalace počitadla uvnitř kontejneru. O Proxmoxu nic neví, takže se dá
|
||||||
|
# pustit v jakémkoli Debianu. Je idempotentní — druhé spuštění jen vymění
|
||||||
|
# binárku za nejnovější.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
GITEA="${GITEA:-https://gitea.spacilovi.eu}"
|
||||||
|
REPO="${REPO:-david-spacil/dice-counter}"
|
||||||
|
PORT="${PORT:-8000}"
|
||||||
|
VERSION="${VERSION:-}"
|
||||||
|
|
||||||
|
USER_NAME=kostky
|
||||||
|
HOME_DIR=/opt/kostky
|
||||||
|
DATA_DIR=/var/lib/kostky
|
||||||
|
|
||||||
|
msg() { echo -e "\e[1;34m →\e[0m $*"; }
|
||||||
|
ok() { echo -e "\e[1;32m ✓\e[0m $*"; }
|
||||||
|
die() { echo -e "\e[1;31m ✗\e[0m $*" >&2; exit 1; }
|
||||||
|
|
||||||
|
case "$(dpkg --print-architecture)" in
|
||||||
|
amd64) ASSET=kostky-linux-x86_64 ;;
|
||||||
|
arm64) ASSET=kostky-linux-arm64 ;;
|
||||||
|
*) die "Pro architekturu $(dpkg --print-architecture) binárka není." ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
msg "Doinstalovávám, co je potřeba ke stažení"
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq curl ca-certificates >/dev/null
|
||||||
|
ok "Základ je hotový"
|
||||||
|
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
msg "Zjišťuji poslední vydanou verzi"
|
||||||
|
# Jen tag; adresa přílohy se z něj složí, takže tu nepotřebujeme jq.
|
||||||
|
VERSION=$(curl -fsSL "$GITEA/api/v1/repos/$REPO/releases/latest" \
|
||||||
|
| grep -o '"tag_name":[[:space:]]*"[^"]*"' | head -1 | cut -d'"' -f4)
|
||||||
|
[ -n "$VERSION" ] || die "Nepodařilo se zjistit poslední verzi z $GITEA."
|
||||||
|
fi
|
||||||
|
ok "Instaluje se $VERSION ($ASSET)"
|
||||||
|
|
||||||
|
BASE="$GITEA/$REPO/releases/download/$VERSION"
|
||||||
|
TMP=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$TMP"' EXIT
|
||||||
|
|
||||||
|
msg "Stahuji binárku"
|
||||||
|
curl -fsSL -o "$TMP/$ASSET" "$BASE/$ASSET" \
|
||||||
|
|| die "$ASSET pro $VERSION na releasu není. Vydání pro tuhle architekturu možná ještě neproběhlo."
|
||||||
|
curl -fsSL -o "$TMP/$ASSET.sha256" "$BASE/$ASSET.sha256" \
|
||||||
|
|| die "Chybí kontrolní součet — radši nic neinstaluju."
|
||||||
|
|
||||||
|
msg "Ověřuji kontrolní součet"
|
||||||
|
( cd "$TMP" && sha256sum -c "$ASSET.sha256" >/dev/null ) \
|
||||||
|
|| die "Kontrolní součet nesedí. Stažený soubor zahazuju."
|
||||||
|
ok "Součet sedí"
|
||||||
|
|
||||||
|
id -u "$USER_NAME" >/dev/null 2>&1 \
|
||||||
|
|| useradd --system --home-dir "$HOME_DIR" --shell /usr/sbin/nologin "$USER_NAME"
|
||||||
|
|
||||||
|
install -d -o root -g root -m 755 "$HOME_DIR"
|
||||||
|
|
||||||
|
# Zastavit se dá jen to, co běží — při první instalaci služba ještě není.
|
||||||
|
if systemctl is-active --quiet kostky; then
|
||||||
|
systemctl stop kostky
|
||||||
|
fi
|
||||||
|
|
||||||
|
install -o root -g root -m 755 "$TMP/$ASSET" "$HOME_DIR/kostky"
|
||||||
|
echo "$VERSION" > "$HOME_DIR/verze"
|
||||||
|
ok "Binárka je na místě"
|
||||||
|
|
||||||
|
msg "Zapisuji službu"
|
||||||
|
cat > /etc/systemd/system/kostky.service <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Počitadlo kostek
|
||||||
|
Documentation=$GITEA/$REPO
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=$USER_NAME
|
||||||
|
Environment=DICE_DB=$DATA_DIR/dice.db
|
||||||
|
Environment=DICE_PORT=$PORT
|
||||||
|
ExecStart=$HOME_DIR/kostky
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
# Databáze je jediné, co appka potřebuje mít zapisovatelné. StateDirectory ji
|
||||||
|
# založí a předá správnému uživateli, takže se tu nemusí nic chownovat.
|
||||||
|
StateDirectory=kostky
|
||||||
|
ReadWritePaths=$DATA_DIR
|
||||||
|
|
||||||
|
NoNewPrivileges=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=true
|
||||||
|
# Binárka se při každém startu rozbaluje do /tmp; tady do vlastního, ne do
|
||||||
|
# sdíleného.
|
||||||
|
PrivateTmp=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --quiet --now kostky
|
||||||
|
ok "Služba běží"
|
||||||
|
|
||||||
|
# --- konzole v rozhraní Proxmoxu --------------------------------------------
|
||||||
|
|
||||||
|
if [ "${AUTOLOGIN:-1}" = "1" ]; then
|
||||||
|
msg "Nastavuji konzoli"
|
||||||
|
# Kontejner nemá root heslo, takže by se do konzole ve webu Proxmoxu
|
||||||
|
# nedalo dostat. Autologin to řeší stejně, jako to dělají community-scripts.
|
||||||
|
# Nová práva to nikomu nedává — kdo má web Proxmoxu, má root na uzlu tak
|
||||||
|
# jako tak.
|
||||||
|
mkdir -p /etc/systemd/system/container-getty@1.service.d
|
||||||
|
cat > /etc/systemd/system/container-getty@1.service.d/override.conf <<'GETTY'
|
||||||
|
[Service]
|
||||||
|
ExecStart=
|
||||||
|
ExecStart=-/sbin/agetty --autologin root --noclear --keep-baud tty%I 115200,38400,9600 $TERM
|
||||||
|
GETTY
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl restart container-getty@1.service 2>/dev/null || true
|
||||||
|
ok "Konzole se přihlásí sama"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- příkaz update ----------------------------------------------------------
|
||||||
|
|
||||||
|
# Instalátor si necháme, ať je z čeho aktualizovat. Když se skript pouští
|
||||||
|
# rourou, soubor neexistuje a zůstane ten z minula.
|
||||||
|
if [ -f "$0" ]; then
|
||||||
|
install -m 755 "$0" "$HOME_DIR/install.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > /usr/bin/update <<UPDATE
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Aktualizace počitadla na poslední vydání. Stačí napsat: update
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Nejdřív zkusíme obnovit i samotný instalátor, kdyby se mezitím zlepšil.
|
||||||
|
# Bez sítě nebo při změněné adrese se použije ten uložený.
|
||||||
|
NOVY=\$(mktemp)
|
||||||
|
if curl -fsSL "$GITEA/$REPO/raw/branch/main/deploy/pve-kostky.sh" -o "\$NOVY" 2>/dev/null \\
|
||||||
|
&& bash "\$NOVY" instalator > "\$NOVY.in" 2>/dev/null \\
|
||||||
|
&& bash -n "\$NOVY.in" 2>/dev/null; then
|
||||||
|
install -m 755 "\$NOVY.in" "$HOME_DIR/install.sh"
|
||||||
|
fi
|
||||||
|
rm -f "\$NOVY" "\$NOVY.in"
|
||||||
|
|
||||||
|
exec env PORT="$PORT" GITEA="$GITEA" REPO="$REPO" bash "$HOME_DIR/install.sh"
|
||||||
|
UPDATE
|
||||||
|
chmod 755 /usr/bin/update
|
||||||
|
ok "Aktualizovat půjde příkazem: update"
|
||||||
|
|
||||||
|
msg "Čekám, až začne odpovídat"
|
||||||
|
for _ in $(seq 30); do
|
||||||
|
curl -fsS -o /dev/null "http://127.0.0.1:$PORT/" 2>/dev/null && break
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
curl -fsS -o /dev/null "http://127.0.0.1:$PORT/" \
|
||||||
|
|| die "Služba nastartovala, ale neodpovídá. Mrkni na journalctl -u kostky."
|
||||||
|
|
||||||
|
# Verzi bereme ze souboru, ne z binárky. Starší vydání --version neumí
|
||||||
|
# a místo výpisu by nastartovala server, který by tenhle skript zavěsil.
|
||||||
|
ok "Počitadlo $(cat "$HOME_DIR/verze") odpovídá na portu $PORT"
|
||||||
|
INSTALL
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- společné části ----------------------------------------------------------
|
||||||
|
|
||||||
|
install_into() {
|
||||||
|
local ctid="$1" tmp
|
||||||
|
tmp=$(mktemp)
|
||||||
|
installer > "$tmp"
|
||||||
|
|
||||||
|
msg "Posílám instalátor do kontejneru $ctid"
|
||||||
|
pct push "$ctid" "$tmp" /root/kostky-install.sh --perms 0755
|
||||||
|
rm -f "$tmp"
|
||||||
|
|
||||||
|
pct exec "$ctid" -- env PORT="$PORT" GITEA="$GITEA" REPO="$REPO" \
|
||||||
|
VERSION="$VERSION" AUTOLOGIN="$AUTOLOGIN" bash /root/kostky-install.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
address_of() {
|
||||||
|
pct exec "$1" -- hostname -I 2>/dev/null | awk '{print $1}'
|
||||||
|
}
|
||||||
|
|
||||||
|
hotovo() {
|
||||||
|
local ctid="$1" ip jmeno
|
||||||
|
ip=$(address_of "$ctid")
|
||||||
|
jmeno=$(pct config "$ctid" | awk -F': ' '/^hostname:/ {print $2}')
|
||||||
|
|
||||||
|
echo
|
||||||
|
ok "Hotovo. Kontejner $ctid ($jmeno) běží."
|
||||||
|
echo
|
||||||
|
echo -e " Zápisník na notebook: \e[1;32mhttp://${ip}:${PORT}/board\e[0m"
|
||||||
|
echo -e " Zadávání z telefonu: \e[1;32mhttp://${ip}:${PORT}/\e[0m"
|
||||||
|
echo
|
||||||
|
echo -e " \e[2mDatabáze: /var/lib/kostky/dice.db (uvnitř kontejneru)"
|
||||||
|
echo -e " Aktualizace: v konzoli kontejneru napiš update"
|
||||||
|
echo -e " Log: pct exec $ctid -- journalctl -u kostky -f"
|
||||||
|
echo -e " Konzole: pct enter $ctid"
|
||||||
|
echo -e " Zrušit: pct stop $ctid && pct destroy $ctid\e[0m"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- co se má vlastně dělat --------------------------------------------------
|
||||||
|
#
|
||||||
|
# Rourou z curlu se argumenty předávají mizerně, tak jde všechno i proměnnou:
|
||||||
|
# MODE=update CTID=123. Ze souboru funguje i `bash pve-kostky.sh update 123`.
|
||||||
|
MODE="${MODE:-${1:-create}}"
|
||||||
|
[ "$MODE" = "update" ] && CTID="${CTID:-${2:-}}"
|
||||||
|
|
||||||
|
if [ "$MODE" = "instalator" ]; then
|
||||||
|
installer
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
command -v pct >/dev/null || die "Tohle patří na uzel Proxmoxu — pct tu není."
|
||||||
|
[ "$(id -u)" -eq 0 ] || die "Spusť to jako root."
|
||||||
|
|
||||||
|
# --- aktualizace -------------------------------------------------------------
|
||||||
|
|
||||||
|
if [ "$MODE" = "update" ]; then
|
||||||
|
[ -n "${CTID:-}" ] || die "Řekni který: CTID=123 MODE=update ..."
|
||||||
|
pct status "$CTID" >/dev/null 2>&1 || die "Kontejner $CTID neexistuje."
|
||||||
|
|
||||||
|
header
|
||||||
|
if [ "$(pct status "$CTID")" != "status: running" ]; then
|
||||||
|
msg "Startuji kontejner"
|
||||||
|
pct start "$CTID"
|
||||||
|
sleep 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
install_into "$CTID"
|
||||||
|
hotovo "$CTID"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- nový kontejner ----------------------------------------------------------
|
||||||
|
|
||||||
|
header
|
||||||
|
|
||||||
|
# Úložiště se nehádá. local-lvm na ZFS instalacích neexistuje a pct create by
|
||||||
|
# spadlo až po půlce práce, tak se radši zeptáme systému, co tu opravdu je.
|
||||||
|
if [ -z "$STORAGE" ]; then
|
||||||
|
STORAGE=$(pvesm status -content rootdir 2>/dev/null \
|
||||||
|
| awk 'NR>1 && $3=="active" {print $1; exit}')
|
||||||
|
[ -n "$STORAGE" ] || die "Nenašel jsem úložiště pro kontejnery. Zadej STORAGE=<jméno>; co máš, ukáže pvesm status."
|
||||||
|
msg "Úložiště: $STORAGE (nalezeno automaticky)"
|
||||||
|
else
|
||||||
|
pvesm status -content rootdir 2>/dev/null | awk 'NR>1 {print $1}' | grep -qx "$STORAGE" \
|
||||||
|
|| die "Úložiště $STORAGE pro kontejnery nesedí. Co máš, ukáže: pvesm status -content rootdir"
|
||||||
|
msg "Úložiště: $STORAGE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
CTID="${CTID:-$(pvesh get /cluster/nextid)}"
|
||||||
|
msg "Kontejner dostane číslo $CTID"
|
||||||
|
|
||||||
|
# Architektura uzlu, ne první šablona v seznamu. pveam nabízí amd64 i arm64
|
||||||
|
# vedle sebe a bez tohohle filtru by výběr padl na tu abecedně poslední.
|
||||||
|
ARCH=$(dpkg --print-architecture)
|
||||||
|
SABLONA="debian-${OSVERSION}-standard[^[:space:]]*_${ARCH}\.tar\.[a-z]*"
|
||||||
|
|
||||||
|
msg "Hledám šablonu Debianu $OSVERSION pro $ARCH"
|
||||||
|
|
||||||
|
# Nejdřív co už na uzlu leží — stahovat 120 MB znovu je zbytečné.
|
||||||
|
TEMPLATE=$(pveam list "$TEMPLATE_STORAGE" 2>/dev/null | grep -o "$SABLONA" | sort -V | tail -1)
|
||||||
|
|
||||||
|
if [ -n "$TEMPLATE" ]; then
|
||||||
|
ok "Šablona $TEMPLATE (už je na uzlu)"
|
||||||
|
else
|
||||||
|
pveam update >/dev/null 2>&1 || true
|
||||||
|
TEMPLATE=$(pveam available --section system 2>/dev/null | grep -o "$SABLONA" | sort -V | tail -1)
|
||||||
|
[ -n "$TEMPLATE" ] || die "Šablona pro Debian $OSVERSION a $ARCH není k dispozici."
|
||||||
|
|
||||||
|
msg "Stahuji $TEMPLATE (asi 120 MB, chvíli to trvá)"
|
||||||
|
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null \
|
||||||
|
|| die "Stažení šablony selhalo."
|
||||||
|
ok "Šablona $TEMPLATE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Nesting: Debian 13 veze systemd 257 a ten v neprivilegovaném kontejneru bez
|
||||||
|
# něj nedostane, co potřebuje — Proxmox na to při startu sám upozorňuje.
|
||||||
|
# Stejnou výchozí hodnotu mají i community-scripts.
|
||||||
|
msg "Zakládám kontejner"
|
||||||
|
pct create "$CTID" "$TEMPLATE_STORAGE:vztmpl/$TEMPLATE" \
|
||||||
|
--hostname "$CT_HOSTNAME" \
|
||||||
|
--cores "$CORES" \
|
||||||
|
--memory "$MEMORY" \
|
||||||
|
--swap 256 \
|
||||||
|
--rootfs "$STORAGE:$DISK" \
|
||||||
|
--net0 "name=eth0,bridge=$BRIDGE,ip=dhcp" \
|
||||||
|
--unprivileged "$UNPRIVILEGED" \
|
||||||
|
--features "nesting=$NESTING" \
|
||||||
|
--ostype debian \
|
||||||
|
--onboot 1 \
|
||||||
|
--description "$APP — $GITEA/$REPO" >/dev/null
|
||||||
|
ok "Kontejner $CTID založen"
|
||||||
|
|
||||||
|
msg "Startuji"
|
||||||
|
pct start "$CTID"
|
||||||
|
|
||||||
|
msg "Čekám na síť"
|
||||||
|
for _ in $(seq 60); do
|
||||||
|
if [ -n "$(address_of "$CTID")" ] \
|
||||||
|
&& pct exec "$CTID" -- getent hosts deb.debian.org >/dev/null 2>&1; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
[ -n "$(address_of "$CTID")" ] || die "Kontejner nedostal adresu. Sedí bridge $BRIDGE?"
|
||||||
|
ok "Adresa $(address_of "$CTID")"
|
||||||
|
|
||||||
|
install_into "$CTID"
|
||||||
|
hotovo "$CTID"
|
||||||
Reference in new issue
Block a user