warmbox/docs/deploy-ci-cd.md
Jonny Nguyen ed3ec86025 Add Woodpecker CI/CD pipeline configuration and new chart components
Introduce a Woodpecker CI/CD pipeline in `.woodpecker.yml` for automated deployment on pushes to the main branch. Add new components for visualizing campaign performance, including `DailyPerformanceChart`, `InboxPlacementChart`, and `InboxVsSpamChart`, to enhance the Campaign Detail page. Update `WarmupPlanChart` to include additional metrics and improve tooltip information. Enhance utility functions for chart data formatting and daily statistics mapping.
2026-06-26 14:23:18 -07:00

183 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CI/CD with Woodpecker (Forgejo)
Automate deploys to your home server when you push to **`main`** on [Forgejo](https://git.jonnyn.com/).
```text
git push main → Forgejo webhook → Woodpecker → verify (build/test) → deploy.sh → docker compose
```
Woodpecker is the right choice here — it runs on your server next to the app, can use the Docker socket, and integrates natively with Forgejo. GitHub Actions would require SSH secrets and extra wiring for a self-hosted Forgejo repo.
---
## Overview
| Piece | Role |
|-------|------|
| **Forgejo** (`git.jonnyn.com`) | Git remote, sends webhooks on push |
| **Woodpecker** | Runs `.woodpecker.yml` pipeline |
| **`scripts/deploy.sh`** | `git pull` + `docker compose down` + `up --build` on server |
| **`/srv/docker-configs/warmbox`** | Live deploy directory (must stay a git clone) |
---
## 1. One-time server setup
### Deploy directory is a git clone
Your live app should already be:
```bash
cd /srv/docker-configs/warmbox
git remote -v
# origin https://git.jonnyn.com/you/warmbox.git (or SSH URL)
```
If you copied files without git, re-clone:
```bash
mv /srv/docker-configs/warmbox /srv/docker-configs/warmbox.bak
git clone https://git.jonnyn.com/YOU/warmbox.git /srv/docker-configs/warmbox
cp /srv/docker-configs/warmbox.bak/.env /srv/docker-configs/warmbox/
# restore warmbox-data volume is unchanged — docker volume persists
```
Ensure `git pull` works without a password (deploy key or credential helper):
```bash
cd /srv/docker-configs/warmbox
git pull origin main
```
### Make deploy script executable
```bash
chmod +x /srv/docker-configs/warmbox/scripts/deploy.sh
```
### Woodpecker agent: allow Docker socket + deploy path
The **deploy** step mounts:
- `/var/run/docker.sock` — run `docker compose` from CI
- `/srv/docker-configs/warmbox` — your live checkout
In your **Woodpecker agent** container environment (docker-compose or stack config), allow pipeline volumes. Example:
```yaml
# woodpecker-agent service (adjust to your stack)
environment:
WOODPECKER_VOLUMES_ALLOWED: /var/run/docker.sock,/srv/docker-configs/warmbox
```
Alternatively, in the Woodpecker UI → your **warmbox** repository → enable **Trusted** (allows volume mounts for that repo).
The agent also needs the Docker socket mounted (you likely already have this):
```yaml
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
If your deploy path differs from `/srv/docker-configs/warmbox`, edit:
- `.woodpecker.yml``deploy` step volume path
- Or set a symlink
---
## 2. Connect Forgejo to Woodpecker
These steps are in the Woodpecker UI (URL depends on your install, often `https://ci.jonnyn.com` or similar).
1. **Forgejo OAuth app** (Forgejo → Settings → Applications → Create OAuth2 Application)
- Redirect URI: `https://<woodpecker-host>/authorize`
2. **Woodpecker server** — add Forgejo host `https://git.jonnyn.com` with OAuth client ID/secret
3. **Login to Woodpecker** with Forgejo account
4. **Activate** the `warmbox` repository
5. Enable **Trusted** on the repo (if not using `WOODPECKER_VOLUMES_ALLOWED`)
6. Confirm webhook exists on Forgejo (repo → Settings → Webhooks)
---
## 3. Pipeline file (in repo)
Already included at repo root:
**`.woodpecker.yml`**
1. **`verify`** — `npm ci`, `prisma generate`, `build`, `test` (runs in Woodpecker workspace clone)
2. **`deploy`** — runs `scripts/deploy.sh` in `/srv/docker-configs/warmbox`
Push this file to `main`, then Woodpecker picks it up automatically.
---
## 4. First CI deploy
```bash
# On your Mac
git add .woodpecker.yml scripts/deploy.sh docs/deploy-ci-cd.md
git commit -m "Add Woodpecker CI/CD deploy pipeline"
git push origin main
```
Watch the pipeline in Woodpecker UI. On success:
```bash
curl -s https://warmbox.jonnyn.com/health
```
---
## 5. Manual deploy (without CI)
```bash
ssh burke
cd /srv/docker-configs/warmbox
./scripts/deploy.sh
```
---
## 6. Customize deploy path
If not using `/srv/docker-configs/warmbox`, edit `.woodpecker.yml`:
```yaml
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /your/path/warmbox:/deploy
```
---
## Troubleshooting
| Symptom | Fix |
|---------|-----|
| Pipeline not triggered | Check Forgejo webhook deliveries; repo activated in Woodpecker |
| `volume not allowed` | Trusted repo or `WOODPECKER_VOLUMES_ALLOWED` on agent |
| `permission denied` docker.sock | Agent container must mount `/var/run/docker.sock` |
| `git fetch` fails in deploy | Fix git credentials in `/srv/docker-configs/warmbox` |
| `.env missing` | Create `.env` on server (never commit it); CI does not copy `.env` |
| `verify` fails | Fix tests locally; push again |
| `deploy` health check fails | `docker compose logs warmbox` on server |
| Wrong branch | Default is `main`; set `DEPLOY_BRANCH` in deploy step if needed |
### Brief downtime
`docker compose down` stops Warmbox for the length of the rebuild (usually 13 minutes). Cron jobs pause during that window — acceptable for homelab deploys.
### Secrets
- **Do not** commit `.env` — stays only on server
- Woodpecker does not need `ENCRYPTION_KEY` or `API_KEY` for deploy (only `verify` uses a dummy key)
---
## Optional: deploy only (skip tests)
For faster iteration, comment out the `verify` step and remove `depends_on` from `deploy` in `.woodpecker.yml`. Not recommended for `main` long term.
See also [deploy-ubuntu-docker.md](./deploy-ubuntu-docker.md).