Jump to
↵select↑↓navigateescclose

Production

From development to production

The immutable builtBench package that the development shell, the container images and the NixOS module all share, and how to choose between images and the module.

Updated
Tags
  • production
  • builtbench
  • deployment
On this page

frappe-nix builds one production artifact, builtBench, and everything you deploy is assembled from it. It contains the apps, the production Python environment, Node and the compiled assets. nix build .#default builds it, and so does nix build in an app repository.

Nothing is installed or compiled at deploy time or at container start. The environment, node_modules and assets are all fixed at build time, so a given set of locks and app commits produces the same bench every time.

What goes into it

PartComes from
Python environmentuv.lock, through uv2nix. Nothing runs uv sync at build or start time.
node_modulesEach node target's own yarn.lock, or a node-locks/ fallback. See Dependencies and locks.
Compiled assetsbench build --production, run inside the Nix sandbox. See Build production images.
App registrysites/apps.txt and sites/apps.json, regenerated from the workspace members. See Apps in a bench.

The package exposes passthru.{pythonEnv, nodejs, appsPath, appNames}, so the NixOS module and the containers discover interpreters from the package itself. There is no separate pythonEnv or nodejs option on the server side. The extraPackages option installs extra packages in both the dev shell and any production deployment of this package: the NixOS module reads them off the package's passthru.extraPackages, so no server-side configuration is needed.

What is the same in development and production

  • The Python and Node interpreters, and every locked dependency.

  • The unified runtime, and the single-origin shape of nginx in front of unix sockets.

  • frappe_unixsock, which makes Frappe honor unix sockets, and frappe_journald, which gives log lines journald priorities. Both are grafted into both virtualenvs.

What is development-only

  • The guard rails. prodPythonEnv, the NixOS module and the containers never see frappe_devguard.

  • The editable installs of apps/*, the watcher and Mailpit.

Two ways to run it

You wantUse
Declarative, multi-tenant Frappe on a NixOS host, with systemd units, automatic migrations and journald loggingThe services.frappe NixOS module
To run Frappe on a host that is not NixOS, or in an orchestrator you already haveOCI container images

The bench repository exposes only the package. The NixOS module is imported directly from frappe-nix, not re-exported by the bench, so a deployment server combines both.

Both read the same builtBench. Read The unified runtime for the process they run, Operate a deployed site for migrations, tuning and day-two tasks, and Logging for the journal contract.

Production checklist

  1. Commit uv.lock, every yarn.lock that is yours, node-locks/ and sites/apps.json. A flake sees only tracked files.

  2. Build the package: nix build .#default. It must succeed from a clean checkout.

  3. Decide how secrets reach the host. See Secrets.

  4. Deploy with the module or the images.

  5. Create or restore the site. Neither route installs one for you. See Operate a deployed site.