From cb95cef763010b399c19345f72a2c0e8d8902813 Mon Sep 17 00:00:00 2001 From: claude Date: Fri, 24 Jul 2026 17:12:34 +0700 Subject: [PATCH] docs: add DEPLOY.md step-by-step (Traefik + Bromite) Co-Authored-By: Claude Opus 4.8 --- DEPLOY.md | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 DEPLOY.md diff --git a/DEPLOY.md b/DEPLOY.md new file mode 100644 index 0000000..83fb70d --- /dev/null +++ b/DEPLOY.md @@ -0,0 +1,174 @@ +# Deployment + +Step-by-step for the backend (Docker + Traefik) and the Bromite userscript. +Assumes you already run Traefik in Docker with a working HTTPS entrypoint and an +ACME/cert resolver, and control a domain. + +--- + +## 0. Prerequisites + +- Docker + Docker Compose on the server. +- A Traefik instance watching a Docker network (default name assumed: `proxy`). +- DNS: an `A`/`AAAA` record for `manga-api.` pointing at the server. +- The repo copied to the server, e.g. `/opt/mangabm/` (needs `backend/`, + `docker-compose.yml`, `docker-compose.prod.yml`, `.env.example`). + +Confirm the Traefik network exists (create if not): + +```bash +docker network ls | grep proxy || docker network create proxy +``` + +--- + +## 1. Configure `.env` + +```bash +cd /opt/mangabm +cp .env.example .env +``` + +Edit `.env`: + +```ini +# Required — long random secret, also goes in the userscript. +API_TOKEN= + +# CORS allowlist — leave as-is unless a site changes hostname. +ALLOWED_ORIGINS=https://asuracomic.net,https://asurascans.com,https://demonicscans.org + +# Required for the Traefik override. +MANGA_API_HOST=manga-api.yourdomain.com + +# Only if your Traefik setup differs from these defaults: +# PROXY_NETWORK=proxy +# TRAEFIK_ENTRYPOINT=websecure +# TRAEFIK_CERTRESOLVER=le +``` + +Generate + insert the token in one line: + +```bash +sed -i "s|^API_TOKEN=.*|API_TOKEN=$(openssl rand -hex 32)|" .env +grep -E '^API_TOKEN=' .env # copy this — the userscript needs the same value +``` + +> Match `TRAEFIK_ENTRYPOINT` / `TRAEFIK_CERTRESOLVER` to your Traefik's actual +> names (check your Traefik static config — common alternatives: `https`, +> `myresolver`, `cloudflare`). Wrong names = no certificate issued. + +--- + +## 2. Build + start + +```bash +docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build +``` + +This merges the base file (build/image/env/volume) with the prod override +(no host port, Traefik network + router labels). Always pass **both** `-f` +flags — the prod file is not standalone. + +Check it's up and healthy: + +```bash +docker compose -f docker-compose.yml -f docker-compose.prod.yml ps +docker logs manga-api --tail 20 # expect: "listening on :8080 ..." +``` + +--- + +## 3. Verify over HTTPS + +Give Traefik a few seconds to issue the cert, then: + +```bash +# Health (no auth) — must be valid TLS, no cert warning. +curl -s https://manga-api.yourdomain.com/healthz # -> ok + +# Auth enforced. +curl -s -o /dev/null -w '%{http_code}\n' \ + https://manga-api.yourdomain.com/bookmarks # -> 401 + +TOKEN=$(grep -E '^API_TOKEN=' .env | cut -d= -f2) +curl -s -H "Authorization: Bearer $TOKEN" \ + https://manga-api.yourdomain.com/bookmarks # -> [] + +# CORS preflight from a real site origin. +curl -s -i -X OPTIONS \ + -H 'Origin: https://asurascans.com' \ + -H 'Access-Control-Request-Method: PUT' \ + https://manga-api.yourdomain.com/bookmarks/x | grep -i access-control +# -> Access-Control-Allow-Origin: https://asurascans.com (+ Methods/Headers) +``` + +All four must pass. Valid TLS is non-negotiable — the manga sites are HTTPS, so +a bad cert makes the browser block the userscript's `fetch()` (mixed content). + +--- + +## 4. Configure the userscript + +Edit the config block at the top of `userscript/manga-bookmark.user.js`: + +```js +const API_BASE = "https://manga-api.yourdomain.com"; // no trailing slash +const API_TOKEN = ""; +``` + +The token sits in the userscript's isolated world — the manga sites' JS can't +read it. + +--- + +## 5. Install on Bromite + +1. Bromite → **Settings → User scripts** → enable (accept the permission prompt). +2. Put the edited `manga-bookmark.user.js` on the device (save the file, or open + its raw URL). Bromite detects `.user.js` and offers to install. +3. Confirm install — the `@match` list covers both sites. +4. Open a series on asurascans.com or demonicscans.org → a 📑 button appears + bottom-right → tap → **+ Bookmark this**. + +Optional desktop test: the script is `GM_*`-free, so the same file installs in +Tampermonkey/Violentmonkey for quick checks before going mobile. + +--- + +## 6. Smoke-test the full loop + +1. Bookmark a series on Asura. +2. `curl -s -H "Authorization: Bearer $TOKEN" https://manga-api.yourdomain.com/bookmarks` + on the server — the series should appear. +3. Open a chapter of that series — reopen the panel; last-read updates to that + chapter (auto, never regresses on older chapters). +4. Open Demonic, open the panel — the Asura bookmark shows there too (shared + store, cross-site unified list). + +--- + +## Updating + +Pull new code, then rebuild: + +```bash +docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build +``` + +SQLite data persists in the named volume `bookmarks-data` across rebuilds. + +--- + +## Troubleshooting + +| Symptom | Likely cause / fix | +|---------|--------------------| +| No cert / TLS error at the domain | `TRAEFIK_ENTRYPOINT` or `TRAEFIK_CERTRESOLVER` name wrong; or DNS not resolving yet. Check `docker logs `. | +| 404 from Traefik | Service not on the `proxy` network, or `MANGA_API_HOST` mismatch. Confirm `docker network inspect proxy` lists `manga-api`. | +| `fetch` fails in the userscript, `curl` works | Origin missing from `ALLOWED_ORIGINS`, or mixed content (backend not HTTPS). | +| 401 with the right token | Trailing space/newline in `API_TOKEN`; regenerate and restart. | +| Panel button absent | URL didn't match an adapter, or user scripts disabled in Bromite. | +| `compose ... config` errors about `API_TOKEN` | Run compose from the dir with `.env`, or export the vars. | + +Backend config reference and endpoint list: see `README.md`.