Production deployment and configuration best practices
git clone <repository_url>
cd thalamus
cp .env.production.example .env.production
nano .env.production
# Application
PHX_HOST=your-domain.com
PHX_PORT=4000
SECRET_KEY_BASE=your-64-char-secret
# Database
DATABASE_URL=ecto://user:pass@localhost:5432/thalamus_prod
DB_POOL_SIZE=20
# Redis (optional but recommended)
REDIS_URL=redis://:password@localhost:6379/0
# Email (SendGrid, Mailgun, or AWS SES)
SMTP_RELAY=smtp.sendgrid.net
SMTP_USERNAME=apikey
SMTP_PASSWORD=YOUR_SENDGRID_API_KEY
FROM_EMAIL=noreply@your-domain.com
# Security
ENABLE_SSL=true
FORCE_SSL=true
mix phx.gen.secret 64
or openssl rand -base64 64
docker-compose up -d
docker-compose exec thalamus bin/thalamus eval "Thalamus.Release.migrate()"
docker-compose logs -f thalamus
curl https://your-domain.com/api/public/health
Expected response: JSON with status=ok, version, and checks for database and cache.
For full control over your deployment, follow these steps to deploy Thalamus manually on a Linux server.
sudo apt update
sudo apt install -y build-essential git postgresql-16 nginx certbot
sudo -u postgres createuser -P thalamus_user
sudo -u postgres createdb -O thalamus_user thalamus_prod
git clone <repository_url> ~/thalamus
cd ~/thalamus
mix deps.get --only prod
MIX_ENV=prod mix assets.deploy
MIX_ENV=prod mix release
Create /etc/systemd/system/thalamus.service:
[Unit]
Description=ZEA Thalamus OAuth2 Server
After=network.target postgresql.service
[Service]
Type=exec
User=thalamus
WorkingDirectory=/home/thalamus/thalamus
Environment=MIX_ENV=prod
EnvironmentFile=/home/thalamus/thalamus/.env.production
ExecStart=/home/thalamus/thalamus/_build/prod/rel/thalamus/bin/thalamus start
ExecStop=/home/thalamus/thalamus/_build/prod/rel/thalamus/bin/thalamus stop
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable thalamus
sudo systemctl start thalamus
sudo systemctl status thalamus
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
Certbot will automatically configure Nginx with SSL and set up auto-renewal.
Create /etc/nginx/sites-available/thalamus with:
See DEPLOYMENT_GUIDE.md in the repository for complete Nginx configuration.
Thalamus requires email configuration for user verification, password reset, and notifications.
100 emails/day free
Easy setup, reliable
100 emails/day free
Developer-friendly
62k emails/month free
AWS account required
SMTP_RELAY=smtp.sendgrid.net
SMTP_USERNAME=apikey
SMTP_PASSWORD=SG.your-api-key-here
SMTP_PORT=587
SMTP_TLS=always
FROM_EMAIL=noreply@your-domain.com
FROM_NAME="ZEA Thalamus"
| Item | Status | Priority |
|---|---|---|
| SSL/TLS enabled (HTTPS) |
Critical
|
|
| SECRET_KEY_BASE is 64+ characters |
Critical
|
|
| Firewall configured (ports 80, 443 only) |
Critical
|
|
| Database password is strong (16+ chars) |
High
|
|
| Redis password configured |
High
|
|
| Automated database backups |
High
|
|
| Email sending tested |
Medium
|
|
| Monitoring and alerts configured |
Medium
|
Monitor your Thalamus instance with:
curl https://your-domain.com/api/public/health
# Docker
docker-compose logs -f thalamus
# Systemd
sudo journalctl -u thalamus -f
Create a daily backup script:
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
pg_dump -U thalamus_user thalamus_prod | \
gzip > /backup/thalamus_$DATE.sql.gz
# Keep last 30 days
find /backup -name "thalamus_*.sql.gz" -mtime +30 -delete