Files
dealplustech-astroreal/docs/ci-setup.md
hermes d73e48351f
Some checks failed
Build & Deploy to EasyPanel / build-and-deploy (push) Has been cancelled
Lint & Test / build-check (push) Has been cancelled
fix(deploy): switch from nixpacks to Dockerfile + change branch to main
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
2026-06-09 10:28:46 +07:00

3.4 KiB

CI/CD Setup — EasyPanel Deploy

Push to main triggers build-and-deploy.yml:

  1. Builds the Astro static site into dist/
  2. Uploads dist/ as a 7-day artifact
  3. 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 customerwebsite project on the panel; the repo is dealplustech-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 branch main (not source-code).
  • 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

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:

  1. Stage 1 (node:20-alpine): runs npm ci then npm run build to produce dist/.
  2. Stage 2 (nginx:1.27-alpine): copies dist/ 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: "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.