Files
CASAN/AINative_OKR_CASAN5/.gitea/vps-setup-runbook.md
T
thanhnvandClaude Sonnet 4.6 9892e82221 feat(wave5): CI/CD pipeline + Vault KMS + OKR deploy to port 80/3001
Infrastructure (H3 CI gate, H5 KMS):
- Gitea Actions enabled (GITEA__actions__ENABLED=true)
- act_runner: Docker-outside-of-Docker for deploy job
- Vault Transit RSA-2048 signing keys (casan-audit-key, casan-policy-key)

Vault KMS scripts (H5 governance):
- .specify/scripts/bash/vault-kms.sh — sign/verify/pubkey/ensure-key
- .specify/scripts/bash/sign-audit-head.sh — sign audit chain via Vault
- Updated sign-policy-bundle.sh — Vault path + local fallback
- Updated security-gate.sh — KMS gate added (PASS=11 FAIL=0)

OKR app deployment (port 80/3001):
- Dockerfile.backend — node:22-slim (node:sqlite requires Node 22)
- Dockerfile.frontend — node:20-alpine build + nginx:alpine runtime
- nginx/nginx.conf — React SPA + /api/v1/* proxy to okr-backend:3001
- backend/entrypoint.sh — auto init DB on first run + seed
- .dockerignore

CI pipeline (.gitea/workflows/ci.yml):
- Job 1: Vitest frontend tests (H3)
- Job 2: CASAN security gate + Vault KMS signing (H4/H5)
- Job 3: Deploy OKR → port 80 (runs on push to main after tests pass)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 12:55:17 +09:00

5.4 KiB

VPS CI/CD Setup Runbook

Oracle Cloud Tokyo — 161.33.139.73

Architecture

VPS (Ubuntu 24.04, 1 GB RAM)
├── /opt/gitea/
│   ├── docker-compose.yml     ← add act-runner service here
│   ├── .env                   ← add RUNNER_REGISTRATION_TOKEN here
│   ├── act-runner-config.yaml ← copy from .gitea/act-runner-config.yaml
│   └── gitea-data/

Step 1 — Enable Gitea Actions

SSH into the VPS:

ssh ubuntu@161.33.139.73

Add the Actions env variable to the Gitea service in docker-compose.yml:

# In the gitea service environment section, add:
- GITEA__actions__ENABLED=true

Restart Gitea:

cd /opt/gitea
docker compose restart gitea

Verify: Open http://161.33.139.73:3000 → Site Administration → Runners You should see "Runners" menu item (confirming Actions is enabled).


Step 2 — Get the Runner Registration Token

  1. Log into Gitea as admin: http://161.33.139.73:3000
  2. Go to: Site Administration (⚙) → Runners → "Create new runner"
  3. Copy the Registration Token shown (looks like: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)

Step 3 — Copy act_runner config to VPS

From your local machine:

scp AINative_OKR_CASAN5/.gitea/act-runner-config.yaml \
    ubuntu@161.33.139.73:/opt/gitea/act-runner-config.yaml

Step 4 — Add RUNNER_REGISTRATION_TOKEN to /opt/gitea/.env

On the VPS:

# Replace <TOKEN> with the token copied in Step 2
echo "RUNNER_REGISTRATION_TOKEN=<TOKEN>" >> /opt/gitea/.env

Step 5 — Add act_runner service to docker-compose.yml

Edit /opt/gitea/docker-compose.yml and add the act-runner service.

Typical Gitea docker-compose.yml after changes:

version: "3"

networks:
  gitea:
    external: false

volumes:
  gitea-data:
  act-runner-data:

services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    restart: always
    networks:
      - gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__actions__ENABLED=true        # ← ADD THIS LINE
    ports:
      - "3000:3000"
      - "2222:22"
    volumes:
      - ./gitea-data:/data

  act-runner:
    image: gitea/act_runner:latest
    container_name: act-runner
    restart: unless-stopped
    networks:
      - gitea                                # same network as gitea
    depends_on:
      - gitea
    environment:
      - GITEA_INSTANCE_URL=http://gitea:3000 # internal Docker hostname
      - GITEA_RUNNER_REGISTRATION_TOKEN=${RUNNER_REGISTRATION_TOKEN}
      - GITEA_RUNNER_NAME=casan-runner-oracle
      - CONFIG_FILE=/config/act-runner-config.yaml
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock   # DinD for job containers
      - ./act-runner-config.yaml:/config/act-runner-config.yaml:ro
      - act-runner-data:/data

If your current docker-compose.yml already has a networks: or volumes: section, merge them — don't add duplicate top-level keys.


Step 6 — Start act_runner

cd /opt/gitea
docker compose pull act-runner
docker compose up -d act-runner

Check registration:

docker compose logs -f act-runner
# Look for: "runner registered" or "connected to Gitea"

In Gitea Web UI: Site Administration → Runners → you should see "casan-runner-oracle" with status Online.


Step 7 — Pull the catthehacker runner image (one-time)

The first CI run will pull catthehacker/ubuntu:act-22.04 (~2 GB). Pre-pull to avoid timeout:

docker pull catthehacker/ubuntu:act-22.04

This takes ~2-5 minutes depending on internet speed.


Step 8 — Create repo in Gitea and push the project

On the VPS (or via Gitea web UI), create a new repository:

On your local machine:

cd Output_CASAN5_REFINED/AINative_OKR_CASAN5

# Add Gitea as remote
git remote add gitea ssh://git@161.33.139.73:2222/<YOUR_USER>/casan5.git

# Push
git push gitea main

Step 9 — Verify CI triggered

After push, go to: http://161.33.139.73:3000/<YOUR_USER>/casan5/actions

You should see a workflow run in progress. Click it to see live logs.

Expected final result:

✅ Frontend Tests (H3 gate)        — 16/16 PASS
✅ CASAN Security Gate (H4/H5/H2)  — PASS=7 SKIP=1 FAIL=0

SKIP=1 is expected (Ollama is not on the CI server — this is the model-router/red-team group). The gate exits 0 because FAIL=0.


Memory Monitoring

# Watch RAM usage while CI runs
watch -n 2 'free -h && docker stats --no-stream'

If OOM occurs, reduce the job container memory limit in act-runner-config.yaml or add swap:

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Troubleshooting

Symptom Fix
Runner shows "Offline" Check docker compose logs act-runner; verify token is correct
GITEA_INSTANCE_URL unreachable Ensure gitea and act-runner are on the same Docker network
Job stuck "Waiting for runner" Runner is busy (capacity=1); wait or increase capacity
python: command not found The workflow's "Install test tools" step installs python-is-python3
OOM during npm ci Switch to npm ci -w frontend (already done in workflow) or add swap
catthehacker/ubuntu:act-22.04 pull fails Run docker pull manually on VPS first