Quickstart

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

  1. In the console, create a managed PostgreSQL database. For testing, the db-free plan is available.
  2. Choose the desired version from the options shown in the console (15, 16, 17, or 18).
  3. Copy the full URI or the connection details shown. The URI uses the postgresql-<project-id>.managed.zenifra.com host and requires TLS with sslmode=verify-full.
  4. Keep the URI to configure the DATABASE_URL variable in the HTTP project.

Important: Zenifra does not inject DATABASE_URL automatically 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 pg

Create 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

  1. Create a repository on GitHub, add a "start": "node index.js" script to package.json, and push the code, including package-lock.json.
  2. In the console, set Project Source to Git repository and, under Git provider, select GitHub.
  3. Select the repository and the main branch.
  4. Under Runtime, select Node.js.
  5. In the Port field, enter 3000.
  6. Configure the DATABASE_URL environment variable with the PostgreSQL URI created in step 1.
  7. In Start Command, use npm start; leave Build Command empty.
  8. If you want automatic updates on push, select Automatic by branch under Deployment mode.
  9. 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/health

Check 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 fieldDescription
DATABASE_URLPostgreSQL connection string copied from the console
PortHTTP 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

On this page