Skip to content

Docker / Hono Standalone Deployment

PSI can be deployed as a standalone Hono server (via @hono/node-server) in a Docker container, without Firebase Cloud Functions. This is useful for partners deploying on their own infrastructure or using MongoDB.

Architecture

In standalone mode:

Component How It Runs
Frontend Static SPA served by nginx (or any static file server)
Backend Hono server in a Docker container, port 5001
Database Firebase RTDB (default) or MongoDB (via adapter)
Auth Firebase Auth (still required for token management)

Dockerfile

The project provides Dockerfile.server for multi-stage builds:

# Multi-stage build
FROM node:22-alpine AS build
# ... installs pnpm, builds server with tsc

FROM node:22-alpine AS runtime
# ... copies built artifacts, runs express-index.js on port 5001

Key details:

  • Base image: node:22-alpine (minimal)
  • Uses pnpm deploy --filter for optimized production dependencies
  • Entry point: node lib/index.js (standalone Hono server)
  • Exposes port 5001
  • Health check: GET /health/live

Quick Start

1. Build the Docker Image

docker build -f Dockerfile.server -t psi-server .

2. Configure Environment Variables

Create a .env file:

AUTH_SECRET=your-secret-key
DATABASE_URL=https://your-project-rtdb.firebasedatabase.app
HOSTING_DOMAIN=https://your-domain.com
PORT=5001

# For MongoDB instead of Firebase RTDB:
# DATABASE_ADAPTER=mongodb
# MONGODB_URL=mongodb://localhost:27017/psi-database

# Optional services:
# OPENAI_KEY=sk-...
# PERSPECTIVE_API_KEY=...
# EMAIL_PROVIDER=smtp
# SMTP_MAIL_SERVER=smtp.example.com

3. Run the Container

docker run -p 5001:5001 --env-file .env psi-server

4. Build and Serve the Frontend

cd client && pnpm run webbuild
# Serve client/dist with nginx, Apache, or any static file server

Configure your web server to:

  • Serve static files from client/dist
  • Rewrite /api/* requests to the backend container (port 5001)
  • Serve index.html for all other routes (SPA fallback)

Docker Compose Example

services:
  psi-server:
    build:
      context: .
      dockerfile: Dockerfile.server
    ports:
      - "5001:5001"
    env_file:
      - server/.env
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost:5001/health/live"]
      interval: 30s
      timeout: 10s
      retries: 3

  psi-frontend:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./client/dist:/usr/share/nginx/html
    depends_on:
      - psi-server

Using MongoDB

To use MongoDB instead of Firebase Realtime Database:

  1. Set environment variables:

    DATABASE_ADAPTER=mongodb
    MONGODB_URL=mongodb://your-mongo-host:27017/psi-database
    

  2. The MongoDB adapter automatically creates collections:

  3. instances -- instance properties
  4. collection_objects -- per-instance collections
  5. moduledata_private, moduledata_public, etc. -- module data
  6. silos -- silo configuration

See MongoDB Adapter for schema details.

Further Reading