Project configuration
Project configuration in Zenifra defines how your application is published, executed, and exposed on the internet. This page is a central overview of the main settings available in the console, focused on rules, practical decisions, and the most important limits.
For details on each area, see Environment variables, Persistent storage, Network and access control, and Custom domains.
For step-by-step instructions, also see:
- How to create an HTTP project
- How to change HTTP project settings
- How to connect GitHub to Zenifra
- How to change a project image
What project configuration includes
In the current Zenifra flow, project configuration can include:
- project identity, such as name and description
- publishing source, such as
Git repository(GitHub or Forgejo) orOCI Image - build and startup parameters for projects based on a Git repository
- environment variables and operational secrets
- subdomain and custom domains
- IP-based network access rules
- operational capacity, such as instances and storage
These options are centered in the console and help define how the application is deployed, updated, and maintained.
What is usually defined at creation time and what can change later
Some choices are made during project creation, while others also appear again on the edit screen.
| Area | Defined during creation | Can be adjusted later |
|---|---|---|
| Name and description | Yes | Yes |
| Source and repository | Yes | Forgejo: yes, the Git repository section lets you change or disconnect the repository. GitHub: not in the console |
| Branch | Yes | Forgejo: yes, in the Git repository section. GitHub: not in the console |
| Update mode | Yes | Yes |
| Runtime and build commands | Yes, for projects with a Git repository | Commands: yes. Runtime: yes for Forgejo projects; not in the console for GitHub projects |
| Environment variables | Yes | Yes |
| Zenifra subdomain | Yes | Yes, on plans with a custom subdomain (Premium and above) |
| Custom domains | No | Yes, after the public project is created |
| Instances | Yes | Yes |
| Storage | Yes | Capacity can be increased (never reduced) on hourly projects; the persisted directory does not change |
Note: Not every setting follows the same editing rule. When a choice affects build, restart, persistence, or billing, validate the expected behavior on the project edit screen.
Choosing the project source
In the console, an HTTP project's source is Git repository or OCI Image. You can also start from a template or publish with the CLI and the GitHub Action.
Git repository (GitHub or Forgejo)
This option is a good fit when you want deployment tied to source code. In this mode, the console can expose settings such as:
- Git provider, repository owner, and repository name
- branch
runtimeand runtime version (Node.js, Python, or Bun)- update mode
pre-build,build, andstartcommands
This model is useful for applications that evolve frequently and need a deployment flow closely tied to development.
If your project uses GitHub as the source, also see how to connect GitHub to Zenifra. For Forgejo, see Deploying from Forgejo.
OCI Image
This option is a better fit when you already have a ready image, want to control the artifact outside the repository, or need to publish through a registry. It is also the path for stacks without a Zenifra build runtime, such as Go, Java, PHP, or .NET.
It usually makes more sense when:
- the build pipeline already runs outside Zenifra
- the image is produced by external CI
- you want to promote immutable tagged versions
If you need to change the published image, use the flow described in how to change a project image.
Build and startup in Git repository projects
In projects based on a Git repository, configuration goes beyond choosing a repository. The console can also expose parameters that directly affect build and startup.
Runtime and version
These fields help align the build environment with the stack used by the project. In Node.js or Python flows, for example, choosing the correct version can avoid differences between development and production.
Automatic by branch
In Automatic by branch mode, pushes to the selected branch trigger new publications. Choose this mode only when the watched branch is stable; other modes let you publish manually, by tag, or by release.
pre-build, build, and start commands
These commands control important deployment stages such as dependency installation, compilation, and application startup. They are especially useful when:
- the project changed frameworks
- the default command does not fit the repository structure
- the startup process must be adjusted without recreating the project
Projects whose source is a Git repository can edit these commands after creation on the project edit screen; saving new commands triggers a new build.
Environment variables and secrets
Environment variables centralize values that should not be hardcoded in the repository, such as:
DATABASE_URLAPI_KEYPORT- external API URLs
Best practices:
- use the console to store sensitive secrets
- do not commit tokens, passwords, or keys to the repository
- separate operational variables from local development values
- review names and values before saving, because changes may require instance restarts
Platform-injected variables
In addition to the variables you define in the console, Zenifra can also inject operational variables automatically into instances.
One important example is:
ZENIFRA_INSTANCE_VERSION: identifies the deployed instance version
You can use this variable in your code to:
- distinguish logs between different versions
- quickly identify which release is serving a request
- help with troubleshooting during rollouts and updates
For practical examples, see the HTTP project creation guide.
Network, domains, and public exposure
HTTP projects can be created with exposure: public or exposure: private.
public: creates a public route, Zenifra subdomain, and allows custom domains according to the plan.private: keeps the application without a public domain, useful for automations, workers, and internal routines.
Subdomain and custom domains
Depending on the plan, a public project can use a Zenifra subdomain and also accept custom domains. This layer defines how users reach your application.
Custom domains make sense when you want to:
- publish with your company identity
- separate environments by host
- use a more stable endpoint for integrations
Whitelist and blacklist
For public projects that require access control, from the Premium Plus plan, Zenifra offers IP lists in CIDR format (up to 10 in each list).
- the whitelist defines who can enter
- the blacklist blocks specific IPs
This is useful for internal environments, admin panels, restricted APIs, or staging phases.
Scale and operations
Instances
The number of instances affects capacity, availability, and cost. In general:
- fewer instances simplify test environments
- more instances increase capacity and redundancy
Instances can be changed on the project edit screen. On paid plans, auto-scaling adjusts instances automatically between a minimum and a maximum.
Application port
The port tells Zenifra where HTTP/HTTPS traffic should be forwarded inside the application. It must match the port your application actually listens on (default 3000 for Node.js and Bun, 8000 for Python).
Even when the detailed instructions live in the creation flow, this should still be treated as a critical part of the initial project configuration.
Persistent storage
Storage defines whether specific application data should survive restarts and new executions.
When to use it
Persistent storage makes sense when the application needs to:
- keep uploads
- keep generated artifacts
- preserve files used across restarts
A common use case is using /data to store temporary work files, imports, reports, or generated PDFs that may be deleted after use, but should not disappear in the middle of operations.
What to watch
- configured capacity should match expected data volume
- the persisted path should be chosen carefully
- not every storage change follows the same rule across plans and billing models
If your flow depends on persistence, review the details in the HTTP project creation guide.
Guides in this section
| Guide | When to use |
|---|---|
| Environment variables | Configure secrets, limits, and restarts |
| Persistent storage | Keep files across restarts and versions |
| Network and access control | Public or private projects and IP lists |
| Custom domains | Publish with your company domain |
Use this page to decide what to configure and why. For click-by-click steps and screen validations, follow the console guides.
Next steps
- Private connections between applications, Jobs, databases, and cache
- Create an HTTP project
- Edit an HTTP project
- Connect GitHub
- Change the project image
FAQ
What is the difference between a Git repository and an OCI image?
Git repository is more suitable when deployment depends on source code and the platform build flow. OCI Image is a better fit when you already deliver a ready artifact through a registry.
Can I edit build commands after creation?
Yes. In projects whose source is a Git repository (GitHub or Forgejo), the pre-build, build, and start commands can be changed later on the project edit screen.
Where should I store secrets?
In the Zenifra console, using environment variables. Do not place keys, tokens, or passwords directly in the repository.
Does Zenifra inject any variables automatically?
Yes. One example is ZENIFRA_INSTANCE_VERSION, which identifies the deployed instance version and can be used to distinguish logs, releases, and behavior across versions.
When should I use persistent storage?
When the application needs to keep files across restarts. If the data can be recreated and does not need to survive, evaluate whether persistence is really necessary.
Last updated on
Template permissions and visibility
Learn who can create, read, update, publish, delete, and deploy templates within each Zenifra organization.
Environment variables
Configure environment variables and secrets for Zenifra HTTP projects through the console, CLI, or API, with limits, restarts, and best practices.