---
title: Deploy
description: Put your Hollware on your Cloudflare account with one command, then create your site in the remote database.
section: start
order: 4
---

# Deploy

Hollware deploys to your own Cloudflare account as a Worker, with a D1 database, a KV namespace, two queues and an R2 bucket for the [images](/docs/images/) of your sites. The Workers free plan is enough to start.

## Log in and deploy

```sh
npx wrangler login
npm run deploy
```

`npm run deploy` runs `hollware deploy`, which:

1. deploys the Worker with wrangler. The first time, wrangler creates the database, the namespace, the queues and the bucket that `wrangler.jsonc` names;
2. sets `HOLLWARE_PUBLIC_URL` in `wrangler.jsonc` to the URL of the Worker, and deploys again with it;
3. makes `HOLLWARE_SECRET`, which seals the secrets Hollware makes, when the Worker has none;
4. applies the migrations to the remote database.

Commit `wrangler.jsonc` afterwards: it now holds the public URL. Locally, `npx hollware dev` still serves at `http://localhost:5199`, whatever URL the deploy wrote.

## Create your site

The remote database starts empty. Create your site and its owner in it; the site starts from a preset, which you shape in the admin:

```sh
npx hollware init --site my-site --remote
```

It prints a token for your agents and a link to set up your passkey on the deployed admin.

## Your own domain

To serve Hollware at a domain of yours, in a zone of the same Cloudflare account, deploy with it as the public URL:

```sh
npx hollware deploy --url https://cms.example.com
```

It writes the URL into `HOLLWARE_PUBLIC_URL` and a route for its host into `wrangler.jsonc`, and Cloudflare makes the DNS record and the certificate. The first deploy can take it already: `npm run deploy -- --url https://cms.example.com`.

`HOLLWARE_PUBLIC_URL` matters: Hollware answers only requests for that host, and refuses every other one. That is its guard against DNS rebinding.

## Check it

```sh
npx hollware doctor --remote
```

It checks the flags, the bindings, the bucket of images, the migrations and the owner, and says what to fix.

Your Hollware is not meant to be found: every answer carries `X-Robots-Tag: noindex, nofollow`, and its `/robots.txt` disallows everything. Search engines index your sites, never the CMS.

::callout{type="note"}
Updating Hollware is an update of its packages and a deploy: `hollware deploy` applies the new migrations first, then deploys the new Worker. Before it applies anything to a database that already has data, it takes a Time Travel bookmark and prints it. See [Upgrade Hollware](/docs/upgrade/).
::

## Backups

Every day after 03:00 UTC, the cron of your Hollware writes a backup of each site to its R2 bucket: one JSON file with the definition of the site and every entry, its latest Markdown and the one that is published. It holds the content only, never the images: they are in the bucket already, and never change. Each backup is kept 30 days unless the site says otherwise: in the admin under **Site**, in **Backups**, or in the `backups` of its definition with `update_site`, an owner keeps them from 1 to 365 days, or turns them off:

```json
"backups": { "enabled": true, "retentionDays": 30 }
```

With backups off, no new one is made, and the ones kept go when their retention passes. The admin lists them under **Site**, in **Backups**, where an owner downloads one; `list_backups` lists them over MCP, and `hollware backup get` turns one into files.

## Restore

Three ways back, for three kinds of loss:

- **The whole database, to a moment.** D1 keeps 30 days of Time Travel: `npx wrangler d1 time-travel restore <database> --timestamp <ISO time>` puts the database back as it was then, or `--bookmark <id>` to the bookmark that `hollware migrate --remote` printed before it migrated. Everything after that moment is lost, so read what you will lose with `npx wrangler d1 time-travel info <database> --timestamp <ISO time>` first.
- **Your content, from a day.** `hollware backup get <date> ./restore --url <your Hollware URL> --token-file <file>` writes the backup of that day as Markdown files, and `hollware import ./restore` takes them back as drafts. It reaches the content of one site without touching the rest of the database.
- **Your content, from files.** `hollware export ./backup --url <your Hollware URL> --token-file <file>` writes every entry as Markdown; `hollware import ./backup` takes them back as drafts, unchanged, which you then publish. Keep an export somewhere else than Cloudflare, on a schedule of your own: it is the copy that survives losing the account.
