Database Setup
Rack Gateway requires PostgreSQL 14+ for storing users, API tokens, audit logs, and session data.
Requirements
Section titled “Requirements”| Requirement | Minimum | Recommended |
|---|---|---|
| PostgreSQL version | 14 | 16 |
| Storage | 10GB | 50GB+ (scales with audit logs) |
| Memory | 256MB | 1GB+ |
| Connections | 25 | 50+ |
Connection Configuration
Section titled “Connection Configuration”Connection String
Section titled “Connection String”Set the DATABASE_URL environment variable:
DATABASE_URL=postgres://user:password@host:5432/rack_gatewayAlternative: Individual Variables
Section titled “Alternative: Individual Variables”Use PostgreSQL standard environment variables:
PGHOST=database.example.comPGPORT=5432PGUSER=rack_gatewayPGPASSWORD=your-passwordPGDATABASE=rack_gatewayConnection Pool
Section titled “Connection Pool”Configure the connection pool for your workload:
| Variable | Default | Description |
|---|---|---|
DB_MAX_OPEN_CONNS | 25 | Maximum concurrent connections |
DB_MAX_IDLE_CONNS | 5 | Idle connections to keep warm |
DB_CONN_MAX_LIFETIME | 30m | Connection lifetime before recycling |
DB_CONN_MAX_IDLE_TIME | 10m | Idle time before closing |
Sizing Guidelines
Section titled “Sizing Guidelines”| Workload | Max Open | Max Idle | Notes |
|---|---|---|---|
| Small (<100 users) | 10 | 3 | Conservative for shared DB |
| Medium (<1000 users) | 25 | 5 | Default settings |
| Large (>1000 users) | 50 | 10 | Increase with load |
Database Provisioning
Section titled “Database Provisioning”Create a PostgreSQL resource in your Convox rack:
# Create databaseconvox resources create postgres --name gateway-db
# Link to applicationconvox resources link gateway-db -a rack-gateway
# View connection infoconvox resources info gateway-dbConvox automatically sets DATABASE_URL for linked apps.
Create an RDS PostgreSQL instance:
resource "aws_db_instance" "gateway" { identifier = "rack-gateway" engine = "postgres" engine_version = "16.1" instance_class = "db.t3.medium"
allocated_storage = 50 max_allocated_storage = 200 storage_type = "gp3" storage_encrypted = true
db_name = "rack_gateway" username = "rack_gateway_admin" password = var.db_password
vpc_security_group_ids = [aws_security_group.rds.id] db_subnet_group_name = aws_db_subnet_group.private.name
backup_retention_period = 30 backup_window = "03:00-04:00" maintenance_window = "sun:04:00-sun:05:00"
deletion_protection = true skip_final_snapshot = false
performance_insights_enabled = true}For local development:
services: postgres: image: postgres:16 environment: POSTGRES_USER: rack_gateway POSTGRES_PASSWORD: development POSTGRES_DB: rack_gateway volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432"
volumes: pgdata:Migrations
Section titled “Migrations”Automatic Migrations
Section titled “Automatic Migrations”Migrations run automatically when the gateway starts. The gateway:
- Checks current schema version in
schema_migrations - Applies any pending migrations
- Continues to API server startup
Manual Migrations
Section titled “Manual Migrations”Run migrations manually:
# Via Dockerdocker exec rack-gateway rack-gateway-api migrate
# Via Convoxconvox run gateway -- rack-gateway-api migrate -a rack-gatewayMigration Safety
Section titled “Migration Safety”- Migrations are idempotent - safe to run multiple times
- Each migration runs in a transaction
- Failures abort startup with clear error messages
Database Reset
Section titled “Database Reset”Development Reset
Section titled “Development Reset”export RESET_RACK_GATEWAY_DATABASE=DELETE_ALL_DATAexport DEV_MODE=truerack-gateway-api reset-dbEmergency Production Reset
Section titled “Emergency Production Reset”export RESET_RACK_GATEWAY_DATABASE=DELETE_ALL_DATAexport DISABLE_DATABASE_ENVIRONMENT_CHECK=1rack-gateway-api reset-dbSafety Guards
Section titled “Safety Guards”The reset command enforces safety checks:
| Check | Purpose | Override |
|---|---|---|
RESET_RACK_GATEWAY_DATABASE=DELETE_ALL_DATA | Explicit confirmation | Required |
| Development mode or environment check | Prevent accidental prod reset | DISABLE_DATABASE_ENVIRONMENT_CHECK=1 |
Schema Overview
Section titled “Schema Overview”The gateway creates these tables:
| Table | Purpose |
|---|---|
users | User accounts and roles |
user_sessions | Active user sessions |
api_tokens | API tokens for CI/CD |
mfa_methods | MFA registrations (TOTP, WebAuthn) |
mfa_backup_codes | MFA recovery codes |
trusted_devices | Remembered MFA devices |
audit.audit_event | Complete audit trail |
deploy_approval_requests | Deploy workflow state |
settings | Configuration settings |
user_resources | User ↔ resource audit links |
cli_login_states | CLI OAuth state tracking |
rgw_internal_metadata | Environment markers |
slack_integration | Slack OAuth tokens |
schema_migrations | Migration tracking |
Backup and Recovery
Section titled “Backup and Recovery”Backup Strategy
Section titled “Backup Strategy”For production, implement regular backups:
| Frequency | Retention | Purpose |
|---|---|---|
| Hourly | 24 hours | Point-in-time recovery |
| Daily | 30 days | Operational recovery |
| Weekly | 1 year | Compliance/audit |
RDS Automated Backups
Section titled “RDS Automated Backups”resource "aws_db_instance" "gateway" { # ... other config backup_retention_period = 30 # days backup_window = "03:00-04:00" # UTC
# Enable PITR delete_automated_backups = false}Manual Backup
Section titled “Manual Backup”# Export full databasepg_dump -h $PGHOST -U $PGUSER $PGDATABASE | gzip > backup-$(date +%Y%m%d).sql.gz
# Export specific tablespg_dump -h $PGHOST -U $PGUSER -t audit.audit_event $PGDATABASE > audit-backup.sqlRecovery
Section titled “Recovery”# Restore full backupgunzip -c backup-20240115.sql.gz | psql -h $PGHOST -U $PGUSER $PGDATABASE
# Restore from RDS snapshotaws rds restore-db-instance-from-db-snapshot \ --db-instance-identifier rack-gateway-restored \ --db-snapshot-identifier rds:rack-gateway-2024-01-15-03-00Audit Log Considerations
Section titled “Audit Log Considerations”Storage Growth
Section titled “Storage Growth”Audit logs grow continuously. Estimate storage needs:
| Events/Day | Annual Storage | Notes |
|---|---|---|
| 1,000 | ~5 GB | Small team |
| 10,000 | ~50 GB | Medium team |
| 100,000 | ~500 GB | Large/busy |
Log Retention
Section titled “Log Retention”For compliance, set appropriate retention:
# 400 days (annual audit + buffer)convox env set LOG_RETENTION_DAYS=400
# 7 years (SOX/FINRA compliance)convox env set LOG_RETENTION_DAYS=2557Audit Anchoring
Section titled “Audit Anchoring”For tamper-evident logs, enable S3 WORM anchoring:
convox env set \ AUDIT_ANCHOR_BUCKET=audit-anchors-prod \ AUDIT_ANCHOR_CHAIN_ID=productionSee S3 WORM Storage for setup details.
Performance Tuning
Section titled “Performance Tuning”PostgreSQL Configuration
Section titled “PostgreSQL Configuration”For dedicated gateway databases:
-- Connection limitsALTER SYSTEM SET max_connections = 100;
-- Memory settingsALTER SYSTEM SET shared_buffers = '256MB';ALTER SYSTEM SET work_mem = '16MB';ALTER SYSTEM SET maintenance_work_mem = '64MB';
-- Write performanceALTER SYSTEM SET wal_buffers = '16MB';ALTER SYSTEM SET checkpoint_completion_target = 0.9;
-- Query optimizationALTER SYSTEM SET effective_cache_size = '768MB';ALTER SYSTEM SET random_page_cost = 1.1; -- For SSD
SELECT pg_reload_conf();Index Maintenance
Section titled “Index Maintenance”The gateway creates necessary indexes automatically. For high-volume deployments, monitor and maintain:
-- Check index usageSELECT relname AS table, indexrelname AS index, idx_scan AS scans, idx_tup_read AS tuples_read, idx_tup_fetch AS tuples_fetchedFROM pg_stat_user_indexesORDER BY idx_scan DESC;
-- Reindex if neededREINDEX TABLE audit_events;Monitoring
Section titled “Monitoring”Key Metrics
Section titled “Key Metrics”Monitor these PostgreSQL metrics:
| Metric | Warning Threshold | Critical Threshold |
|---|---|---|
| Connection usage | 70% | 90% |
| Replication lag | 1s | 10s |
| Transaction rate | - | Baseline + 200% |
| Disk usage | 70% | 85% |
CloudWatch (RDS)
Section titled “CloudWatch (RDS)”resource "aws_cloudwatch_metric_alarm" "db_connections" { alarm_name = "rack-gateway-db-connections" comparison_operator = "GreaterThanThreshold" evaluation_periods = 2 metric_name = "DatabaseConnections" namespace = "AWS/RDS" period = 300 statistic = "Average" threshold = 40
dimensions = { DBInstanceIdentifier = aws_db_instance.gateway.identifier }}Query Performance
Section titled “Query Performance”Enable slow query logging:
ALTER SYSTEM SET log_min_duration_statement = 1000; -- Log queries > 1sSELECT pg_reload_conf();Security
Section titled “Security”Network Isolation
Section titled “Network Isolation”- Place database in private subnet
- Use security groups to restrict access
- Enable SSL for connections
resource "aws_security_group" "rds" { name = "rack-gateway-rds" vpc_id = var.vpc_id
ingress { from_port = 5432 to_port = 5432 protocol = "tcp" security_groups = [aws_security_group.gateway.id] }
egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }}Encryption
Section titled “Encryption”- Enable encryption at rest (RDS default)
- Use SSL for connections in transit
- Consider KMS for key management
# Force SSL connectionsDATABASE_URL=postgres://user:pass@host:5432/db?sslmode=requireAccess Control
Section titled “Access Control”Create a dedicated database user:
-- Create role with minimal privilegesCREATE ROLE rack_gateway_app WITH LOGIN PASSWORD 'secure-password';
-- Grant necessary permissionsGRANT CONNECT ON DATABASE rack_gateway TO rack_gateway_app;GRANT USAGE ON SCHEMA public TO rack_gateway_app;GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO rack_gateway_app;GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO rack_gateway_app;
-- For migrations (separate admin user)CREATE ROLE rack_gateway_admin WITH LOGIN PASSWORD 'admin-password';GRANT ALL PRIVILEGES ON DATABASE rack_gateway TO rack_gateway_admin;Troubleshooting
Section titled “Troubleshooting”Connection Issues
Section titled “Connection Issues”# Test connectionpsql $DATABASE_URL -c "SELECT 1"
# Check connection countpsql $DATABASE_URL -c "SELECT count(*) FROM pg_stat_activity"
# View active connectionspsql $DATABASE_URL -c "SELECT * FROM pg_stat_activity WHERE datname = 'rack_gateway'"Migration Failures
Section titled “Migration Failures”# Check migration statuspsql $DATABASE_URL -c "SELECT * FROM schema_migrations ORDER BY version"
# View gateway logs for migration errorsconvox logs -a rack-gateway --filter migrationPerformance Issues
Section titled “Performance Issues”-- Find slow queriesSELECT query, calls, mean_time, total_timeFROM pg_stat_statementsORDER BY total_time DESCLIMIT 10;
-- Check table sizesSELECT relname, pg_size_pretty(pg_total_relation_size(relid))FROM pg_stat_user_tablesORDER BY pg_total_relation_size(relid) DESC;Next Steps
Section titled “Next Steps”- Convox Deployment - Deploy the gateway
- S3 WORM Storage - Audit anchoring
- Production Checklist - Go-live preparation