Skip to main content

Deploy a static site, start to finish

Everything from an empty directory to a React app live in production with automatic deploys on every merge. ~10 minutes.

You need: Node.js, git, a Pagifier API token (PAGIFIER_TOKEN), and your platform's API URL (we'll use https://pagifier.company.com).

1. Create the app

npm create vite@latest hello-pagifier -- --template react
cd hello-pagifier && npm install
npm run dev # check it works locally, then Ctrl-C

2. Add the one file

pagifier.toml
#:schema https://pagifier.company.com/v1/schema/pagifier.json
version = 1

name = "hello-pagifier"
template = "vite-static"
environment = "prod"
ingress = "hello.company.com"

The vite-static template supplies the build (npm ci && npm run build), the artifact directory (dist), nginx, and caching. Your file adds only identity: name, environment, hostname.

Your repository now looks like:

hello-pagifier/
├── pagifier.toml ← the only Pagifier file you'll ever write
├── package.json
├── index.html
└── src/…

3. First deploy, by hand

zip -r app.zip . -x '.git/*' -x 'node_modules/*'

curl -H "Authorization: Bearer $PAGIFIER_TOKEN" \
-F config=@pagifier.toml -F archive=@app.zip \
"https://pagifier.company.com/v1/applications/hello-pagifier/environments/prod/deployments?wait=true"

Watch the stream:

{"releaseId":"r20260714-093012-1f2e3d4c","status":"Pending"}
{"phase":"Building"} ← npm ci + npm run build, in-cluster
{"phase":"Built"} ← image pushed, content-addressed
{"phase":"Available","url":"https://hello.company.com","done":true,"success":true}

Open the URL. Your app is live behind TLS, with hardened containers, health checks, and a network policy you never wrote.

4. Automate it

.github/workflows/deploy.yml
name: deploy
on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: company/pagifier-deploy@v1
with:
config: pagifier.toml
environment: prod
token: ${{ secrets.PAGIFIER_TOKEN }}

Add PAGIFIER_TOKEN to the repo secrets, merge, done: every push to main validates the config, deploys, streams the build into the job log, and fails the job with the compiler output if anything breaks.

5. Ship a change — and roll it back

Edit src/App.jsx, push, and watch the workflow deploy it. Then:

# instant rollback to the previous release — no rebuild
curl -X POST -H "Authorization: Bearer $PAGIFIER_TOKEN" \
https://pagifier.company.com/v1/applications/hello-pagifier/environments/prod/rollback

Deploy history is always available:

curl -H "Authorization: Bearer $PAGIFIER_TOKEN" \
"https://pagifier.company.com/v1/applications/hello-pagifier/environments/prod/releases?limit=5"

6. Polish (optional, all in the same file)

pagifier.toml — additions
security = "strict" # strict security-header profile
cache = {static = "365d", html = "5m"} # long-cache hashed assets

[headers.custom]
X-App-Version = "v2"

Header and cache changes don't rebuild — the server config lives in a ConfigMap, so this redeploys in seconds.

Where to next