Updates
This commit is contained in:
42
README.md
42
README.md
@@ -27,13 +27,21 @@ Designed for Docker/Portainer with Traefik. Uses **pnpm** everywhere; no Tailwin
|
||||
|
||||
## Deploy (Portainer)
|
||||
|
||||
1. In Portainer: **Stacks → Add stack**.
|
||||
2. Use the repo root `docker-compose.yml` (clone repo or paste content).
|
||||
3. Set required env vars (at least):
|
||||
- `DB_PASSWORD` — Postgres password for Kutt
|
||||
- `JWT_SECRET` — Kutt JWT secret (generate a random string)
|
||||
- `KUTT_API_KEY` — Kutt API key for qr-api (after creating it in Kutt UI)
|
||||
4. Deploy. No ports are exposed; Traefik handles ingress.
|
||||
**Option A — Registry + webhook (recommended for CI/CD)**
|
||||
Use prebuilt images and redeploy on push via webhook:
|
||||
|
||||
1. In Portainer: **Stacks → Add stack**. Use **docker-compose.portainer.yml** (paste or pull from repo).
|
||||
2. Set env vars:
|
||||
- **Required:** `DB_PASSWORD`, `JWT_SECRET`
|
||||
- **Optional:** `REGISTRY` (default `git.mifi.dev`), `IMAGE_TAG` (default `latest`), `KUTT_API_KEY`
|
||||
3. Deploy. Then in the stack: **Webhooks** → add webhook. Copy the URL and add it as secret `portainer_webhook_url` in Woodpecker (repo secrets). On each push to `main`, the pipeline builds multi-arch images, pushes to the registry, and triggers this webhook to redeploy the stack.
|
||||
|
||||
**Option B — Build from source**
|
||||
For one-off or local deploys without CI:
|
||||
|
||||
1. In Portainer: **Stacks → Add stack**. Use **docker-compose.yml** (builds qr-api and qr-web from Dockerfiles).
|
||||
2. Set required env vars: `DB_PASSWORD`, `JWT_SECRET`, and optionally `KUTT_API_KEY`.
|
||||
3. Deploy. No ports are exposed; Traefik handles ingress.
|
||||
|
||||
## Env vars and .env.example
|
||||
|
||||
@@ -71,10 +79,12 @@ Ports 3000 and 8080 are forwarded by the devcontainer.
|
||||
|
||||
## Repo structure
|
||||
|
||||
- `docker-compose.yml` — Root compose for Portainer (Kutt + qr-api + qr-web, Traefik labels).
|
||||
- `docker-compose.yml` — Compose that builds qr-api and qr-web from source (local or one-off Portainer).
|
||||
- `docker-compose.portainer.yml` — Compose that uses registry images; for Portainer + CI/CD webhook redeploys.
|
||||
- `qr-api/` — Node/TS Express API: SQLite projects, uploads, shorten proxy to Kutt. Not exposed via Traefik.
|
||||
- `qr-web/` — Next.js (App Router) + Mantine QR designer; proxies all API calls to qr-api server-side.
|
||||
- `.woodpecker.yml` — CI: lint-and-test on PR/push to main; manual deploy with `depends_on` lint-and-test.
|
||||
- `.woodpecker/ci.yml` — CI: install, format check, lint, test, build on PR/push/tag.
|
||||
- `.woodpecker/deploy.yml` — Deploy: build qr-api and qr-web (multi-arch amd64/arm64), push to registry, trigger Portainer webhook. Runs on push/tag to `main` after CI.
|
||||
- `.devcontainer/` — Devcontainer for local dev.
|
||||
|
||||
## Security
|
||||
@@ -87,18 +97,20 @@ Ports 3000 and 8080 are forwarded by the devcontainer.
|
||||
|
||||
The QR designer uses **qr-code-styling** for dots, corners, colors, and error correction. The optional **qr-border-plugin** (from [lefe.dev marketplace](https://lefe.dev/marketplace/qr-border-plugin)) adds border styling but depends on `@lefe-dev/lefe-verify-license`, which may involve licensing/watermark behavior. This stack uses qr-code-styling only by default; you can add qr-border-plugin from npm or GitHub if desired and document any license terms.
|
||||
|
||||
## Switching to prebuilt images (CI/CD)
|
||||
## CI/CD (Woodpecker)
|
||||
|
||||
In `.woodpecker.yml`, the deploy pipeline has placeholder steps. To use prebuilt images:
|
||||
- **CI** (`.woodpecker/ci.yml`): on every PR/push to `main`/tag — `pnpm install --frozen-lockfile`, format check, lint, test, build. Requires `pnpm-lock.yaml` committed.
|
||||
- **Deploy** (`.woodpecker/deploy.yml`): on push/tag to `main` after CI — builds `shorty-qr-api` and `shorty-qr-web` as multi-arch (linux/amd64, linux/arm64), pushes to `git.mifi.dev/mifi-holdings/shorty-qr-api` and `shorty-qr-web`, then POSTs the Portainer webhook to redeploy the stack.
|
||||
|
||||
1. Build `qr-api` and `qr-web` in CI (e.g. `docker build -t $REGISTRY/shorty/qr-api:$CI_COMMIT_SHA ./qr-api`).
|
||||
2. Push to your registry; set `REGISTRY` and `IMAGE_PREFIX` (or equivalent) as secrets.
|
||||
3. In `docker-compose.yml`, replace `build: context: ./qr-api` with `image: $REGISTRY/shorty/qr-api:$TAG` (use env or a compose override for TAG).
|
||||
**Secrets** (repo or org): `gitea_registry_username`, `gitea_package_token`, `portainer_webhook_url`.
|
||||
|
||||
**Local build/push test (before committing):**
|
||||
From repo root: build with buildx and push to your registry, or run `docker compose -f docker-compose.yml build` to verify builds.
|
||||
|
||||
## Code style and tooling
|
||||
|
||||
- **TypeScript** everywhere.
|
||||
- **Prettier:** tabWidth 4, spaces (no tabs), singleQuote, trailingComma all, semi.
|
||||
- **ESLint** for TS/React/Next in qr-web; shared root config for qr-api.
|
||||
- **pnpm** only; `pnpm-lock.yaml` is the single lockfile (no package-lock.json or yarn.lock).
|
||||
- **pnpm** only; `pnpm-lock.yaml` is committed and is the single lockfile (no package-lock.json or yarn.lock).
|
||||
- **Tests:** Vitest (qr-api and qr-web).
|
||||
|
||||
Reference in New Issue
Block a user