Deploying Instant Open-Source Firebase Alternative on Ubuntu 24.04
Step-by-step guide to deploy InstantDB with PostgreSQL, Docker Compose, and Traefik on Ubuntu 24.04 as a self-hosted, real-time backend with automatic HTTPS.

Instant (InstantDB) is an open-source, real-time backend platform (a self-hosted alternative to Firebase) built around a PostgreSQL store with relational queries, authentication, and live sync. This guide deploys Instant using Docker Compose with PostgreSQL and Traefik for automatic HTTPS, following real-time backend deployment practices documented in Vultr Docs.
Set Up the Directory Structure
1. Create the project directory and clone Instant:
mkdir ~/instant
cd ~/instant
git clone https://github.com/instantdb/instant.git app
cd app/server
2. Move the bundled Compose file aside (we'll provide our own):
mv docker-compose.yml docker-compose.yml.bak
3. Create the environment file:
nano .env
TZ=UTC
DOMAIN=instant.example.com
EMAIL=admin@example.com
POSTGRES_USER=instant
POSTGRES_PASSWORD=YOUR_DATABASE_PASSWORD
POSTGRES_DB=instant
Deploy with Docker Compose
1. Create the Compose manifest:
nano docker-compose.yml
services:
traefik:
image: traefik:v3.6
container_name: traefik
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=${EMAIL}"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./letsencrypt:/letsencrypt"
restart: unless-stopped
postgres:
image: ghcr.io/instantdb/postgresql:postgresql-16-pg-hint-plan
container_name: postgres
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- ./postgres-data:/var/lib/postgresql/data
command:
- postgres
- -c
- wal_level=logical
- -c
- max_replication_slots=4
- -c
- max_wal_senders=4
- -c
- shared_preload_libraries=pg_hint_plan
- -c
- random_page_cost=1.1
healthcheck:
test: ["CMD", "pg_isready", "-U", "instant"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
server:
build:
context: .
dockerfile: Dockerfile-dev
container_name: instant
working_dir: /app
command: ["make", "dev-oss"]
depends_on:
postgres:
condition: service_healthy
environment:
TZ: ${TZ}
DATABASE_URL: "postgresql://\({POSTGRES_USER}:\){POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}"
NREPL_BIND_ADDRESS: "0.0.0.0"
volumes:
- ./:/app
expose:
- "8888"
labels:
- "traefik.enable=true"
- "traefik.http.routers.instant.rule=Host(`${DOMAIN}`)"
- "traefik.http.routers.instant.entrypoints=websecure"
- "traefik.http.routers.instant.tls.certresolver=letsencrypt"
- "traefik.http.services.instant.loadbalancer.server.port=8888"
restart: unless-stopped
2. Build and start the stack:
docker compose up -d --build
3. Verify the services and tail logs:
docker compose ps
docker compose logs
Verify the Backend
1. Test the HTTPS endpoint:
curl https://instant.example.com
You should see:
<code>Welcome to Instant's Backend!</code>
Note: First request may take ~1 minute while Let's Encrypt issues the certificate.
2. Confirm in a browser:
Open https://instant.example.com and verify the page loads over HTTPS.
Verify Database Connectivity
1. Open a psql session inside the postgres container:
docker compose exec postgres psql -U instant -d instant
2. Run sample DDL/DML:
CREATE TABLE messages (id SERIAL PRIMARY KEY, content TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW());
INSERT INTO messages (content) VALUES ('Hello from Instant'), ('Real-time sync test');
SELECT id, content, created_at FROM messages ORDER BY created_at DESC;
\q
3. Review backend logs:
docker compose logs --tail=20 server
Next Steps
Instant is running and served securely over HTTPS. From here you can:
Wire client SDKs against your domain for live-sync apps
Configure authentication providers and per-table permissions
Set up backups against the
postgres-datavolume for durability
For the full guide with additional tips, visit the original article on Vultr Docs.





