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.
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.
Nixpacks auto-detect could not find a 'start' script in package.json
and bailed out. Astro builds to static files in dist/ — there is no
Node server to start. Switching to a Dockerfile + nginx fixes the
'No start command could be found' error from EasyPanel.
The workflow also pointed at the source-code branch, but the panel's
git source ref for the dealplustech-astro service is 'main', so the
trigger was firing for the wrong ref. Both workflows now run on push
to main.
- Dockerfile: multi-stage node:20-alpine build + nginx:1.27-alpine serve
- nginx.conf: gzip, security headers, 1-year cache for hashed assets,
try_files fallback for UTF-8 slugs (Astro file-based routing)
- .dockerignore: keep build context small (skip CI, docs, .gitea, IDE)
- build-and-deploy.yml + lint.yml: branch source-code -> main
- docs/ci-setup.md: corrected project + service names (customerwebsite
/ dealplustech-astro), documented the Dockerfile rationale, added a
note for the 'Failed to sync changes' server-side error
Replaces the old EASYPANEL_WEBHOOK_URL flow with a direct tRPC call
to the panel, using three minimal secrets the operator fills in:
EASYPANEL_TOKEN - bearer token from EasyPanel profile
EASYPANEL_PROJECT_NAME - project name in the dashboard
EASYPANEL_SERVICE_NAME - service name inside that project
The endpoint (https://panelwebsite.moreminimore.com/api/trpc/services.
app.deployService) is hardcoded because the panel URL does not change.
Payload uses tRPC's wrapped-json shape: {"json":{"projectName":...,
"serviceName":...}}.
The build still runs and the dist/ artifact still uploads when any
secret is empty — only the trigger step is skipped with a warning.
Also adds docs/ci-setup.md explaining the three secrets, the service
type requirement (must be 'app' / Dockerfile-based), and a curl recipe
for testing the payload shape locally before pushing.