Astro 6.x requires Node >=22.12.0. The previous Dockerfile used node:20-alpine, which the Astro CLI rejected with: Node.js v20.20.2 is not supported by Astro! Please upgrade Node.js to a supported version: ">=22.12.0" EasyPanel pulled the change, ran the build, and failed at `RUN npm run build`. Bumping to node:22-alpine fixes it. Also added two 'common failure' sections to docs/ci-setup.md covering the nixpacks 'No start command' and Node version mismatch errors we just hit.
4.0 KiB
CI/CD Setup — EasyPanel Deploy
Push to main triggers build-and-deploy.yml:
- Builds the Astro static site into
dist/ - Uploads
dist/as a 7-day artifact - Calls EasyPanel tRPC endpoint to trigger a redeploy
Required Gitea repo secrets
Go to Settings → Actions → Secrets and add three secrets:
| Name | Value (for this site) | Where to get it |
|---|---|---|
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
customerwebsiteproject on the panel; the repo isdealplustech-astroreal.
If any of these are empty, the workflow logs a warning and skips the deploy trigger. The build still runs and the artifact is still uploaded.
EasyPanel service requirements
The service on the panel side must be:
- Type:
app - Source: Git, pointing at this repo (
kunthawat/dealplustech-astroreal) on branchmain(notsource-code). - Build type:
dockerfile, file:Dockerfileat the repo root.The workflow used to trigger nixpacks builds, but nixpacks expects a
startscript inpackage.jsonand an Astro static site doesn't have one. Switching to a Dockerfile + nginx fixes that. - Port:
80
If you need a different service type later, swap the endpoint in
.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
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:
- Stage 1 (
node:20-alpine): runsnpm cithennpm run buildto producedist/. - Stage 2 (
nginx:1.27-alpine): copiesdist/to nginx's web root and serves it.
nginx.conf ships gzip, security headers, 1-year cache for hashed
assets, and a try_files fallback for client-side routes (Astro's
file-based routing produces UTF-8 slugs).
Verifying the trigger payload
If the deploy runs but the panel rejects it, the response in the workflow
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:
curl -sS -X POST \
"https://panelwebsite.moreminimore.com/api/trpc/services.app.deployService" \
-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 rebuilding/redploying in the EasyPanel dashboard.
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.