docs(ci): rewrite setup guide for Gitea Webhook deploy trigger
The previous doc assumed a Gitea Actions workflow (which requires a self-hosted act_runner that we don't have, hence the 'No matching online runner with label: ubuntu-latest' error). The actual setup is much simpler: a Gitea Webhook pointing at the deploy endpoint. No runner, no workflow file. Setup is one-time in Settings -> Webhooks -> Add Webhook. Documents: - The push -> webhook -> deploy -> EasyPanel flow - Exact payload URL, method, content type, events - Test Delivery verification step - Why Gitea Actions doesn't work without act_runner - Troubleshooting: push not triggering, build failure modes (nixpacks 'No start command', node 20 vs 22), and a curl recipe for redeploying without a code change.
This commit is contained in:
160
docs/ci-setup.md
160
docs/ci-setup.md
@@ -1,99 +1,109 @@
|
|||||||
# CI/CD Setup — EasyPanel Deploy
|
# CI/CD Setup — Deploy via Gitea Webhook
|
||||||
|
|
||||||
Push to `main` triggers `build-and-deploy.yml`:
|
The site auto-rebuilds on every push to `main` via a Gitea **webhook**
|
||||||
1. Builds the Astro static site into `dist/`
|
(no Actions runner, no `.gitea/workflows/`, no act_runner required).
|
||||||
2. Uploads `dist/` as a 7-day artifact
|
|
||||||
3. Calls EasyPanel tRPC endpoint to trigger a redeploy
|
|
||||||
|
|
||||||
## Required Gitea repo secrets
|
## How it works
|
||||||
|
|
||||||
Go to **Settings → Actions → Secrets** and add three secrets:
|
```
|
||||||
|
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/<token>
|
||||||
|
│ HTTP 200 "Deploying..."
|
||||||
|
▼
|
||||||
|
EasyPanel pulls repo, builds with Dockerfile, redeploys
|
||||||
|
```
|
||||||
|
|
||||||
| Name | Value (for this site) | Where to get it |
|
## One-time webhook setup
|
||||||
|---|---|---|
|
|
||||||
| `EASYPANEL_TOKEN` | `cmq61xwrv000407qn9e2hhfuw` | EasyPanel → profile/settings → API tokens |
|
|
||||||
| `EASYPANEL_PROJECT_NAME` | `customerwebsite` | EasyPanel → project name in the dashboard |
|
|
||||||
| `EASYPANEL_SERVICE_NAME` | `dealplustech-astro` | EasyPanel → service name inside the project |
|
|
||||||
|
|
||||||
> ⚠️ Project name ≠ repo name. The site lives in the `customerwebsite`
|
In `https://git.moreminimore.com/kunthawat/dealplustech-astroreal/settings/hooks`:
|
||||||
> project on the panel; the repo is `dealplustech-astroreal`.
|
|
||||||
|
|
||||||
If any of these are empty, the workflow logs a warning and skips the deploy
|
1. Click **Add Webhook → Gitea**
|
||||||
trigger. The build still runs and the artifact is still uploaded.
|
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
|
## EasyPanel service requirements
|
||||||
|
|
||||||
The service on the panel side must be:
|
The service on the panel side (`project=customerwebsite`,
|
||||||
|
`service=dealplustech-astro`) must be:
|
||||||
|
|
||||||
- **Type: `app`**
|
- **Type: `app`**
|
||||||
- **Source: Git**, pointing at this repo (`kunthawat/dealplustech-astroreal`)
|
- **Source: Git**, branch `main`
|
||||||
on branch **`main`** (not `source-code`).
|
- **Build type: `dockerfile`**, file `Dockerfile` at repo root
|
||||||
- **Build type: `dockerfile`**, **file: `Dockerfile`** at the repo root.
|
|
||||||
> The workflow used to trigger nixpacks builds, but nixpacks expects a
|
|
||||||
> `start` script in `package.json` and an Astro static site doesn't
|
|
||||||
> have one. Switching to a Dockerfile + nginx fixes that.
|
|
||||||
- **Port: `80`**
|
- **Port: `80`**
|
||||||
|
|
||||||
If you need a different service type later, swap the endpoint in
|
The Dockerfile is two-stage:
|
||||||
`.gitea/workflows/build-and-deploy.yml` to the matching procedure:
|
|
||||||
- `services.app.deployService` (Dockerfile / app)
|
|
||||||
- `services.box.rebuildDockerImage` (low-level)
|
|
||||||
- `services.compose.deployService` (docker-compose)
|
|
||||||
|
|
||||||
## Why Dockerfile and not nixpacks
|
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)
|
||||||
|
|
||||||
Astro builds to static files in `dist/` — there is no Node server to run.
|
## Why not Gitea Actions?
|
||||||
Nixpacks tries to find a `start` command and fails. The Dockerfile in
|
|
||||||
this repo:
|
|
||||||
|
|
||||||
1. **Stage 1** (`node:20-alpine`): runs `npm ci` then `npm run build` to
|
Gitea Actions does **not** ship with managed runners (unlike GitHub
|
||||||
produce `dist/`.
|
Actions' `ubuntu-latest`). Without a self-hosted `act_runner` registered
|
||||||
2. **Stage 2** (`nginx:1.27-alpine`): copies `dist/` to nginx's web root
|
with matching labels, any workflow run will fail with
|
||||||
and serves it.
|
**"No matching online runner with label: ubuntu-latest"**.
|
||||||
|
|
||||||
`nginx.conf` ships gzip, security headers, 1-year cache for hashed
|
The Gitea Webhook mechanism is built into Gitea itself — no runner
|
||||||
assets, and a `try_files` fallback for client-side routes (Astro's
|
required. It fires the same events but POSTs to a URL you control,
|
||||||
file-based routing produces UTF-8 slugs).
|
which is the simplest possible deploy trigger.
|
||||||
|
|
||||||
## Verifying the trigger payload
|
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.
|
||||||
|
|
||||||
If the deploy runs but the panel rejects it, the response in the workflow
|
## Troubleshooting
|
||||||
log will show the exact `zodErrors` field telling you which field name
|
|
||||||
or shape is wrong. Update the `PAYLOAD` JSON in the workflow accordingly.
|
|
||||||
|
|
||||||
To test the payload shape from your local machine:
|
### 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
|
```bash
|
||||||
curl -sS -X POST \
|
curl -X POST \
|
||||||
"https://panelwebsite.moreminimore.com/api/trpc/services.app.deployService" \
|
"http://110.164.146.47:3000/api/deploy/772d2c3a4a7d8671657c947c059bc1cdc64bd816efb7fbe2"
|
||||||
-H "Authorization: Bearer *** -H "Content-Type: application/json" \
|
|
||||||
-d '{"json":{"projectName":"customerwebsite","serviceName":"dealplustech-astro"}}'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
A 2xx response = the panel accepted the trigger. The service will start
|
A `200` response with body `Deploying...` means the panel accepted the
|
||||||
rebuilding/redploying in the EasyPanel dashboard.
|
trigger. The actual rebuild happens in the background — check EasyPanel
|
||||||
|
UI for the progress.
|
||||||
## Common failure: "No start command could be found" (nixpacks)
|
|
||||||
|
|
||||||
Astro builds to static files in `dist/` — there is no Node server to run.
|
|
||||||
Nixpacks tries to find a `start` command and fails. The Dockerfile in
|
|
||||||
this repo handles this with a two-stage build (node:22-alpine build +
|
|
||||||
nginx:1.27-alpine serve).
|
|
||||||
|
|
||||||
## Common failure: "Node.js v20.x is not supported by Astro"
|
|
||||||
|
|
||||||
Astro 6 requires Node `>=22.12.0`. The Dockerfile uses `node:22-alpine`.
|
|
||||||
If you see this error, the panel is probably reading a stale `node:20`
|
|
||||||
cached image. Push an empty commit to force a rebuild, or clear the
|
|
||||||
panel's image cache from the EasyPanel UI.
|
|
||||||
|
|
||||||
## Common failure: "Failed to sync changes" (HTTP 500)
|
|
||||||
|
|
||||||
This is a **server-side** error, not a payload problem. It usually means:
|
|
||||||
|
|
||||||
- The EasyPanel service is currently in a state that can't be redeployed
|
|
||||||
(e.g. the previous container is stuck, or a build is in progress).
|
|
||||||
- The Docker daemon on the panel host is busy.
|
|
||||||
|
|
||||||
Try again in a few seconds. If it persists, open the EasyPanel dashboard
|
|
||||||
and check the service's container state.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user