Skip to main content
The CLI offers two deployment paths depending on whether you want the deployed site to be editable:

primo deploy — Editable CMS

Deploy your entire workspace (every site under sites/, plus library/ and server.yaml) as one editable Primo instance:
Run from the workspace root (the directory containing server.yaml).

Railway

The CLI sets up a Railway project and persistent storage for the CMS. Prerequisites:
The CLI provisions a Railway project, attaches a persistent volume for /app/pb_data, and prints the deployed URL.

Fly.io

Fly.io offers usage-based hosting in multiple regions. New accounts receive a trial, not an ongoing free tier; see Fly.io pricing. Prerequisites:
  • Fly CLI installed (fly auth login)
  • A Fly.io account

Updating a Deployed Workspace

Once deployed, push subsequent changes with primo push:
By default, a push updates the CMS draft. Publish from the hosted browser editor, or use primo publish with a compatible server. To upload and publish in one command, use primo push --only my-site --publish from the workspace root. See CLI publishing for requirements and verification, and Push and Pull for sync safety.

primo build — Static Site

Build a single site as static HTML and CSS for a static host:
Run from the workspace root and pass the site folder with -d. If you run inside the site folder, you can omit -d. Use CLI 0.2.1 or later for interactive blocks and resolved field references. It generates static HTML and CSS plus JavaScript for blocks with a script. The commands below use the custom ./dist output:
Static builds have no CMS — collaborators can’t edit content through a UI. Use primo deploy if you need editor access.

Static build limitations

CLI 0.2.1 supplies block field props automatically, matching the browser compiler. You can still declare them explicitly in component.svelte, which also supports older static builders:
component.svelte
When you declare $props(), include every field the component uses; the browser compiler also leaves field declarations to you in that case. CLI 0.2.1 resolves Site Field, Page Field, Page, Page List, Markdown, and Rich Text values and includes both site and page type foot.html. Earlier 0.2.0 builds omit hydration scripts and some reference resolution, and include only the site footer. Stop a running primo dev before updating with npm install -g primo-cli@latest. Static files do not include a CMS or a form-processing backend. Root-relative URLs such as /_symbols/ and /about expect the site at the hostname’s root. Preview the generated files through a local HTTP server and test links, images, and interactions before deploying; opening index.html directly from disk does not test module loading correctly. primo build replaces its output directory. Choose a dedicated output folder containing only generated files.

Choosing a Host

  • Usage-based compute and persistent-volume billing
  • Global edge deployment
  • Best for: prototypes, low-traffic sites, regional latency requirements
  • Full server access; you manage updates, storage, and certificates
  • Manual setup via Docker
  • See the Deployment Guide for instructions
  • Best for: teams comfortable with Linux and Docker
  • Static file hosting; check your provider’s plan and usage limits
  • No CMS — use primo build and deploy the static output
  • Best for: marketing sites where content is edited locally and shipped via Git

Backups

Hosted Primo uses PocketBase’s built-in backup system. Configure scheduled backups from https://your-server.com/_/ under Settings → Backups. See the Deployment Guide for details. For Git-based content snapshots, primo pull exports your sites and shared library. It does not include user accounts, server settings, or database backups, so keep PocketBase backups too:

Next Steps

Push and Pull

Sync changes between local and deployed servers

Deployment Guide

Self-host Primo on a VPS or custom infrastructure