Author SHA1 Message Date
libretech 0f4758cd8f Ignore runtime data and state of the stopped stack (#57)
Deploy / deploy (push) Failing after 18s
CI / ci (push) Successful in 11m27s
Co-authored-by: Michael Czechowski <mail@librete.ch>
2026-09-24 11:47:38 +02:00
libretech b6762a9deb Use the helper names the shell actually defines (#56)
CI / ci (push) Successful in 13m48s
Deploy / deploy (push) Failing after 2m9s
Co-authored-by: Michael Czechowski <mail@librete.ch>
2026-09-23 22:35:33 +02:00
libretech db991d8e21 chore: keep one agent pointer file, ignore agent scratch
Deploy / deploy (push) Failing after 1m45s
CI / ci (push) Successful in 12m47s
AGENTS.md is the convention; CODEX.md and GEMINI.md were 37-byte stubs
pointing back at it. .agents/ holds run logs and contracts, not source.
2026-09-23 22:10:14 +02:00
libretechandClaude Opus 4.7 622531d78d fix(devshell): bind ~/.gnupg into bwrap sandbox for signed commits
Deploy / deploy (push) Failing after 1m38s
CI / ci (push) Successful in 11m57s
The tmpfs overlay on $HOME hid the host GPG keyring inside the sandbox, so
git commits with commit.gpgsign failed with "can't connect to the keyboxd".
Bind ~/.gnupg rw, bind the gpg-agent socket dir (XDG_RUNTIME_DIR/gnupg),
and propagate GPG_TTY so pinentry-tty works.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 11:39:43 +02:00
libretech e738aeac05 ci: bump runner-image pin v0.1.0 → v0.2.0
Deploy / deploy (push) Failing after 1m28s
CI / ci (push) Successful in 11m51s
2026-05-04 21:37:26 +02:00
libretech 6b6993cc6f docs(deploy): add netcup deploy runbook
Deploy / deploy (push) Failing after 3m22s
CI / ci (push) Successful in 15m30s
Derived from netcup canonical DEPLOY-TEMPLATE.md. Same 9 sections
across all stacks (target, env, first-time, update, smoke,
troubleshooting, rollback, stack-specific notes, issue tracking).
README links to DEPLOY.md.
2026-05-04 16:19:27 +02:00
libretech fd77452727 docs(security): remove SSH username/host specifics from public docs
Deploy / deploy (push) Failing after 1m18s
CI / ci (push) Successful in 11m58s
2026-05-02 14:43:28 +02:00
libretech c0ac049d01 ci(runner-image): switch to public/ namespace (#55)
Co-authored-by: Michael Czechowski <mail@dailysh.it>
Co-committed-by: Michael Czechowski <mail@dailysh.it>
2026-05-02 14:10:56 +02:00
9 changed files with 102 additions and 5 deletions
+2 -2
View File
@@ -10,9 +10,9 @@ jobs:
ci: ci:
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Bespoke runner image (Ubuntu 24.04 + make + git + node + go via # Bespoke runner image (Ubuntu 24.04 + make + git + node + go via
# actions/setup-go). See git.librete.ch/libretech/runner-image. # actions/setup-go). See git.librete.ch/public/runner-image.
container: container:
image: git.librete.ch/libretech/runner-image:v1 image: git.librete.ch/public/runner-image:v0.2.0@sha256:f60c587d3c0b0aac04a572db5349e27672bf76baec2ce547a3dcc28cebcf1b7e
timeout-minutes: 5 timeout-minutes: 5
steps: steps:
- name: Checkout - name: Checkout
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
# + perl + ssh, runner user pre-joined to docker gid 998 so the # + perl + ssh, runner user pre-joined to docker gid 998 so the
# auto-mounted /var/run/docker.sock is writable without --user root. # auto-mounted /var/run/docker.sock is writable without --user root.
container: container:
image: git.librete.ch/libretech/runner-image:v1 image: git.librete.ch/public/runner-image:v0.2.0@sha256:f60c587d3c0b0aac04a572db5349e27672bf76baec2ce547a3dcc28cebcf1b7e
timeout-minutes: 20 timeout-minutes: 20
if: ${{ vars.DEPLOY_ENABLED == 'true' }} if: ${{ vars.DEPLOY_ENABLED == 'true' }}
steps: steps:
+7
View File
@@ -15,3 +15,10 @@ wave.yaml
/dist/ /dist/
*.test *.test
*.out *.out
# Agent scratch
/.agents/
# runtime data and state of the stopped stack
/data/
/state/
+1
View File
@@ -0,0 +1 @@
See CLAUDE.md for project guidelines.
+1 -1
View File
@@ -5,7 +5,7 @@ Cloud-native multi-tenant notes application built on Notesium (MIT).
## Project ## Project
- Repo: https://git.librete.ch/public/librenotes - Repo: https://git.librete.ch/public/librenotes
- Remote: `https://git.librete.ch/public/librenotes.git` - Remote: `ssh://git.librete.ch:41240/public/librenotes.git` (configure SSH user in `~/.ssh/config`)
- Stack: Go backend (forked from Notesium), vanilla JS frontend - Stack: Go backend (forked from Notesium), vanilla JS frontend
- License: MIT (inherited from Notesium) - License: MIT (inherited from Notesium)
+82
View File
@@ -0,0 +1,82 @@
# Deploy runbook — librenotes
Derived from [`netcup/DEPLOY-TEMPLATE.md`](https://git.librete.ch/libretech/netcup/src/branch/main/DEPLOY-TEMPLATE.md).
Section ordering and headings stable across stacks.
## 1. Target
| Field | Value |
|-------|-------|
| Vhost | `ln.cloud.librete.ch` |
| Server path | `/srv/librenotes/` |
| Repo | `git.librete.ch/public/librenotes` |
| Image source | `${LIBRENOTES_IMAGE}` from `git.librete.ch/public/librenotes` (registry image, no source build on remote) |
| Cert | edge caddy via INWX DNS-01 |
| Edge net container name | `librenotes` (matches `caddy/Caddyfile` reverse_proxy target on `:8080`) |
## 2. Required env / secrets
`/srv/librenotes/.env` (gitignored, mode 0600):
| Variable | Notes |
|----------|-------|
| `LIBRENOTES_IMAGE` | published tag, e.g. `git.librete.ch/public/librenotes:v0.1.0` |
| `LIBRENOTES_BASE_URL` | `https://ln.cloud.librete.ch` |
| `LIBRENOTES_JWT_SECRET` | `openssl rand -base64 48` |
| `LIBRENOTES_SMTP_HOST`, `..._PORT`, `..._USER`, `..._PASS`, `..._FROM` | outbound mail (uberspace per `netcup/.env`) |
## 3. First-time deploy
```sh
ssh netcup 'docker network ls | grep -q edge || docker network create edge'
ssh netcup 'mkdir -p /srv && cd /srv && git clone ssh://tengo@git.librete.ch:41240/public/librenotes.git'
scp librenotes/.env netcup:/srv/librenotes/.env
ssh netcup 'chmod 600 /srv/librenotes/.env'
ssh netcup 'cd /srv/librenotes && docker compose -f compose.yaml -f compose.netcup.yaml pull && docker compose -f compose.yaml -f compose.netcup.yaml up -d'
```
## 4. Update deploy
```sh
deploy librenotes
# Bump LIBRENOTES_IMAGE in /srv/librenotes/.env then:
ssh netcup 'cd /srv/librenotes && docker compose -f compose.yaml -f compose.netcup.yaml pull && docker compose -f compose.yaml -f compose.netcup.yaml up -d'
```
## 5. Smoke / health
```sh
ping ln.cloud.librete.ch
cert ln.cloud.librete.ch
svcs librenotes
logs librenotes librenotes --tail=100
```
UI smoke: signup magic-link email arrives, login succeeds, note creation persists.
## 6. Logs + troubleshooting
| Symptom | First check |
|---------|-------------|
| 502 from edge | container off `edge` net or down |
| SMTP failure | `LIBRENOTES_SMTP_*` correct; firewall to uberspace |
| State loss | bind-mount `./state:/var/lib/librenotes` permissions |
## 7. Rollback
```sh
# Edit LIBRENOTES_IMAGE to prior tag in /srv/librenotes/.env, then:
ssh netcup 'cd /srv/librenotes && docker compose -f compose.yaml -f compose.netcup.yaml pull && docker compose -f compose.yaml -f compose.netcup.yaml up -d'
```
## 8. Stack-specific notes
- **Bind mounts** `./data:/data` (notes payload) and `./state:/var/lib/librenotes` (DB/state) — back up both.
- Multi-tenant by base URL — single image instance per tenant config.
- Image is published from `public/librenotes` CI; never builds on remote.
## 9. Issue tracking
- Deploy issues: `git.librete.ch/public/librenotes/issues`
- Cross-stack: `libretech/netcup`
- After every deploy: append to `netcup/deployments.md`.
+2
View File
@@ -7,6 +7,8 @@ Cloud-native, multi-tenant notes application. A fork of
authentication, per-user data isolation, sync, and PWA support so it can authentication, per-user data isolation, sync, and PWA support so it can
run as a hosted service at [librenot.es](https://librenot.es). run as a hosted service at [librenot.es](https://librenot.es).
> **Deploy / operate on netcup:** see [DEPLOY.md](DEPLOY.md) (canonical netcup runbook).
## Features ## Features
- Markdown notes with bi-directional links (Zettelkasten / evergreen notes) - Markdown notes with bi-directional links (Zettelkasten / evergreen notes)
+1 -1
View File
@@ -70,7 +70,7 @@ docker compose -f compose.yaml -f compose.netcup.yaml up -d
Workflows run on the netcup `act_runner` (see `runner/` stack in Workflows run on the netcup `act_runner` (see `runner/` stack in
the netcup umbrella). Both `ci.yml` and `deploy.yml` declare the netcup umbrella). Both `ci.yml` and `deploy.yml` declare
`container: image: git.librete.ch/libretech/runner-image:v1` — `container: image: git.librete.ch/public/runner-image:v1` —
a bespoke Ubuntu 24.04 image (built and signed by us, hosted on a bespoke Ubuntu 24.04 image (built and signed by us, hosted on
the same Gitea instance) that bundles `git`, `make`, `node`, the same Gitea instance) that bundles `git`, `make`, `node`,
`perl`, `ssh`, and a docker CLI. The image's `runner` user is `perl`, `ssh`, and a docker CLI. The image's `runner` user is
+5
View File
@@ -48,6 +48,10 @@
--bind "$HOME/.claude" "$HOME/.claude" --bind "$HOME/.claude" "$HOME/.claude"
--bind "$HOME/.claude.json" "$HOME/.claude.json" --bind "$HOME/.claude.json" "$HOME/.claude.json"
# Writable: GPG keyring + agent socket (commit signing)
--bind "$HOME/.gnupg" "$HOME/.gnupg"
--bind-try "''${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/gnupg" "''${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/gnupg"
--ro-bind "$HOME/.gitconfig" "$HOME/.gitconfig" --ro-bind "$HOME/.gitconfig" "$HOME/.gitconfig"
--ro-bind "$HOME/.ssh" "$HOME/.ssh" --ro-bind "$HOME/.ssh" "$HOME/.ssh"
--setenv GIT_SSH_COMMAND "ssh -F ~/.ssh/config" --setenv GIT_SSH_COMMAND "ssh -F ~/.ssh/config"
@@ -61,6 +65,7 @@
--setenv PATH "$PATH" --setenv PATH "$PATH"
--setenv TERM "''${TERM:-xterm}" --setenv TERM "''${TERM:-xterm}"
--setenv SANDBOX_ACTIVE "1" --setenv SANDBOX_ACTIVE "1"
--setenv GPG_TTY "''${GPG_TTY:-}"
--chdir "$PROJECT_DIR" --chdir "$PROJECT_DIR"
) )