Documentation Index
Fetch the complete documentation index at: https://mintlify.com/budgetron-org/budgetron/llms.txt
Use this file to discover all available pages before exploring further.
This guide covers production deployment best practices, security hardening, monitoring, and operational procedures for running Budgetron at scale.
Production Checklist
Before deploying to production:
Security Hardening
Environment Variables
Never commit secrets to version control. Use secure secret management:
Generate Strong Secrets
# AUTH_SECRET (32+ bytes)
openssl rand -base64 32
# CRON_SECRET_TOKEN (hex format)
openssl rand -hex 32
# CRON_SECRET_SLUG
openssl rand -hex 16
Secret Management
Docker Secrets (Docker Swarm):
echo "your-secret" | docker secret create auth_secret -
services:
app:
secrets:
- auth_secret
environment:
AUTH_SECRET_FILE: /run/secrets/auth_secret
secrets:
auth_secret:
external: true
Kubernetes Secrets:
kubectl create secret generic budgetron-secrets \
--from-literal=AUTH_SECRET=$(openssl rand -base64 32) \
--from-literal=DB_URL="postgres://..."
HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault for enterprise deployments.
Database Security
Connection Security
Use SSL for database connections:
DB_URL="postgres://user:pass@host:5432/db?sslmode=require"
SSL modes:
require - Requires SSL, no certificate verification
verify-ca - Requires SSL, verifies CA
verify-full - Requires SSL, verifies CA and hostname
Network Isolation
Restrict database access:
# PostgreSQL pg_hba.conf
host budgetron budgetron 10.0.0.0/8 scram-sha-256
Use private networks or VPC for database connections.
Database User Permissions
Create a limited database user:
-- Create user with minimal privileges
CREATE USER budgetron_app WITH PASSWORD 'secure_password';
GRANT CONNECT ON DATABASE budgetron TO budgetron_app;
GRANT USAGE ON SCHEMA public TO budgetron_app;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO budgetron_app;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO budgetron_app;
-- For migrations, use separate user
CREATE USER budgetron_migrate WITH PASSWORD 'different_password';
GRANT ALL PRIVILEGES ON DATABASE budgetron TO budgetron_migrate;
Application Security
Run as Non-Root User
Modify Dockerfile:
# Add before CMD
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
RUN chown -R nextjs:nodejs /app
USER nextjs
Read-Only Filesystem
Run container with read-only root:
docker run --read-only \
--tmpfs /tmp \
--tmpfs /app/.next/cache \
budgetron
Next.js automatically sets security headers. Verify in next.config.ts:
const nextConfig: NextConfig = {
headers: async () => [
{
source: '/:path*',
headers: [
{ key: 'X-DNS-Prefetch-Control', value: 'on' },
{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'Referrer-Policy', value: 'origin-when-cross-origin' },
],
},
],
}
Network Security
Firewall Configuration
Use UFW (Ubuntu):
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
Rate Limiting
Configure Nginx rate limiting:
http {
limit_req_zone $binary_remote_addr zone=budgetron:10m rate=10r/s;
server {
location / {
limit_req zone=budgetron burst=20 nodelay;
proxy_pass http://localhost:3000;
}
}
}
DDoS Protection
Use Cloudflare or AWS WAF for DDoS protection and CDN caching.
High Availability
Load Balancing
Run multiple Budgetron instances behind a load balancer:
# docker-compose.yml
services:
app:
image: ghcr.io/budgetron-org/budgetron:latest
deploy:
replicas: 3
restart_policy:
condition: on-failure
environment:
DB_URL: ${DB_URL}
# ... other env vars
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- app
Nginx upstream configuration:
upstream budgetron {
least_conn;
server app:3000 max_fails=3 fail_timeout=30s;
server app:3000 max_fails=3 fail_timeout=30s;
server app:3000 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
location / {
proxy_pass http://budgetron;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
}
}
Database High Availability
PostgreSQL Replication
Set up primary-replica replication:
# Primary
postgresql.conf:
wal_level = replica
max_wal_senders = 3
pg_hba.conf:
host replication replicator 10.0.0.0/8 scram-sha-256
Managed Database Services
Use managed PostgreSQL for automatic failover:
- AWS RDS with Multi-AZ
- Google Cloud SQL with high availability
- Azure Database for PostgreSQL with read replicas
- DigitalOcean Managed Databases
Health Checks
Implement comprehensive health checks:
// app/api/health/route.ts
import { db } from '@/server/db'
import { NextResponse } from 'next/server'
export async function GET() {
try {
// Check database connectivity
await db.execute('SELECT 1')
return NextResponse.json({
status: 'healthy',
timestamp: new Date().toISOString(),
database: 'connected',
})
} catch (error) {
return NextResponse.json(
{
status: 'unhealthy',
error: error.message,
},
{ status: 503 }
)
}
}
Docker health check:
HEALTHCHECK --interval=30s --timeout=5s --start-period=40s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => { \
if (r.statusCode !== 200) process.exit(1); \
let data = ''; \
r.on('data', chunk => data += chunk); \
r.on('end', () => { \
const json = JSON.parse(data); \
process.exit(json.status === 'healthy' ? 0 : 1); \
}); \
}).on('error', () => process.exit(1))"
Monitoring and Observability
Logging
Structured Logging
Budgetron logs to stdout/stderr. Use a log aggregation service:
Docker Compose with Loki:
services:
app:
logging:
driver: loki
options:
loki-url: "http://localhost:3100/loki/api/v1/push"
loki-retries: 5
Centralized Logging Services:
- Datadog
- New Relic
- Papertrail
- Logtail
- ELK Stack (Elasticsearch, Logstash, Kibana)
Log Rotation
For standalone deployments:
# /etc/logrotate.d/budgetron
/var/log/budgetron/*.log {
daily
rotate 30
compress
delaycompress
notifempty
create 0640 budgetron budgetron
sharedscripts
postrotate
pm2 reloadLogs
endscript
}
Metrics
Application Metrics
Integrate Prometheus metrics:
// lib/metrics.ts
import { Registry, Counter, Histogram } from 'prom-client'
export const register = new Registry()
export const httpRequestDuration = new Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status'],
registers: [register],
})
export const httpRequestTotal = new Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status'],
registers: [register],
})
// app/api/metrics/route.ts
import { register } from '@/lib/metrics'
import { NextResponse } from 'next/server'
export async function GET() {
const metrics = await register.metrics()
return new NextResponse(metrics, {
headers: { 'Content-Type': register.contentType },
})
}
Database Metrics
Monitor PostgreSQL:
-- Active connections
SELECT count(*) FROM pg_stat_activity WHERE datname = 'budgetron';
-- Database size
SELECT pg_size_pretty(pg_database_size('budgetron'));
-- Slow queries
SELECT query, calls, total_time, mean_time
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;
Use monitoring tools:
- pgAdmin
- pganalyze
- pg_stat_statements extension
Infrastructure Metrics
Prometheus + Grafana:
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3001:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
GF_SECURITY_ADMIN_PASSWORD: admin
Alerting
Health Check Monitoring
Use uptime monitoring:
- UptimeRobot (free tier available)
- Pingdom
- Better Uptime
- StatusCake
Custom Alerts
Prometheus alerting rules:
groups:
- name: budgetron
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate detected"
description: "Error rate is {{ $value }} errors/second"
- alert: DatabaseConnectionFailed
expr: up{job="postgres"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Database connection failed"
Backup and Recovery
Database Backups
Automated Backup Script
#!/bin/bash
# /usr/local/bin/backup-budgetron.sh
set -e
# Configuration
BACKUP_DIR="/var/backups/budgetron"
S3_BUCKET="s3://my-backups/budgetron"
DB_URL="postgres://user:pass@localhost:5432/budgetron"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/budgetron_$DATE.sql.gz"
# Create backup directory
mkdir -p $BACKUP_DIR
# Dump database
echo "Starting backup at $(date)"
pg_dump "$DB_URL" | gzip > "$BACKUP_FILE"
# Verify backup
if [ -f "$BACKUP_FILE" ] && [ $(stat -f%z "$BACKUP_FILE") -gt 1000 ]; then
echo "Backup created successfully: $BACKUP_FILE"
else
echo "ERROR: Backup failed or is too small"
exit 1
fi
# Upload to S3 (optional)
if command -v aws &> /dev/null; then
echo "Uploading to S3..."
aws s3 cp "$BACKUP_FILE" "$S3_BUCKET/"
fi
# Remove old backups
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed at $(date)"
Make executable and schedule:
chmod +x /usr/local/bin/backup-budgetron.sh
sudo crontab -e
# Daily backup at 2 AM
0 2 * * * /usr/local/bin/backup-budgetron.sh >> /var/log/budgetron-backup.log 2>&1
Point-in-Time Recovery (PITR)
Enable WAL archiving in PostgreSQL:
# postgresql.conf
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /mnt/wal_archive/%f && cp %p /mnt/wal_archive/%f'
archive_timeout = 3600
Application State Backup
Budgetron is stateless, but back up:
- Environment variables (securely)
- Custom configurations
- SSL certificates
Disaster Recovery
Recovery Procedure
- Restore Database:
gunzip -c budgetron_20260305_020000.sql.gz | psql "$DB_URL"
- Deploy Application:
docker run -d \
--name budgetron \
--env-file .env \
-p 3000:3000 \
ghcr.io/budgetron-org/budgetron:latest
- Verify:
curl http://localhost:3000/api/health
Test Recovery
Regularly test your recovery procedure:
# Test restoration to a separate database
createdb budgetron_test
gunzip -c latest_backup.sql.gz | psql budgetron_test
# Verify data integrity
psql budgetron_test -c "SELECT COUNT(*) FROM transactions;"
Database Optimization
Connection Pooling
Budgetron uses Drizzle ORM with connection pooling. Configure pool size:
// For high-traffic deployments
import { drizzle } from 'drizzle-orm/node-postgres'
import { Pool } from 'pg'
const pool = new Pool({
connectionString: process.env.DB_URL,
max: 20, // Maximum pool size
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
})
export const db = drizzle(pool)
Database Indexes
Ensure proper indexes exist:
-- Example: Index on user transactions
CREATE INDEX idx_transactions_user_date ON transactions(user_id, date DESC);
CREATE INDEX idx_transactions_category ON transactions(category_id);
Query Optimization
Monitor slow queries:
-- Enable pg_stat_statements
CREATE EXTENSION pg_stat_statements;
-- Find slow queries
SELECT
query,
calls,
total_exec_time,
mean_exec_time,
max_exec_time
FROM pg_stat_statements
WHERE mean_exec_time > 100 -- queries taking >100ms
ORDER BY mean_exec_time DESC
LIMIT 20;
Application Optimization
Caching
Next.js App Router includes built-in caching. Configure cache headers:
export const revalidate = 3600 // Revalidate every hour
CDN Integration
Use a CDN for static assets:
- Cloudflare
- AWS CloudFront
- Vercel Edge Network
Resource Limits
Set container resource limits:
services:
app:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
Deployment Strategies
Blue-Green Deployment
# Deploy new version (green)
docker run -d --name budgetron-green \
--env-file .env \
-p 3001:3000 \
ghcr.io/budgetron-org/budgetron:latest
# Test green deployment
curl http://localhost:3001/api/health
# Switch traffic (update load balancer)
# If successful, remove blue
docker stop budgetron-blue
docker rm budgetron-blue
Rolling Updates
With Docker Swarm or Kubernetes:
docker service update \
--image ghcr.io/budgetron-org/budgetron:v0.2.0 \
--update-parallelism 1 \
--update-delay 30s \
budgetron
Rollback Procedure
# Docker
docker stop budgetron
docker run -d --name budgetron \
--env-file .env \
-p 3000:3000 \
ghcr.io/budgetron-org/budgetron:v0.1.0 # Previous version
# Kubernetes
kubectl rollout undo deployment/budgetron
Compliance and Auditing
Audit Logging
Log all authentication and sensitive operations:
import { logger } from '@/lib/logger'
// Log authentication events
logger.info('User login', {
userId: user.id,
ip: request.ip,
timestamp: new Date().toISOString(),
})
Data Privacy
- Implement GDPR data export/deletion
- Encrypt sensitive data at rest
- Use TLS 1.3 for data in transit
- Regular security audits
Compliance Checklist
Next Steps