diff --git a/docs/DEVOPS_RUNNER_SETUP.md b/docs/DEVOPS_RUNNER_SETUP.md new file mode 100644 index 0000000..57c2ba8 --- /dev/null +++ b/docs/DEVOPS_RUNNER_SETUP.md @@ -0,0 +1,256 @@ +# DevOps Agent Prompt: Forgejo Runner Setup + +## Context + +We have a Python/FastAPI dashboard application called **vault-dash** that needs CI/CD via Forgejo Actions. The repository is hosted at: + +``` +ssh://git@10.100.0.2:2222/bu5hm4nn/vault-dash.git +``` + +The project uses: +- **Python 3.11/3.12** with FastAPI + NiceGUI +- **Docker** for containerization +- **Forgejo Actions** for CI/CD (workflows already exist in `.forgejo/workflows/`) + +## Task + +Set up a Forgejo runner that can: +1. Execute CI workflows (lint, test, type-check) +2. Build Docker images +3. Deploy to the production VPS over SSH + +## Infrastructure + +### Forgejo Server +- **URL**: `http://10.100.0.2:3000` (or appropriate internal URL) +- **Git**: `ssh://git@10.100.0.2:2222` + +### Target Deployment Server (VPS) +- **Access**: VPN-only +- **Requirements**: Docker + Docker Compose plugin installed + +## Steps to Complete + +### 1. Verify Forgejo Actions is Enabled + +Check that Actions are enabled in the Forgejo repository: +- Go to repository Settings → Actions +- Ensure "Enable Actions" is checked + +### 2. Create Forgejo Runner Token + +On the Forgejo server: + +```bash +# Option A: Via CLI +forgejo actions generate-runner-token + +# Option B: Via API +curl -X POST http://10.100.0.2:3000/api/v1/repos/bu5hm4nn/vault-dash/actions/runners \ + -H "Authorization: token " +``` + +Save the generated token for runner registration. + +### 3. Install Forgejo Runner + +On the runner host (can be Forgejo server itself or separate machine): + +```bash +# Download forgejo-runner (adjust version as needed) +VERSION=3.5.1 +wget https://code.forgejo.org/forgejo/runner/releases/download/v${VERSION}/forgejo-runner-${VERSION}-linux-amd64 +chmod +x forgejo-runner-${VERSION}-linux-amd64 +sudo mv forgejo-runner-${VERSION}-linux-amd64 /usr/local/bin/forgejo-runner + +# Create runner user +sudo useradd -r -s /bin/false forgejo-runner +sudo mkdir -p /var/lib/forgejo-runner +sudo chown forgejo-runner:forgejo-runner /var/lib/forgejo-runner +``` + +### 4. Register the Runner + +```bash +# Run as forgejo-runner user +sudo -u forgejo-runner forgejo-runner register \ + --instance-addr http://10.100.0.2:3000 \ + --token \ + --runner-name "vault-dash-runner" \ + --labels "docker,linux,ubuntu" + +# Create config file at /var/lib/forgejo-runner/.runner +``` + +### 5. Configure for Docker-in-Docker + +The CI workflows need to build Docker images. Create/edit the runner config: + +```yaml +# /var/lib/forgejo-runner/config.yaml + +runner: + file: /var/lib/forgejo-runner/.runner + capacity: 2 + labels: + - "docker" + - "linux" + - "ubuntu" + +container: + network: "" + options: "" + valid_volumes: + - /var/lib/forgejo-runner + - /var/run/docker.sock + force_pull: false +``` + +Enable Docker socket access: + +```bash +# Give runner access to Docker +sudo usermod -aG docker forgejo-runner + +# Create systemd service +sudo cat > /etc/systemd/system/forgejo-runner.service << 'EOF' +[Unit] +Description=Forgejo Runner +After=network.target docker.service +Requires=docker.service + +[Service] +Type=simple +User=forgejo-runner +WorkingDirectory=/var/lib/forgejo-runner +ExecStart=/usr/local/bin/forgejo-runner daemon +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + +sudo systemctl daemon-reload +sudo systemctl enable forgejo-runner +sudo systemctl start forgejo-runner +``` + +### 6. Verify Runner is Connected + +```bash +# Check runner status +sudo systemctl status forgejo-runner + +# Check runner logs +journalctl -u forgejo-runner -f + +# Verify in Forgejo UI +# Go to: Repository → Settings → Actions → Runners +# Should show "vault-dash-runner" as online +``` + +### 7. Configure Deployment Secrets + +In Forgejo repository, go to **Settings → Secrets and variables → Actions** and add: + +| Secret Name | Description | Example Value | +|-------------|-------------|---------------| +| `DEPLOY_SSH_PRIVATE_KEY` | SSH key for VPS access | `-----BEGIN OPENSSH PRIVATE KEY-----...` | +| `DEPLOY_HOST` | VPS IP/hostname | `10.100.0.5` | +| `DEPLOY_USER` | Deploy user on VPS | `deploy` | +| `NICEGUI_STORAGE_SECRET` | Random 32+ char secret | `a1b2c3d4e5f6...` | + +### 8. Create Deploy User on VPS + +On the target deployment server: + +```bash +# Create deploy user +sudo useradd -m -s /bin/bash deploy +sudo usermod -aG docker deploy + +# Create deployment directory +sudo mkdir -p /opt/vault-dash +sudo chown deploy:deploy /opt/vault-dash + +# Add runner's public key +sudo mkdir -p /home/deploy/.ssh +echo "" | sudo tee /home/deploy/.ssh/authorized_keys +sudo chmod 700 /home/deploy/.ssh +sudo chmod 600 /home/deploy/.ssh/authorized_keys +sudo chown -R deploy:deploy /home/deploy/.ssh +``` + +### 9. Test the Pipeline + +Trigger a test run: + +- Push a commit to the `main` branch, OR +- Go to Actions tab → Select "CI" workflow → "Run workflow" + +Verify all jobs pass: +- ✅ lint (ruff + black) +- ✅ test (pytest) +- ✅ type-check (mypy) +- ✅ build (Docker image) +- ✅ security-scan (Trivy) +- ✅ deploy (only on main branch) + +## Verification Checklist + +- [ ] Forgejo Actions enabled on repository +- [ ] Runner registered and showing as "online" +- [ ] Runner has Docker access (can build images) +- [ ] Secrets configured in repository settings +- [ ] Deploy user created on VPS with Docker access +- [ ] SSH key authentication works from runner to VPS +- [ ] CI workflow passes on test commit +- [ ] Deploy workflow can reach VPS and run docker commands + +## Troubleshooting + +### Runner can't connect to Forgejo +- Check network connectivity: `curl http://10.100.0.2:3000` +- Verify token hasn't expired (tokens are single-use) + +### Docker build fails +- Ensure runner user is in `docker` group +- Check Docker socket permissions: `ls -la /var/run/docker.sock` +- Restart Docker daemon: `sudo systemctl restart docker` + +### Deploy job fails to SSH +- Test SSH manually: `ssh -i deploy@` +- Check key permissions: `chmod 600 ~/.ssh/id_ed25519` +- Verify host is in known_hosts or `StrictHostKeyChecking no` + +### Health check fails after deploy +- Check container logs: `docker logs vault-dash` +- Verify port 8000 is accessible: `curl http://127.0.0.1:8000/health` +- Check Docker network connectivity + +## Files Referenced + +- `.forgejo/workflows/ci.yaml` - Lint, test, type-check +- `.forgejo/workflows/deploy.yaml` - Build, scan, deploy +- `scripts/deploy.sh` - Deployment script +- `Dockerfile` - Container build +- `docker-compose.deploy.yml` - Production compose file + +## Success Criteria + +After completion: +1. Pushing to `main` triggers CI pipeline automatically +2. All CI checks pass (lint, test, type-check) +3. Docker image builds and pushes to registry +4. Image deploys to VPS via SSH +5. Application accessible at `http://:8000/health` + +--- + +Please complete these steps and report: +1. Runner registration result (token created, runner online) +2. Secrets configured (list of secret names, not values) +3. Test pipeline run URL and result +4. Any issues encountered during setup \ No newline at end of file