diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..7e612fe --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,67 @@ +name: Release + +# Samme udløser som GitHub-workflowet: et semver-tag, og ikke andet. +# +# Gitea Actions læser samme format som GitHub Actions og kan bruge handlinger +# derfra, men det er *ikke* det samme sted. Filen ligger derfor for sig i +# `.gitea/workflows/` frem for at være delt: `secrets.GITHUB_TOKEN` findes ikke +# her, registret er et andet, og der er ingen Releases-side at skrive til. En delt +# fil ville være fire betingede led, der hver kun gælder ét af de to steder. +on: + push: + tags: ["v[0-9]+.[0-9]+.[0-9]+*"] + +jobs: + image: + name: Build and publish image + # `ubuntu-latest` betyder her det, runneren er sat op til at kalde det. + # Registreres runneren med en anden etiket, skal denne linje følge med. + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 + + # `GITEA_TOKEN` er automatisk til stede i et Actions-job og har lov at + # skrive pakker for den, der ejer repoet. Ingen hemmelighed at sætte op. + - uses: docker/login-action@v3 + with: + registry: gitea.nolimit.dk + username: ${{ gitea.actor }} + password: ${{ secrets.GITEA_TOKEN }} + + - id: meta + uses: docker/metadata-action@v5 + with: + images: gitea.nolimit.dk/${{ gitea.repository }} + # v1.4.2 udgiver 1.4.2, 1.4 og 1 — så en rune, der er bundet til :1, får + # rettelser uden nogensinde at krydse et hovedversionsskifte. + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=raw,value=latest + + # arm64 er ikke valgfrit: et hjemmelab er lige så tit en Raspberry Pi eller + # en Apple silicon-VM som en x86-kasse. + - uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + VERSION=${{ gitea.ref_name }} + # Ingen `cache-from: type=gha`. Den cache er GitHubs tjeneste, og den + # findes ikke her — bedt om den, fejler trinnet på noget, der ikke har + # med bygningen at gøre. Uden cache tager en kold bygning nogle minutter + # længere, og det er prisen, indtil runneren har en cache af sin egen. + # Ingen Release oprettes. + # + # GitHub-workflowet laver en Release, fordi opdateringsnotitsen i appen læser + # `releases/latest` derfra. Gitea har sit eget Releases-begreb, men notitsen + # peger på GitHub — så en release her ville ingen læse. Skal notitsen flyttes + # med, er det `internal/update`, der skal have en ny adresse, og det er en + # ændring for sig. diff --git a/README.md b/README.md index b4f5994..d6a0f39 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ docker run -d --name verdande \ -p 8080:8080 \ -v verdande-data:/data \ -e VERDANDE_BASE_URL=https://todo.example.dk \ - ghcr.io/kristianwind/verdande:latest + gitea.nolimit.dk/kw/verdande:latest ``` ### From source diff --git a/docs/index.md b/docs/index.md index e6e8da6..097a7da 100644 --- a/docs/index.md +++ b/docs/index.md @@ -72,7 +72,7 @@ docker run -d --name verdande \ -p 8080:8080 \ -v verdande-data:/data \ -e VERDANDE_BASE_URL=https://todo.example.dk \ - ghcr.io/kristianwind/verdande:latest + gitea.nolimit.dk/kw/verdande:latest ``` Open the address, create the first account — that account is the administrator. diff --git a/docs/rune.md b/docs/rune.md index be653a9..b1221a8 100644 --- a/docs/rune.md +++ b/docs/rune.md @@ -7,14 +7,14 @@ verdande ships with a Rune manifest for ``` create container: Error response from daemon: -No such image: ghcr.io/kristianwind/verdande:latest +No such image: gitea.nolimit.dk/kw/verdande:latest ``` This message is a liar. It does not mean the tag is missing from the registry — it means the image is not on the host, and the panel's attempt to fetch it failed without saying so. -The usual cause is a **private** GHCR package. Yggdrasil pulls anonymously: its +The usual cause is a **private** package. Yggdrasil pulls anonymously: its `PullImage` calls the Docker SDK with no `RegistryAuth`, so a private image comes back 401. The pull error is discarded, and `ContainerCreate` — which only ever looks locally — then reports the image as missing. @@ -24,10 +24,21 @@ looks locally — then reports the image as missing. sends them itself with each request. Yggdrasil is a different client and sends none, so logging in changes nothing for the panel. -**Make the package public.** Under -[Packages → verdande → Package settings](https://github.com/users/kristianwind/packages/container/package/verdande) -→ *Change visibility*. The repository stays private; only the built image becomes -readable, which is what the manifest and these pages have always assumed. +**The package has to be readable without credentials.** On Gitea that does not +mean making the source repository public: a container package is only tied to a +repository when it is pushed with a repository link, and this one is not — so its +visibility follows the account, which is public, while `kw/verdande` stays +private. + +Check it the way a puller does, with no credentials at all: + +```bash +docker --config /tmp/empty pull gitea.nolimit.dk/kw/verdande:latest +``` + +If that works, the panel can pull it. A plain `curl` against `/v2/…/manifests/…` +answers 401 even for a readable image — the registry hands out an anonymous token +first — so a bare curl is not the test. Once it is public, press **Start** on the server you already have. There is no need to delete it and make another: the image reference is read from the rune at @@ -37,8 +48,8 @@ To keep the package private you have to put the image on the host yourself, before creating the server, and again after every release: ```bash -sudo docker login ghcr.io -u kristianwind -sudo docker pull ghcr.io/kristianwind/verdande:latest +sudo docker login gitea.nolimit.dk -u kw +sudo docker pull gitea.nolimit.dk/kw/verdande:latest ``` Run it as the user the Docker daemon runs as — `sudo` if the panel does. The diff --git a/docs/self-hosting.md b/docs/self-hosting.md index eaf1bc9..9ca5183 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -6,9 +6,10 @@ cache, no queue and no second process. ## Docker !!! note "If the pull is refused" - The GHCR package is public, so this needs no credentials. If it is ever set - back to private, `docker login ghcr.io` with a token carrying the - `read:packages` scope before pulling — and see + The image is published from a self-hosted Gitea and is readable without + credentials — the package is not linked to a repository, so its visibility + follows the account rather than the (private) source repo. If it is ever set + back to private, `docker login gitea.nolimit.dk` before pulling — and see [the Rune page](rune.md#if-the-image-will-not-pull), because a private image fails differently and much more confusingly under Yggdrasil. @@ -18,7 +19,7 @@ docker run -d --name verdande \ -p 8080:8080 \ -v verdande-data:/data \ -e VERDANDE_BASE_URL=https://todo.example.dk \ - ghcr.io/kristianwind/verdande:latest + gitea.nolimit.dk/kw/verdande:latest ``` `VERDANDE_BASE_URL` has to be the address you actually reach it on. Invite links, @@ -30,7 +31,7 @@ means the links in your email point somewhere that does not answer. ```yaml services: verdande: - image: ghcr.io/kristianwind/verdande:latest + image: gitea.nolimit.dk/kw/verdande:latest restart: unless-stopped ports: - "8080:8080" diff --git a/rune/verdande.yaml b/rune/verdande.yaml index 493fbdb..d305065 100644 --- a/rune/verdande.yaml +++ b/rune/verdande.yaml @@ -15,14 +15,30 @@ gameskill: # this: a manifest with new fields and an unchanged version is a manifest the # panel has no reason to re-read, so the fields never appear and the failure is # silent — the server's settings page simply does not offer them. - version: 4 + # Bumpet til 5, fordi imagets adresse flyttede. En rune opdaterer ikke sig selv: + # panelet skriver rune-rækken fra en UI-handling, så ændringen her kræver + # **Runes → verdande → Update** — og katalog-listen caches ti minutter, så to + # forsøg lige efter hinanden kan begge give den gamle version. + version: 5 icon: "app" # The image is distroless — no shell — so keep_entrypoint runs the binary the # image already declares as its ENTRYPOINT, and startup.exec passes it argv # directly rather than through /bin/sh, which does not exist in there. + # Hentes fra vores egen Gitea frem for fra GHCR. + # + # Panelets `PullImage` sætter aldrig `RegistryAuth`, så registret skal kunne + # læses anonymt. Det kan det her: pakken er *ikke* knyttet til repoet — Gitea + # binder kun en container-pakke til et repo, når den bliver skubbet med et + # repo-link — så dens synlighed følger brugeren `kw`, som er offentlig, mens + # `kw/verdande` bliver ved med at være privat. Bevist med en `docker pull` uden + # nogen legitimation, som hentede samme digest som GHCR havde. + # + # Skubbes den nogensinde på en måde, der knytter den til repoet, bliver den + # privat med det samme, og panelet får `No such image` — lydløst, fordi + # `pullImageRetry` kasserer fejlen og `ContainerCreate` først slår op lokalt. docker: - image: "ghcr.io/kristianwind/verdande:latest" + image: "gitea.nolimit.dk/kw/verdande:latest" data_path: /data keep_entrypoint: true diff --git a/site/index.html b/site/index.html index 2e7a0cc..05865f3 100644 --- a/site/index.html +++ b/site/index.html @@ -1238,7 +1238,7 @@ -p 8080:8080 \ -v verdande-data:/data \ -e VERDANDE_BASE_URL=https://todo.example.dk \ - ghcr.io/kristianwind/verdande:latest + gitea.nolimit.dk/kw/verdande:latest