# Deploy Docusaurus on Lizard

Build Docusaurus on Lizard and serve its generated `build/` directory through nginx on port `80`. The production deployment serves static files; it does not run the `docusaurus start` development server.

Start with the [complete source example](https://github.com/lizard-build/docs/tree/main/_examples/docusaurus), which includes the configuration and files used by this recipe.

## Prepare the site

Run from the Docusaurus directory containing `package.json`, its lockfile, and `docusaurus.config.*`. Keep `@docusaurus/core` in the dependencies and a build script that runs `docusaurus build`.

| Setting | Value |
|---|---|
| Build | `npm run build` |
| Output | `build/` |
| Runtime | nginx |
| Service port | `80` |

Set `url` in the Docusaurus config to the site's intended public origin and `baseUrl` to the path where it will run. For a site at the domain root, `baseUrl` is `/`. Once you know the final hostname, rebuild with that hostname so generated canonical URLs and sitemap entries use it.

Choose a consistent trailing-slash policy and check the resulting files. Keep the default output directory unless you provide a Dockerfile that copies your custom directory. The [Docusaurus deployment guide](https://docusaurus.io/docs/deployment) explains these framework settings.

## Build and check locally

```bash
npm ci
npm run build
npm run serve
```

The last command assumes your project has the scaffold's `serve` script. Check the home page, a nested documentation page, an image, and a versioned page if you use docs versions. Fix broken links reported by the build before deployment.

## Deploy

After [CLI setup](https://lizard.build/docs/framework-guides#prepare-the-project):

```bash
lizard init --name docusaurus-docs
lizard add --service web
lizard up --service web --port 80
lizard logs --build --service web --json
lizard ps --json
```

If you use the generated hostname, read it after the first deploy:

```bash
lizard service show web --json
```

Set `url` in `docusaurus.config.js` to that hostname:

```js
url: 'https://YOUR_PUBLIC_HOST',
```

Upload the changed config so the build uses the public URL:

```bash
lizard up --service web --port 80
```


Commit source, plugins, configuration, and the lockfile. Exclude `node_modules/`, `build/`, `.docusaurus/`, and `.env` files from uploads. Leave service command overrides unset to use the Docusaurus detection path.

## Serve inner routes and missing pages

New Docusaurus builds serve generated route files and return HTTP 404 for unknown paths. A custom Dockerfile is not needed for this routing policy. If your service still uses an image built before the September 2026 routing fix, rebuild it. Use [static routes and 404s](https://lizard.build/docs/framework-guides/static-routing) only when you need custom nginx behavior.

After deployment, request a nested docs URL directly, refresh it, and check a made-up URL's status. Also inspect the canonical URL and sitemap on the final hostname. A visible error page with HTTP 200 is still a soft 404.

If assets are missing, compare their URLs with `baseUrl`. If an inner route returns the home page, inspect the generated file layout and nginx rules. If old content remains after editing an environment value or Markdown file, verify that a new build actually completed; static HTML changes only with a build.

See [tested versions and cloud results](https://lizard.build/docs/framework-guides/validation) for the September 9, 2026 deployment checks and their limits.

