Skip to content

Self-Hosting

Salient is designed to run on minimal infrastructure. The reference deployment uses a single $6/mo DigitalOcean droplet with Docker Compose.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended) with at least 512MB RAM + 2GB swap
  • Docker and Docker Compose installed
  • A domain name with DNS pointing to your server
  • (Optional) GitHub/Google OAuth app credentials for authentication
  • (Optional) An AI provider API key for enhanced scoring

Quick Deploy

1. Clone and Configure

git clone https://github.com/noperse/projectTTX_Salient.git
cd projectTTX_Salient
cp .env.example .env

Edit .env with your settings (see Configuration for all variables).

2. Start Production Stack

make prod

This runs docker-compose.prod.yml, which starts:

  • Caddy — reverse proxy with auto-TLS via Let's Encrypt
  • Backend — FastAPI server with 256MB memory limit

Caddy serves the React frontend as static files (built during the Docker image build) and proxies API requests to the backend.

3. Verify

make status    # Show container health and resource usage
make logs      # Tail container logs

Visit https://your-domain.com — you should see the Salient login page.

Architecture

Internet ──► Caddy (:443, auto-TLS)
                ├── Static React build (/)
                ├── API proxy (/api/*)
                └── Auth proxy (/auth/*)
                FastAPI Backend (:8000)
                SQLite (data/session_data.db)

Make Commands

Command Description
make dev Start development stack (backend:8000 + frontend:3000)
make prod Start production stack (Caddy + backend)
make stop Stop all containers
make restart Stop, rebuild, and start production
make update Git pull + rebuild
make logs Tail container logs
make status Show containers and resource usage

TLS Configuration

Caddy handles TLS automatically via Let's Encrypt. Requirements:

  • SALIENT_DOMAIN set in .env
  • DNS A record pointing to your server's IP
  • Ports 80 and 443 open

No manual certificate management

Caddy obtains and renews certificates automatically. No certbot, no cron jobs, no manual renewal.

IP Restriction

Set ALLOWED_IPS in .env to restrict access to specific IP addresses:

ALLOWED_IPS=203.0.113.50,198.51.100.25

For dynamic IPs, use the self-service update endpoint with UPDATE_IP_TOKEN.

Resource Usage

The production stack runs within a 512MB RAM / 2GB swap envelope:

Component Memory
Caddy ~20MB
FastAPI + fastembed ~200MB
SQLite Negligible

Budget constraint

The $10/mo hard cap means a single $6/mo droplet. Docker images are built in CI (GitHub Actions) and pushed to GHCR — the droplet only pulls pre-built images, avoiding build-time memory pressure.

Configuration · Architecture