ZKRINET Docs
Build

Deploy

Deploying means putting new code into your project. There are three ways — the terminal, a zip in the panel and GitHub — and all of them go through the same chain: snapshot first, health check after, and back on its own if the project doesn't respond.

What may be uploaded

A deploy package may only contain these folders:

FolderWhat happens
pb_hooks/Replaces your server code
pb_migrations/Replaces your migrations. New migrations run when the project restarts
pb_public/Replaces your frontend

The building blocks live in a separate layer and are never affected by a deploy — see All building blocks.

Deploy keys

A deploy key unlocks one project and can only deploy — nothing else. Create it under the Deploy tab. The key is shown once; we only store a hash of it. Save it as a secret, for example ZKRINET_TOKEN in GitHub. At most ten keys per project. Revoke a key you no longer use.

1. From the terminal

Run in the project folder (where pb_hooks/, pb_migrations/ and pb_public/ are). Requires Node 18 or later, no other dependencies.

ZKRINET_TOKEN=zk_dep_… npx https://zkrinet.com/cli/zkrinet.tgz deploy

Another folder, or a message that shows in the log:

ZKRINET_TOKEN=zk_dep_… npx https://zkrinet.com/cli/zkrinet.tgz deploy ./min-app -m "new start page"

The command packs the folders, uploads them and follows the deploy until it is live or restored. Publishing the CLI as npx zkrinet COMING.

2. Zip in the panel

The Deploy tab → Choose zip and deploy. The zip must contain the folders above. Same checks and same chain as in the terminal.

3. From GitHub

Put the file below in the repo as .github/workflows/zkrinet.yml and the deploy key as the repo secret ZKRINET_TOKEN. Every push to main deploys.

name: Zkrinet
on: { push: { branches: [main] } }
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20 }
      - run: npx --yes https://zkrinet.com/cli/zkrinet.tgz deploy
        env: { ZKRINET_TOKEN: ${{ secrets.ZKRINET_TOKEN }} }

If a deploy from GitHub is rolled back, you get an alert — nobody is sitting and watching an automatic deploy.

What happens during a deploy

  1. The package is fetched and checked against its SHA-256 — what was deployed is exactly what was uploaded.
  2. The check rejects the whole package at the slightest deviation (see above).
  3. A snapshot of the whole project is taken — database, files and code. That is the restore point.
  4. The code is put in place and the project is restarted. New migrations run.
  5. The health check: the project must respond within about 30 seconds. If pb_public/index.html exists, it is also checked that the start page is actually served.
  6. If the project responds, the deploy is live. If it doesn't respond, everything is rolled back to the snapshot — including the database, if a migration managed to change it — and the project starts again as it was before the deploy.

The log for each deploy is shown under the Deploy tab, with the reason if it was rolled back.

Frequently asked questions

My deploy was rolled back. Why? The project didn't respond after the restart. The most common cause is an error in a hook or a migration that crashes on startup. The log under Deploy shows the last lines from PocketBase. Test locally with ./pocketbase serve and the same version (0.40.4).

Is my data deleted if a deploy is rolled back? The project is restored to the state just before the deploy. If someone managed to write data during the seconds the deploy was in progress, exactly that is lost.

Can I roll back to an earlier deploy myself? We keep the three most recent snapshots from deploys. A button for going back to one of them COMING. Until then: deploy the earlier version of the code again.

Can I deploy only the frontend? Yes. Send only pb_public/ — the server code and migrations are not touched.

The start page shows Zkrinet's page instead of mine. You don't have a pb_public/index.html yet. Deploy it, and yours will show.

Why doesn't my new CSS show right away? Files without their own Cache-Control get private, no-cache: the browser asks whether the file has changed and gets a quick answer if it hasn't. If you still see old code: hard-reload the page.