Quickstart — With Database
Publish a Node.js application connected to a managed PostgreSQL database.
Note: This quickstart focuses on
PostgreSQL. For MariaDB, Analytics (ClickHouse), or Valkey (Key-Value, Cache, and Queues), use the dedicated Database, Analytics, and Managed services guides.
Step 1 — Create the PostgreSQL database
- In the console, create a managed PostgreSQL database. For testing, the
db-freeplan is available. - Choose the desired version from the options shown in the console (15, 16, 17, or 18).
- Copy the full URI or the connection details shown. The URI uses the
postgresql-<project-id>.managed.zenifra.comhost and requires TLS withsslmode=verify-full. - Keep the URI to configure the
DATABASE_URLvariable in the HTTP project.
Important: Zenifra does not inject
DATABASE_URLautomatically into your application. This configuration must be done manually in the HTTP project before publishing or in a new deploy.
Step 2 — Create your application
mkdir zenifra-api
cd zenifra-api
npm init -y
npm install express pgCreate index.js:
const express = require('express');
const { Pool } = require('pg');
const app = express();
app.use(express.json());
// The console URI uses sslmode=verify-full&sslrootcert=system.
// node-postgres does not read sslrootcert=system; with ssl: true it validates
// the certificate and hostname using Node.js trusted authorities.
const databaseUrl = new URL(process.env.DATABASE_URL);
databaseUrl.searchParams.delete('sslmode');
databaseUrl.searchParams.delete('sslrootcert');
const pool = new Pool({
connectionString: databaseUrl.toString(),
ssl: true,
});
app.get('/health', (req, res) => {
res.json({ status: 'ok' });
});
app.get('/', async (req, res, next) => {
let client;
try {
client = await pool.connect();
const { rows } = await client.query('SELECT NOW() as now');
res.json({ database_time: rows[0].now });
} catch (error) {
next(error);
} finally {
if (client) client.release();
}
});
app.post('/todos', async (req, res, next) => {
const { task } = req.body;
let client;
try {
client = await pool.connect();
await client.query(
'CREATE TABLE IF NOT EXISTS todos (id SERIAL PRIMARY KEY, task TEXT, done BOOLEAN DEFAULT false)'
);
const { rows } = await client.query('INSERT INTO todos (task) VALUES ($1) RETURNING *', [task]);
res.status(201).json(rows[0]);
} catch (error) {
next(error);
} finally {
if (client) client.release();
}
});
app.use((error, req, res, next) => {
console.error(error);
res.status(500).json({ error: 'Internal server error' });
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, '0.0.0.0', () => {
console.log(`API running on port ${PORT}`);
});Step 3 — Publish via GitHub
- Create a repository on GitHub, add a
"start": "node index.js"script topackage.json, and push the code, includingpackage-lock.json. - In the console, set Project Source to Git repository and, under Git provider, select GitHub.
- Select the repository and the main branch.
- Under Runtime, select
Node.js. - In the Port field, enter
3000. - Configure the
DATABASE_URLenvironment variable with the PostgreSQL URI created in step 1. - In Start Command, use
npm start; leave Build Command empty. - If you want automatic updates on push, select Automatic by branch under Deployment mode.
- Click Create Project.
If the HTTP project already exists, save the DATABASE_URL variable in it and publish a new version so the application reads the updated ENV.
Step 4 — Test
Use the project URL at *.clients.zenifra.com and validate the application.
Check if the application is online:
curl https://your-project.clients.zenifra.com/healthCheck the database connection:
curl https://your-project.clients.zenifra.com/Create an item to validate PostgreSQL writes:
curl -X POST https://your-project.clients.zenifra.com/todos \
-H 'Content-Type: application/json' \
-d '{"task":"Build something cool"}'Response:
{ "id": 1, "task": "Build something cool", "done": false }Environment variables
For this flow, configure at least this variable and this field manually:
| Variable or field | Description |
|---|---|
DATABASE_URL | PostgreSQL connection string copied from the console |
| Port | HTTP project creation field that must reflect the port used by the application |
Zenifra also injects ZENIFRA_INSTANCE_VERSION with the deployed instance version; you do not need to add it.
Database access
Use the full URI or the connection details provided in the console to connect your application or external tools to the managed PostgreSQL database, always with TLS and certificate validation. Zenifra does not offer automatic backups with restore from the console: keep your own dumps (pg_dump) of important data.
Last updated on
Quick Start — Python
Publish a FastAPI or Flask application on Zenifra from a GitHub repository, with a configured port and deployment validation.
Framework guides
Pick your framework and see the runtime, port, build and start commands, and the recommended path to deploy on Zenifra via a Git repository (GitHub or Forgejo) or an OCI image.