FeatureSignals

Self-Hosting Onboarding Guide

A complete walkthrough for deploying and operating FeatureSignals on your own infrastructure — from initial requirements through production hardening, backup strategy, and ongoing monitoring.

Before you begin

This guide assumes familiarity with Linux server administration, Docker, PostgreSQL, and TLS certificate management. If you're looking for a managed experience, check out FeatureSignals Cloud.

System Requirements

ResourceMinimumRecommended
CPU2 vCPUs4+ vCPUs
Memory4 GB RAM8+ GB RAM
Disk20 GB SSD50+ GB SSD (with room for growth)
PostgreSQL14+16+ (with streaming replication)
Docker24.0+Latest stable
Docker Composev2+Latest stable
OSUbuntu 22.04 / Debian 12Ubuntu 24.04 LTS

Database sizing

For production deployments serving more than 10 million evaluations per day, use a dedicated PostgreSQL instance (not co-located on the application server) with at least 4 vCPUs and 16 GB RAM. Enable connection pooling via PgBouncer.

Installation

FeatureSignals is distributed as a set of Docker images. The recommended deployment method is Docker Compose:

1. Clone the Repository

Bash
1
2
git clone https://github.com/dinesh-g1/featuresignals.git
cd featuresignals

2. Configure Environment

Copy the example environment file and customize it for your deployment:

Bash
1
2
3
cp .env.example .env
# Edit .env with your configuration values
nano .env

Key environment variables to configure:

  • DATABASE_URL — PostgreSQL connection string
  • JWT_SECRET — Random 64+ character secret for token signing
  • API_BASE_URL — Public URL where the API server is reachable
  • APP_BASE_URL — Public URL where the dashboard is reachable
  • SMTP_* — SMTP server settings for transactional email

3. Start the Services

Bash
1
docker compose up -d

This starts PostgreSQL, the API server (port 8080), and the Flag Engine dashboard (port 3000). Database migrations run automatically on first startup.

4. Verify Installation

Bash
1
2
3
4
5
6
7
8
# Check that all services are running
docker compose ps


# Verify the API server responds
curl http://localhost:8080/health


# Verify the dashboard is accessible
curl http://localhost:3000

SSL / TLS Setup

FeatureSignals must be served over HTTPS in production. The recommended approach is to place a reverse proxy (nginx or Caddy) in front of the application:

Option A: Caddy (Recommended)

Caddy automatically obtains and renews TLS certificates via Let's Encrypt:

CaddyfilePlaintext
1
2
3
4
5
6
7
featuresignals.example.com {
    reverse_proxy localhost:3000
}


api.featuresignals.example.com {
    reverse_proxy localhost:8080
}

Option B: nginx + Certbot

Traditional nginx setup with Certbot for certificate management:

Bash
1
2
sudo apt install nginx certbot python3-certbot-nginx
sudo certbot --nginx -d featuresignals.example.com -d api.featuresignals.example.com

Backup Strategy

A comprehensive backup strategy protects against data loss. The most critical data to back up is the PostgreSQL database:

Database Backups

Use pg_dump for logical backups. Schedule this as a cron job:

/etc/cron.d/featuresignals-backupBash
1
2
3
4
5
# Daily database backup at 2 AM UTC
0 2 * * * postgres pg_dump -U featuresignals featuresignals | gzip > /backups/featuresignals-$(date +\%Y\%m\%d).sql.gz


# Retain last 30 days of backups
0 3 * * * postgres find /backups -name "featuresignals-*.sql.gz" -mtime +30 -delete

Info

For production deployments, also configure Point-in-Time Recovery (PITR) by enabling PostgreSQL WAL archiving. This allows you to restore to any point in time, not just to the last daily backup.

What to Back Up

  • PostgreSQL database — All configuration data: flags, segments, projects, environments, API keys, audit logs
  • Environment configuration — Your .env file (contains secrets and connection strings)
  • TLS certificates — If not using auto-renewal (Caddy handles this automatically)
  • Custom configurations — Any modified nginx/Caddy configs, custom migration scripts

Restore Procedure

Bash
1
2
3
4
5
6
7
8
# 1. Stop the application
docker compose down


# 2. Restore the database
gunzip < /backups/featuresignals-20260115.sql.gz | psql -U featuresignals featuresignals


# 3. Restart the application
docker compose up -d

Monitoring

A healthy self-hosted deployment requires monitoring at multiple levels:

Application Health

  • Monitor /health endpoint (returns 200 when server is alive)
  • Monitor /ready endpoint (returns 200 when database is reachable)
  • Export server metrics in OpenTelemetry format for integration with SigNoz, Grafana, or Datadog
  • Set alerts for 5xx error rate exceeding 0.1%

Database Monitoring

  • Track connection pool utilization — alert if above 80% of max connections are in use
  • Monitor replication lag if using read replicas
  • Watch for long-running queries (longer than 1 second) that may indicate missing indexes
  • Set up automated vacuum and analyze maintenance windows

Infrastructure Monitoring

  • Disk usage — alert at 80%, critical at 90%
  • Memory usage — track RSS and cache utilization
  • CPU load — alert on sustained above 80% utilization
  • Network throughput — monitor for unusual traffic patterns

Security Hardening

Use a dedicated, non-root user for the FeatureSignals services
Place the application behind a firewall — only expose ports 80/443 to the internet
Enable automatic security updates for the host OS
Rotate JWT secrets and API keys on a regular schedule (recommended: every 90 days)
Configure fail2ban to block repeated failed authentication attempts
Regularly run govulncheck and npm audit on the codebase to catch dependency vulnerabilities
Use network isolation — place the database on a private subnet not accessible from the public internet

Upgrades

To upgrade FeatureSignals to a new version:

Bash
1
2
3
4
5
6
7
8
9
# Pull the latest images
docker compose pull


# Apply any new database migrations and restart
docker compose up -d


# Verify the upgrade
docker compose ps
curl http://localhost:8080/health

Before upgrading

Always back up your database before applying upgrades. Review the changelog for breaking changes, especially database migration changes that cannot be rolled back.

Next Steps