# 2026-04-22 Memory

## Gitea Actions CI/CD Pipeline - Successfully Debugged & Deployed

### Final Status: ✅ Working (Run 13 succeeded)

**What was accomplished:** Fully automated CI/CD pipeline for `app01` repo via Gitea Actions — push to main triggers build + deploy + health check.

### Key Fixes Applied (in order)

1. **post-receive hook interference**: Custom post-receive hook at `/data/git/repositories/gch3n/app01.git/hooks/post-receive` was interfering with Gitea's internal Actions event trigger. Removed it (renamed to `.disabled`), which allowed Gitea's built-in mechanism to fire Actions on push.

2. **Runner execution mode**: Container-based runner (`act-runner-app01`) couldn't run Docker inside Alpine Linux container (`docker: not found`). Switched to **host-mode runner** running directly on the server at `/home/nplx/act_runner_host/`.

3. **Checkout without Node.js**: `actions/checkout` requires Node.js which wasn't available in the runner environment. Replaced with `git archive` command to export code to a temp directory for building.

4. **Missing frontend copy in Dockerfile**: Dockerfile only had `COPY backend ./backend` but no `COPY frontend ./frontend`, causing runtime crash (`Directory '/app/frontend' does not exist`). Added the missing COPY directive.

### Infrastructure Details

- **Server**: `49.235.172.252:11022` (user `nplx`)
- **Runner**: `tencent-app01-host`, host-mode, working dir `/home/nplx/act_runner_host/`
- **Runner config**: `/home/nplx/act_runner_host/config.yaml` (fetch_interval: 2s, capacity: 1)
- **Runner labels**: `self-hosted:host`
- **Workflow file**: `.gitea/workflows/deploy.yml` in repo `gch3n/app01`
- **App endpoint**: `https://app.gch3n.online/health` → `{"status":"ok"}`
- **Actions page**: `https://git.gch3n.online/gch3n/app01/actions`
- **Container**: `app01-blue` on port `127.0.0.1:8001`, proxied by Caddy to `app.gch3n.online`

### Workflow Design (deploy.yml)

```yaml
on: push
runs-on: self-hosted
steps:
  1. git archive → /tmp/app01-build/
  2. docker build -t app01:latest /tmp/app01-build/
  3. Stop old container, remove it
  4. docker run -d --name app01-blue -p 127.0.0.1:8001:8001 app01:latest
  5. Health check curl loop (up to 30s)
  6. Cleanup /tmp/app01-build/
```

### Known Remaining Issues

- Gitea Actions runs 1-12 are failed/cancelled (historical, cosmetic only)
- Previous cron-based deploy (`/home/nplx/ci/check-and-deploy-app01.sh`) still exists but is now redundant — the Gitea Actions workflow replaces it
- Previous container runner `act-runner-app01` was stopped but may still exist

### Lessons Learned

- Gitea Actions event trigger depends on Gitea's internal post-receive processing; custom hooks in the same repo can interfere
- Container-based runners can't run Docker unless Docker-in-Docker is properly set up (socket mount + compatible OS)
- `actions/checkout` is a JavaScript action requiring Node.js — not available in bare Alpine/host environments
- Always verify Dockerfile COPY directives match actual project structure
