Prepare a Linux host
You need Docker Engine with the Compose plugin, a publicly reachable application URL for hosted SDK clients, and persistent disk for PostgreSQL and Redis volumes. Put TLS termination in front of port 3005 for production.
Copy the environment template
Keep .env private. It contains database and application secrets and must not be committed to Git.
git clone https://github.com/ignatius22/experimentlab.git
cd experimentlab
cp .env.example .envSet production values
Use a new 64-character AUTH_SECRET, a strong database password, and your real public URL. Generate the secret in your terminal, then paste its output into .env; environment files do not run shell commands.
openssl rand -hex 32POSTGRES_PASSWORD="use-a-strong-password"
DATABASE_URL="postgresql://experiment_user:use-a-strong-password@postgres:5432/experimentlab_db?schema=public"
AUTH_SECRET="paste-a-generated-64-character-secret-here"
REDIS_URL="redis://redis:6379"
NEXT_PUBLIC_APP_URL="https://flags.example.com"Enable billing on your own instance (optional)
Only add these variables if you operate a hosted service and want to charge your own customers through Paystack. Leaving them unset runs ExperimentLab as a community-only instance: checkout, subscription management, and Paystack webhooks stay disabled.
# Optional: enable Team-plan billing on your own instance
PAYSTACK_SECRET_KEY="sk_..."
PAYSTACK_PUBLIC_KEY="pk_..."
PAYSTACK_TEAM_PLAN_CODE="PLN_..."Start the stack
The web service listens on host port 3005. Redis buffers event ingestion and the worker flushes queued events to PostgreSQL.
docker compose up -d --build
docker compose psOperate it deliberately
Back up PostgreSQL before database migrations. Use explicit, reviewed releases for production and confirm the web health endpoint after every deployment.
- Keep PostgreSQL and Redis volumes on persistent storage
- Never put server API keys or
.envin client code - Apply migrations before replacing application containers