# 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:///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 1–3 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).