Runtimes
Zenifra does not perform automatic runtime detection. In projects created from a Git repository, the user explicitly chooses the runtime during project creation.
Supported runtimes
| Runtime | How it works |
|---|---|
| Node.js | The user chooses the version in the console, and the platform installs dependencies with npm ci |
| Python | The user chooses the version in the console, and the platform installs dependencies with pip install --no-cache-dir -r requirements.txt when the file exists |
| Bun | The user chooses the version in the console, and the platform installs dependencies with bun install --frozen-lockfile |
Note: Today,
Node.js,Python, andBunare officially supported for Git repository builds. Java, Go, PHP, .NET, Nginx, Apache, and other stacks should be published via OCI Image.
Available versions
| Runtime | Versions | Suggested default port |
|---|---|---|
| Node.js | 20, 22, 24, and 26 | 3000 |
| Python | 3.11, 3.12, 3.13, and 3.14 | 8000 |
| Bun | 1.2, 1.3, and 1.4 | 3000 |
Pick the same major version you use in development. The suggested port is just a starting point: the project Port field must match the port your app listens on.
Build and runtime environment
- Project environment variables are available during dependency install,
pre-build, andbuild, as well as at runtime. This lets build steps use variables such asNEXT_PUBLIC_*orVITE_*. - Changing a variable restarts the instances but does not rebuild. Values embedded during the build only change on a new deployment.
- The app runs as an unprivileged user inside the application directory. It can write to that directory, but files are ephemeral unless stored in persistent storage.
- On Node.js and Bun, the app runs with
NODE_ENV=production. - The build uses the folder set in Root directory (the repository root by default; in monorepos, a subfolder such as
backend) and an environment generated by Zenifra for the selected runtime: an existingDockerfilein the repository is not used. To build with your ownDockerfile, publish an OCI Image. - The repository
.gitfolder is not included in the published application. If your application read Git information at runtime (for example, the current commit), use an environment variable. - On Python,
print()andloggingoutput reaches the logs unbuffered, and the build environment includes a C compiler and the PostgreSQL client libraries for packages with native extensions.
Important rule
In GitHub projects created in the console, runtime, version, and branch cannot be changed in the console; through the API (PUT /v1/project/:id/source) or the CLI (zenifra project source) you can reconfigure the source. In Forgejo projects, the project page's Git repository section lets you change the runtime (Node.js or Python), version, and commands; the API also accepts Bun.
Node.js
Required files
{
"name": "my-app",
"scripts": {
"start": "node index.js"
}
}For Node.js projects based on Git, these files are required:
package.jsonpackage-lock.json
Default dependency install
Zenifra installs dependencies with:
npm ciBy default, npm ci installs the dependencies declared in the lockfile. Keep TypeScript, bundlers, and other build tools in devDependencies. If the project configuration sets NODE_ENV=production for the build, that install omits those dependencies; in that case, set pre-build to npm install --include=dev. It runs after the default install and before npm run build, making the tools available to the build. The current runtime does not prune devDependencies after that step.
No
buildcommand: when thebuildfield is empty,devDependenciesare pruned after install. Everything thestartcommand uses must be independencies.
Git projects using Yarn or pnpm are compatible with the current Node.js runtime only when they also provide a compatible npm package-lock.json. Zenifra does not automatically convert Yarn or pnpm lockfiles or workspaces; without a compatible npm lockfile, publish an OCI Image prepared by your own build process.
Project commands
After the default install step, these commands are user-defined during project creation:
pre-build(optional)build(optional)start(required)
A common use of pre-build in Node.js is generating code before the build, such as ORM clients. pre-build runs during the build, not on every application start; for database migrations, prefer running them at the beginning of start, as shown in the framework guides.
Python
Dependency files
Keep a requirements.txt in the project's Root directory (the repository root by default) with the runtime dependencies. The install below runs only when that file exists. If the repository also has pyproject.toml or setup.py, the package is installed with pip install -e . after the build.
Default dependency install
pip install --no-cache-dir -r requirements.txtProject commands
These commands are user-defined during project creation:
pre-build(optional)build(optional)start(required)
Bun
Files
{
"name": "my-app",
"scripts": {
"start": "bun index.ts"
}
}package.json(required)bun.lock(recommended): commit the lockfile so the build installs exactly the versions used in development. Generate it with the same Bun version selected for the project: a lockfile created by a newer version can be rejected by an older one.
Default dependency install
bun install --frozen-lockfiledevDependencies stay installed after the build, so tools such as TypeScript and bundlers are available to pre-build and build. Bun runs TypeScript directly, with no required compile step.
Project commands
The default start command is bun run start, which runs the start script from package.json. As with the other runtimes, you can also set:
pre-build(optional)build(optional)start(required)
What can be edited later
In GitHub projects, after creation, the pre-build, build, and start commands and the update mode remain editable; runtime, runtime version, and branch are set during creation. See GitHub Deployment.
In Forgejo projects, you can also change the repository, branch, runtime, version, and deployment mode after creation; see Deploy from Forgejo.
Last updated on
Health checks for HTTP projects
Configure HTTP project health checks, validate 2xx responses, review failures for 30 days, and keep Zenifra instances available.
Templates in Zenifra
Deploy n8n, Metabase, WordPress, and other ready-to-use applications with one click, or create Templates for your organization.