From 1eb6fd930d6adb0035af1330c789b20d416a6815 Mon Sep 17 00:00:00 2001 From: Kristian Wind Date: Mon, 17 Aug 2026 10:41:06 +0200 Subject: [PATCH] docs: the registry is private, and the handoff is current again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Installing the Rune failed with create container: Error response from daemon: No such image: ghcr.io/kristianwind/verdande:latest which was two things wearing one message. No semver tag had ever been pushed, so release.yml had never run and the image did not exist. And now that v0.1.0 is published, the package is private because the repository is — and an anonymous pull reports that as "no such image" rather than as a permission error, which sends you looking in the wrong place. The Docker daemon on the host has to be logged in once, as whichever user runs it. Said in rune.md, self-hosting.md, the README and the handoff, because whichever one you are holding is the one that has to say it. The handoff's seven gaps are down to the ones that need real credentials and real services: Gmail against an account, Web Push against a push service, PNG icons for iOS, the AI adapters against a key. Added in their place are the traps this round cost the most time on — that the embedded frontend is a copy that npm run build does not touch, that Playwright re-runs its config in every worker, and that svelte-check is not a gate in a codebase with no type annotations. Co-Authored-By: Claude Opus 5 --- README.md | 23 +++++++++++++++++++---- docs/rune.md | 28 ++++++++++++++++++++++++++++ docs/self-hosting.md | 10 ++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 21bd4e4..db1049c 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,9 @@ Apple Reminders, forward mail into it, and add it to Claude as a connector. | Sharing: invites, roles, members | Done, tested | | Live sync over WebSocket | Done | | Web interface: sign-in, views, quick add, ⌘K, shortcuts | Done | +| Task detail: description, sub-tasks, comments, files, reminders | Done | +| Settings: account, notifications, integrations, AI, tokens, data | Done | +| Drag to reorder, in both the list and the board | Done | | Recurring tasks (RRULE, Danish + English) | Done, tested | | Reminders, absolute and relative | Done, tested | | Saved filters with a query language | Done, tested | @@ -78,13 +81,17 @@ Apple Reminders, forward mail into it, and add it to Claude as a connector. | AI layer (Anthropic/OpenAI/Google/local) | Built, degrades when unconfigured | | Gmail: OAuth2 with PKCE, polling, one-way to tasks | Done, tested | | Update notice for administrators | Done, tested | +| Personal API tokens | Done, tested | +| OpenAPI 3.1 spec, checked against the router | Done, tested | +| End-to-end smoke tests (Playwright) | Done | | Documentation, landing page, licence | Done | **Not finished:** Web Push, the AI providers and the Gmail API calls are -implemented against their specifications but have only been exercised there, not -against live services. And the interface does not yet expose comments, -attachments, reminders, templates, import/export or the settings pages — all of it -works through the API. +implemented against their specifications and have only ever been exercised there, +not against live services. Everything else has an interface: opening a task shows +its description, sub-tasks, comments, files and reminders, and the settings pages +cover the account, notifications, integrations, AI, API tokens, import, export and +templates. Search finds `grøn` when you type `gron`, because Unicode does not consider `ø` an accented `o` and a Danish-first app that cannot do this is broken for its own users. @@ -119,6 +126,14 @@ and the manifest ships in this repository. It runs anywhere Docker does as well. ### With Docker directly +The package is private, and an anonymous pull fails with `No such image` rather +than with a permission error. Log the host's Docker daemon in once, with a GitHub +token carrying the `read:packages` scope: + +```bash +echo "$GHCR_TOKEN" | docker login ghcr.io -u kristianwind --password-stdin +``` + ```bash docker run -d --name verdande \ -p 8080:8080 \ diff --git a/docs/rune.md b/docs/rune.md index 31072b1..a876c91 100644 --- a/docs/rune.md +++ b/docs/rune.md @@ -3,6 +3,34 @@ verdande ships with a Rune manifest for [Yggdrasil Panel](https://github.com/kristianwind/yggdrasil). +## Before you start: the registry is private + +The image lives at `ghcr.io/kristianwind/verdande` and the package is **private**, +so an anonymous pull fails with a message that reads as though the image does not +exist at all: + +``` +create container: Error response from daemon: +No such image: ghcr.io/kristianwind/verdande:latest +``` + +That is a permission error wearing the wrong hat. The Docker daemon **on the +Yggdrasil host** has to be logged in once: + +```bash +echo "$GHCR_TOKEN" | docker login ghcr.io -u kristianwind --password-stdin +``` + +`GHCR_TOKEN` is a GitHub personal access token with the **`read:packages`** scope +and nothing else. The login is stored in `~/.docker/config.json` for whichever +user runs the daemon — if Yggdrasil runs as root or through systemd, log in as +that user, not as yourself. + +!!! tip "Or make the package public" + Under **Packages → verdande → Package settings → Change visibility**. The + repository can stay private; only the built image becomes readable. Then no + login is needed anywhere and this section stops applying. + ## Installing 1. **Runes → Carve a rune (upload)** and pick diff --git a/docs/self-hosting.md b/docs/self-hosting.md index a94ebfa..e078edc 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -5,6 +5,16 @@ cache, no queue and no second process. ## Docker +!!! warning "Log in to the registry first" + The package is private, and an anonymous pull fails with `No such image` + rather than with a permission error. Once per host: + + ```bash + echo "$GHCR_TOKEN" | docker login ghcr.io -u kristianwind --password-stdin + ``` + + `GHCR_TOKEN` is a GitHub token with the `read:packages` scope. + ```bash docker run -d --name verdande \ --restart unless-stopped \