---
title: "Deploying"
description: "Production builds, building without database access, Payload version policy and sitemap caching."
requested_language: sk
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/sk/next/guides/deploying
version: unreleased (main)
docs_index: https://docs.systhema.app/sk/next/llms.txt
---
> This page isn't translated yet. Showing English.


Run a Systhema project in production: start commands, Docker builds, builds that cannot reach the database, and the Payload versions the bundled patch supports.

## Production deployment

On Railway, set the start command to `node_modules/.bin/next start`. Next must receive `SIGTERM` itself during a redeploy. Do not use `pnpm start` as the Railway start command. Run database migrations in Railway's pre-deploy command instead of the start command.

In a multi-stage Docker build, copy `.systhema/` before or with the install stage so its artifact mirror is available. If you regenerate artifacts during the image build, copy the generated `.systhema/` into the runtime stage too. Do not depend on a runtime sync unless you explicitly configure one.

## Building without database access

By default `next build` prerenders every published page and post, so the build needs the database. Some hosts only expose it on a private network that the builder cannot reach. On Railway, for example, `postgres.railway.internal` does not resolve during the build, and the build fails at "Collecting page data" with `ENOTFOUND`.

Set `SYSTHEMA_PRERENDER=off` in the build environment instead of exposing the database publicly:

```bash
SYSTHEMA_PRERENDER=off pnpm build
```

`generateSysthemaStaticParams` then returns no params and never starts Payload. Each page renders on its first request and stays cached for the route's `revalidate` period, and publishing still revalidates it. The trade-off is that the first visitor to each page after a deploy waits for a server render. `false` and `0` work as well as `off`.

The generated routes avoid the other build-time database reads described below. Review your custom routes and template data hooks separately. The sitemap, `robots.txt`, `/sys/*`, Admin and API routes are dynamic, and the not-found page and icons need no data. This flag removes the managed catch-all's prerender query; it does not guarantee success if project-owned code connects during the build.

The catch-all `page.tsx` must hand `generateSysthemaStaticParams` a getter, `payloadInstance: () => getPayload({ config: configPromise })`. A `getPayload()` promise has already started connecting by the time the flag is checked. `systhema upgrade` refreshes an unedited `page.tsx`. If you patched it to return `[]`, take the new template from `page.tsx.new` and set the variable instead.

## Payload version policy

The bundled Lexical patch supports `@payloadcms/richtext-lexical` `^3.90.0`. Keep `payload` and every `@payloadcms/*` package on compatible caret ranges such as `^3.90.1`. The patch file is named for its floor, and pnpm applies it across the supported minor. Run `systhema doctor` after dependency changes. The range is the patch's declared support; it does not prove every future release will accept the diff. Exact family pins are also supported when they remain aligned. Use [Upgrading a client site](recipes/upgrading-a-client-site.md) to review the patch and migration plan.

## Sitemap route caching

The managed sitemap Route Handler uses `export const dynamic = 'force-dynamic'`, not time-based ISR. Its `Cache-Control` response header already provides shared caching and stale-while-revalidate behavior. Keeping it dynamic avoids a database read during `next build`. In the generated routes, the catch-all prerender path queries the database during the build; see [Building without database access](#building-without-database-access).
