# 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