# CI/CD Setup — Deploy via Gitea Webhook The site auto-rebuilds on every push to `main` via a Gitea **webhook** (no Actions runner, no `.gitea/workflows/`, no act_runner required). ## How it works ``` git push origin main │ ▼ Gitea Webhook (Gitea built-in, not Gitea Actions) │ POST Content-Type: application/json ▼ http://110.164.146.47:3000/api/deploy/ │ HTTP 200 "Deploying..." ▼ EasyPanel pulls repo, builds with Dockerfile, redeploys ``` ## One-time webhook setup In `https://git.moreminimore.com/kunthawat/dealplustech-astroreal/settings/hooks`: 1. Click **Add Webhook → Gitea** 2. Fill in: - **Payload URL**: `http://110.164.146.47:3000/api/deploy/772d2c3a4a7d8671657c947c059bc1cdc64bd816efb7fbe2` - **HTTP Method**: `POST` - **Content Type**: `application/json` - **Events**: **Push events** - **Active**: ✓ - **Branch filter**: leave empty (or `main` to restrict) 3. Click **Add Webhook** 4. Test: click the webhook row → **Test Delivery** → **Push events** → confirm **Last Response** is HTTP 200. Done. From now on every push to main redeploys automatically. ## EasyPanel service requirements The service on the panel side (`project=customerwebsite`, `service=dealplustech-astro`) must be: - **Type: `app`** - **Source: Git**, branch `main` - **Build type: `dockerfile`**, file `Dockerfile` at repo root - **Port: `80`** The Dockerfile is two-stage: 1. `node:22-alpine` — runs `npm ci` and `npm run build` to produce `dist/` 2. `nginx:1.27-alpine` — copies `dist/` to nginx's web root and serves it (with gzip, security headers, 1-year cache for hashed assets, and a `try_files` fallback for Astro's UTF-8 slugs) ## Why not Gitea Actions? Gitea Actions does **not** ship with managed runners (unlike GitHub Actions' `ubuntu-latest`). Without a self-hosted `act_runner` registered with matching labels, any workflow run will fail with **"No matching online runner with label: ubuntu-latest"**. The Gitea Webhook mechanism is built into Gitea itself — no runner required. It fires the same events but POSTs to a URL you control, which is the simplest possible deploy trigger. If a real CI step is ever needed (lint, test, build artifact), install `act_runner` on a box, register it, and write a workflow using `runs-on: self-hosted`. See `act_runner` docs for setup. ## Troubleshooting ### Push happened, but site didn't update 1. Open the webhook row in Settings → Webhooks 2. Open **Recent Deliveries** 3. Check the most recent one: - Status 200 → deploy endpoint received it, check EasyPanel logs - Status != 200 → check the response body - **No recent delivery** → webhook is not bound to this branch/event or the push target branch doesn't match the filter ### Build fails inside EasyPanel 1. EasyPanel UI → service `dealplustech-astro` → Logs tab 2. Look for the `nixpacks` or `docker build` step 3. Common failures: - **"No start command could be found"**: you're on `nixpacks`. Switch build type to `dockerfile` and point at `Dockerfile` at repo root. - **"Node.js v20.x is not supported by Astro"**: the Dockerfile is using `node:20-alpine`. It should be `node:22-alpine` (Astro 6 requires `>=22.12.0`). - **"Failed to sync changes"** (HTTP 500 from the deploy endpoint): usually a panel-side state issue. Retry, or open the service in the panel UI and check container state. ### Want to redeploy without a code change The webhook URL itself is idempotent. You can hit it directly with: ```bash curl -X POST \ "http://110.164.146.47:3000/api/deploy/772d2c3a4a7d8671657c947c059bc1cdc64bd816efb7fbe2" ``` A `200` response with body `Deploying...` means the panel accepted the trigger. The actual rebuild happens in the background — check EasyPanel UI for the progress.