---
title: Deploy your documentation site
description: Publish with Thally managed hosting or deploy the open-source runtime to Vercel, Cloudflare, or Docker.
url: https://pr-15-a9c4e9fe1b6c.thally.app/guides/deploying
---

# Deploy your documentation site

Publish with Thally managed hosting or deploy the open-source runtime to Vercel, Cloudflare, or Docker.

Use Thally managed hosting when you want publishing, pull-request previews,
custom domains, and rollback managed from one workspace. Self-host when your
team needs to own the hosting layer as well as the repository.

## Choose a supported deployment path

| Target | Shipped contract | Production command or action |
| --- | --- | --- |
| Thally Cloud | Managed build, previews, releases, routing, and rollback | Publish the site from [Thally Cloud](https://app.thally.io/) |
| Vercel | Native Next.js build through the Thally CLI | `npx --yes @thallylabs/cli@latest deploy --prod` |
| Cloudflare Workers | OpenNext configuration, Wrangler configuration, and project scripts | `npm run deploy:cloudflare` |
| Docker or a container host | The documented server-image recipe | `docker build -t my-docs .` |

> **Warning:**
  An untouched scaffold has no `netlify.toml`, Netlify adapter, or tested
  publish-directory contract. Do not run `netlify deploy --build --prod`
  against it: the CLI can report a live deploy after uploading the repository
  root, while `/` and every documentation route return 404. Use one of the
  supported paths above, or own and test a Netlify-specific Next.js integration
  before treating Netlify as a production target.

## Publish with Thally Cloud

The [quickstart](/quickstart) creates or connects a GitHub repository and
publishes the site to a `thally.app` address. After that:

- pushes to the production branch start a publish;
- documentation pull requests receive isolated previews;
- documentation-only changes can publish faster than application changes;
- a failed publish leaves the previous version online; and
- rollback restores an earlier successful version without rewriting Git
  history.

Open **Deployments** for the live version, previews, searchable history,
repairs, redeploys, and rollback. See [Managed hosting](/guides/managed-hosting)
for operating instructions.

For a self-hosted deployment, complete the checks below and choose the provider
that matches your operational requirements.

## Before you deploy

1. Set the production origin:

   ```bash
   THALLY_SITE_URL=https://docs.example.com
   ```

2. Validate content and navigation:

   ```bash
   npx --yes @thallylabs/cli@latest check --ci .
   ```

3. Create a production build:

   ```bash
   npm run build
   ```

`THALLY_SITE_URL` supplies canonical links, Open Graph metadata, sitemaps, and
agent-facing URLs. Set it in the hosting provider rather than committing it to
the repository.

## Choose a self-hosted target

#### [Deploy to Vercel](/guides/deploy-vercel)

    Import the repository or deploy it with the Thally CLI.

#### [Deploy to Cloudflare](/guides/deploy-cloudflare)

    Build and publish the OpenNext Worker artifact.

#### [Deploy with Docker](/guides/deploy-docker)

    Run the site on a container host with persistent storage when needed.

## Choose the required runtime

Use a server-capable deployment for:

- API **Try It** requests;
- AI chat and remote MCP routes;
- the admin dashboard and analytics ingestion;
- password-protected documentation;
- feedback, search, and other runtime server APIs.

A fully static export is suitable only when you need rendered documentation
pages and static assets. The features above depend on server routes and will
not work in an `output: 'export'` build.

Track is managed by Thally Cloud. A managed site does not need to host a Track
webhook or store GitHub App credentials.

## Add production configuration

Only `THALLY_SITE_URL` is required for a basic public site. Add credentials and
storage variables only for features you enable. See the complete
[environment variable reference](/guides/environment-variables).

For serverless hosts, configure remote libSQL storage when analytics, settings,
task state, or rate-limit counters must survive redeploys. A Docker host or VPS
can instead persist the local `.data/` directory on a volume.

## Verify the live site

Do not treat a provider CLI's success message as proof that the site works.
For a public site, run GET requests against the homepage, a real nested page,
and an agent endpoint:

```bash
DEPLOY_URL=https://docs.example.com
curl --fail --silent --show-error --location "$DEPLOY_URL/" >/dev/null
curl --fail --silent --show-error --location "$DEPLOY_URL/quickstart" >/dev/null
curl --fail --silent --show-error --location "$DEPLOY_URL/llms.txt" >/dev/null
```

All three commands exit with status `0` on success and fail on HTTP 4xx or 5xx
responses. Replace `/quickstart` with a nested route your project actually
publishes. For protected documentation, make the same requests with the
authentication your readers use and verify the unauthenticated response
separately.

Then:

1. Open the homepage and one nested page on desktop and mobile.
2. Follow sidebar, search, breadcrumb, and previous/next links.
3. Check `/sitemap.xml`, `/robots.txt`, and `/llms.txt`.
4. Test any enabled server feature, including Try It, chat, feedback, admin, or
   access protection.
5. Confirm canonical URLs use the production domain.

If the provider reports success but these requests return 404, inspect the
build log and uploaded artifact before changing application routes. A deploy
that uploaded the repository root or treated `.next/` as an ordinary static
directory did not publish a runnable Thally server artifact. Follow the
[all-routes-404 diagnosis](/guides/troubleshooting#the-provider-reports-success-but-every-route-returns-404).

## Next steps

- [Operate a managed deployment](/guides/managed-hosting)
- [Protect private documentation](/guides/private-docs)
- [Validate documentation in CI](/guides/ci-checks)
- [Troubleshoot a deployment](/guides/troubleshooting)