Deploy Portabase | (Just Updated) Database Backup And Restore Console With REST API, Admin Password Generated

Portabase database backup and restore console with REST API, on Postgres

Deploy Portabase | (Just Updated) Database Backup And Restore Console With REST API, Admin Password Generated

Just deployed

/var/lib/postgresql

Just deployed

/data

Deploy and Host Portabase on Railway

Built for an LLM agent to deploy and use. The deploy form has nothing to fill in: the administrator password, the signing secret and the database password are generated, the administrator account is created at first boot, the REST API is switched on, and your backup console, its database and its local backup storage survive redeploys. Portabase is the open-source web console that schedules, stores and restores backups of PostgreSQL, MySQL, MariaDB, MongoDB and other databases through lightweight agents that run next to the databases.

About Hosting Portabase

This template runs two services on one public domain. portabase is the upstream Portabase 1.36.2 image pinned by digest (Next.js dashboard, upload server and nginx) with a volume at /data for local backup storage and uploads. postgres is PostgreSQL 17 with a volume at /var/lib/postgresql, holding the console's own data: users, organizations, agents, backup policies and history.

No default login. The superadmin is admin@example.com, created at first boot from the generated AUTH_DEFAULT_PASSWORD (48 characters, generated with a lower-case letter, an upper-case letter, a digit and a special character, which Portabase requires). The wrapper refuses to start with an empty password or signing secret. Anonymous sign-up is off, so nobody else can register.

What the wrapper fixes for Railway. Upstream's nginx listens on a fixed port 80, so the wrapper points it at Railway's injected PORT. It builds the database URL from the postgres service's private host and password, waits for the database, and sets the public URL and trusted origin from the generated domain so sign-in works behind the Railway edge. It switches on the REST API and its OpenAPI description, and switches off telemetry.

Using it. Sign in at https://YOUR_DOMAIN/ with admin@example.com and AUTH_DEFAULT_PASSWORD, create an organization, add an agent and run the agent next to each database you want to protect. The agent connects to your public URL and reports its databases, then backups run on the schedule you set and are stored locally on the volume or in an S3 bucket you configure.

Agent contract

  • Public URL: https://RAILWAY_PUBLIC_DOMAIN (the generated domain of the portabase service)
  • Private URL: http://portabase.railway.internal:8080
  • Credentials: the variable AUTH_DEFAULT_PASSWORD on the portabase service (the password of the fixed user admin@example.com, which is not a template variable)
  • Auth: sign in with POST /api/auth/sign-in/email (JSON email and password, with an Origin header equal to the public URL) to get a session cookie, then mint an API key with POST /api/auth/api-key/create (configId standard); every /api/v1 call sends the key in the x-api-key header. A request with no key or a wrong key answers 401.
  • Health: GET /api/health returns 200
#!/bin/sh
# needs: RAILWAY_PUBLIC_DOMAIN, AUTH_DEFAULT_PASSWORD (variables of the portabase service); also curl.
R="https://$RAILWAY_PUBLIC_DOMAIN"; J="Content-Type: application/json"; O="Origin: $R"; JAR=$(mktemp); B=$(mktemp)
n=0; until [ "$(curl -s -o /dev/null -w '%{http_code}' "$R/api/health")" = 200 ]; do n=$((n+1)); [ "$n" -le 60 ] || break; sleep 5; done
curl -s -o /dev/null -w "health: %{http_code}\n" "$R/api/health"
# sign in as the fixed superadmin admin@example.com (better-auth wants an Origin header equal to the public URL)
curl -s -c "$JAR" -o /dev/null -w "sign-in: %{http_code}\n" -H "$O" -H "$J" -d "{\"email\":\"admin@example.com\",\"password\":\"$AUTH_DEFAULT_PASSWORD\"}" "$R/api/auth/sign-in/email"
# mint an API key of the standard kind; every /api/v1 call then sends it in the x-api-key header
curl -s -b "$JAR" -H "$O" -H "$J" -d '{"name":"agent","configId":"standard"}' -o "$B" "$R/api/auth/api-key/create"
K=$(sed -n 's/.*"key":"\([^"]*\)".*/\1/p' "$B"); KID=$(sed -n 's/^{"[^}]*"id":"\([^"]*\)".*/\1/p' "$B")
curl -s -o /dev/null -w "read with key: %{http_code}\n" -H "x-api-key: $K" "$R/api/v1/agents"
curl -s -o "$B" -w "write with key: %{http_code}\n" -H "x-api-key: $K" -H "$J" -d '{"name":"railway-check"}' "$R/api/v1/agents"
AID=$(sed -n 's/.*"data":{"id":"\([^"]*\)".*/\1/p' "$B")
curl -s -H "x-api-key: $K" "$R/api/v1/agents" | grep -c '"railway-check"' | sed 's/^/agent found after write: /'
curl -s -o /dev/null -w "delete with key: %{http_code}\n" -X DELETE -H "x-api-key: $K" "$R/api/v1/agents/$AID"
curl -s -o /dev/null -w "read without key: %{http_code}\n" "$R/api/v1/agents"
curl -s -o /dev/null -w "write without key: %{http_code}\n" -H "$J" -d '{"name":"anonymous"}' "$R/api/v1/agents"
curl -s -o /dev/null -w "write wrong key: %{http_code}\n" -H "x-api-key: sk_wrong" -H "$J" -d '{"name":"anonymous"}' "$R/api/v1/agents"
# revoke the key this run minted
curl -s -b "$JAR" -o /dev/null -w "revoke key: %{http_code}\n" -H "$O" -H "$J" -d "{\"keyId\":\"$KID\",\"configId\":\"standard\"}" "$R/api/auth/api-key/delete"

A fresh deploy prints health: 200, sign-in: 200, read with key: 200, write with key: 201, agent found after write: 1 and delete with key: 204. The refusals print read without key: 401, write without key: 401 and write wrong key: 401: a request with no key or a wrong one creates nothing.

Why Deploy Portabase on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Portabase on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

  • Agent-ready - generated secrets, a contract block and one script that proves health, sign-in, key creation, an authenticated write, read-back and delete, and the refusal of a read and a write with no key or a wrong key.
  • No setup form and no default login - the superadmin is created at boot from a generated password, and sign-up is closed.
  • Data survives redeploys - the console's database and the local backup storage sit on volumes.
  • Works behind the Railway edge - the listen port follows PORT and the public URL is set from the generated domain.
  • Pinned - the upstream image is pinned by digest and the wrapper by tag and digest.

Common Use Cases

  • Scheduled database backups - run backups of PostgreSQL, MySQL, MariaDB or MongoDB on a schedule with retention policies from one dashboard.
  • One-click restore - restore a stored backup to the same or another database from the console or the API.
  • Backup status for a team - give each person a login, group databases by organization and project, and alert on failed backups.
  • Backup automation for AI agents - an agent mints a key and registers agents, reads backup status and triggers backups or restores over the REST API.

Dependencies for Portabase Hosting

  • The portabase and postgres services with their volumes, created by the template. The databases you want to back up are separate; each one is reached by a Portabase agent that you run next to it.

Deployment Dependencies


Template Content

More templates in this category

View Template
RustFS | (Just Updated) S3 Object Store, Public URL and Keys Set
S3-compatible object store, keys and public URL preset, volume kept

SuperSlowSloth
0
View Template
TimescaleDB
A PostgreSQL-based time-series database for analytics on Railway.

Rakit
1
View Template
NEW
Neo4j 2026.10 Community
Neo4j graph database with APOC, Browser, Bolt TCP proxy and a volume

My Projects
0