Configuration Management
PGRestify CLI provides comprehensive configuration management for PostgREST deployments and Docker setups. This includes environment-specific configurations, security hardening, and deployment optimization.
Overview
Configuration management helps you:
- Generate optimized PostgREST configuration files
- Set up Docker Compose for development and production
- Configure environment-specific settings
- Apply security best practices
- Manage database connections and authentication
PostgREST Configuration
Generate PostgREST Config
Create PostgREST configuration files optimized for different environments:
# Interactive configuration generation
pgrestify api config postgrest
# Generate for specific environment
pgrestify api config postgrest --env production
# Generate with custom settings
pgrestify api config postgrest \
--env staging \
--port 3001 \
--schema api \
--output ./config/postgrest.conf
PostgREST Config Options
pgrestify api config postgrest [options]
Options:
--output <file> Output file (default: ./postgrest.conf)
--env <environment> Environment (development|staging|production)
--port <port> Server port (default: 3000)
--schema <schema> API schema
--db-uri <uri> Database URI (will prompt if not provided)
Environment Configurations
Development Environment
Optimized for local development with debug features:
# postgrest.conf (Development)
db-uri = "postgresql://postgres:postgres@localhost:5432/myapp_dev"
db-schema = "api"
db-anon-role = "anon"
db-pool = 10
db-pool-timeout = 10
server-host = "0.0.0.0"
server-port = 3000
server-cors-allowed-origins = "*"
jwt-secret = "development-jwt-secret-min-32-chars"
jwt-aud = "authenticated"
log-level = "info"
openapi-server-proxy-uri = "http://localhost:3000"
# Development optimizations
db-prepared-statements = false
db-tx-end = "commit"
db-tx-isolation = "read-committed"
db-max-rows = 1000
Staging Environment
Testing environment with production-like settings:
# postgrest.conf (Staging)
db-uri = "postgresql://staginguser:stagingpass@staging-db:5432/myapp_staging"
db-schema = "api"
db-anon-role = "anon"
db-pool = 20
db-pool-timeout = 10
server-host = "0.0.0.0"
server-port = 3000
server-cors-allowed-origins = "https://staging.myapp.com"
jwt-secret = "staging-jwt-secret-very-secure-32-chars"
jwt-aud = "authenticated"
jwt-role-claim-key = ".role"
log-level = "warn"
openapi-server-proxy-uri = "https://staging-api.myapp.com"
# Staging security
db-prepared-statements = true
db-tx-end = "commit"
db-max-rows = 500
Production Environment
Production environment with security hardening:
# postgrest.conf (Production)
db-uri = "postgresql://produser:securepass@prod-db:5432/myapp_prod"
db-schema = "api"
db-anon-role = "anon"
db-pool = 100
db-pool-timeout = 10
server-host = "0.0.0.0"
server-port = 3000
server-cors-allowed-origins = "https://myapp.com,https://www.myapp.com"
jwt-secret = "production-jwt-secret-very-secure-minimum-32-chars"
jwt-aud = "authenticated"
jwt-role-claim-key = ".role"
jwt-secret-is-base64 = false
log-level = "error"
openapi-server-proxy-uri = "https://api.myapp.com"
# Production security hardening
db-prepared-statements = true
db-tx-end = "rollback-allow-override"
db-tx-isolation = "read-committed"
db-max-rows = 100
# Rate limiting and security
server-request-timeout = "10"
Interactive Configuration
When running without all options, the CLI guides you through configuration:
$ pgrestify api config postgrest
⚙️ Generating PostgREST Configuration
? Target environment:
❯ Development - Local development with debug features
Staging - Testing environment with production-like settings
Production - Production environment with security hardening
? Server configuration:
Port: (3000)
Schema: (api)
Host: (0.0.0.0)
? Database configuration:
Database URI: postgresql://user:pass@host:5432/database
Anonymous role: (anon)
Authenticated role: (authenticated)
Connection pool size: (10)
? Security configuration:
JWT secret: (will be generated)
CORS origins: (*)
Request timeout: (10s)
? Performance settings:
Max rows per request: (1000)
Enable prepared statements: (Y/n)
Transaction isolation: (read-committed)
Docker Configuration
Generate Docker Setup
Create Docker Compose configurations for different deployment scenarios:
# Generate Docker setup
pgrestify api config docker
# Generate with specific services
pgrestify api config docker --services postgres,postgrest,nginx
# Generate for production
pgrestify api config docker --env production --output docker-compose.prod.yml
# Generate with custom networks
pgrestify api config docker --network custom_network
Docker Config Options
pgrestify api config docker [options]
Options:
--output <file> Output file (default: docker-compose.yml)
--env <environment> Environment (development|staging|production)
--services <list> Services to include (postgres,postgrest,nginx,redis)
--network <name> Custom network name
--postgres-version PostgreSQL version (default: 15-alpine)
--postgrest-version PostgREST version (default: latest)
Generated Docker Configurations
Development Docker Compose
# docker-compose.yml (Development)
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: pgrestify_postgres_dev
environment:
POSTGRES_DB: ${POSTGRES_DB:-myapp_dev}
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
ports:
- "${POSTGRES_PORT:-5432}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./sql:/docker-entrypoint-initdb.d:ro
networks:
- pgrestify_network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"]
interval: 10s
timeout: 5s
retries: 5
postgrest:
image: postgrest/postgrest:latest
container_name: pgrestify_postgrest_dev
depends_on:
postgres:
condition: service_healthy
environment:
PGRST_DB_URI: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-myapp_dev}
PGRST_DB_SCHEMA: ${POSTGREST_SCHEMA:-api}
PGRST_DB_ANON_ROLE: ${POSTGREST_ANON_ROLE:-anon}
PGRST_JWT_SECRET: ${JWT_SECRET:-development-jwt-secret-min-32-chars}
PGRST_OPENAPI_SERVER_PROXY_URI: http://localhost:${POSTGREST_PORT:-3000}
ports:
- "${POSTGREST_PORT:-3000}:3000"
networks:
- pgrestify_network
restart: unless-stopped
volumes:
postgres_data:
networks:
pgrestify_network:
driver: bridge
Production Docker Compose
# docker-compose.prod.yml (Production)
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: pgrestify_postgres_prod
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
secrets:
- postgres_password
volumes:
- postgres_data:/var/lib/postgresql/data
- postgres_backup:/backup
networks:
- internal_network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
memory: 1G
cpus: "0.5"
reservations:
memory: 512M
cpus: "0.25"
postgrest:
image: postgrest/postgrest:v11.2.0 # Pinned version for production
container_name: pgrestify_postgrest_prod
depends_on:
postgres:
condition: service_healthy
environment:
PGRST_DB_URI: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
PGRST_DB_SCHEMA: ${POSTGREST_SCHEMA:-api}
PGRST_DB_ANON_ROLE: ${POSTGREST_ANON_ROLE:-anon}
PGRST_JWT_SECRET_FILE: /run/secrets/jwt_secret
PGRST_LOG_LEVEL: error
PGRST_DB_POOL: 100
PGRST_DB_MAX_ROWS: 100
PGRST_DB_PREPARED_STATEMENTS: true
secrets:
- jwt_secret
networks:
- internal_network
- web_network
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
cpus: "0.5"
reservations:
memory: 256M
cpus: "0.25"
nginx:
image: nginx:alpine
container_name: pgrestify_nginx_prod
depends_on:
- postgrest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
- nginx_cache:/var/cache/nginx
networks:
- web_network
restart: unless-stopped
secrets:
postgres_password:
file: ./secrets/postgres_password.txt
jwt_secret:
file: ./secrets/jwt_secret.txt
volumes:
postgres_data:
postgres_backup:
nginx_cache:
networks:
internal_network:
driver: bridge
internal: true
web_network:
driver: bridge
Environment Variables
PostgREST Environment Variables
Generated configurations use environment variables for flexibility:
# .env.example
# Database Configuration
POSTGRES_DB=myapp_db
POSTGRES_USER=postgres
POSTGRES_PASSWORD=secure-password
POSTGRES_PORT=5432
# PostgREST Configuration
POSTGREST_PORT=3000
POSTGREST_SCHEMA=api
POSTGREST_ANON_ROLE=anon
JWT_SECRET=your-jwt-secret-minimum-32-characters
# Optional Configuration
POSTGREST_DB_POOL=20
POSTGREST_MAX_ROWS=1000
CORS_ORIGINS=*
# SSL Configuration (Production)
SSL_CERT_PATH=/path/to/cert.pem
SSL_KEY_PATH=/path/to/key.pem
Security Environment Variables
# Security-focused variables
JWT_SECRET_FILE=/run/secrets/jwt_secret
POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password
ADMIN_PASSWORD_FILE=/run/secrets/admin_password
# CORS and security headers
CORS_ALLOWED_ORIGINS=https://myapp.com,https://www.myapp.com
RATE_LIMIT_PER_MINUTE=100
REQUEST_TIMEOUT=10
# Monitoring and logging
LOG_LEVEL=error
METRICS_ENABLED=true
HEALTH_CHECK_ENABLED=true
Configuration Validation
Validate Configurations
Check configuration files for common issues:
# Validate PostgREST config
pgrestify validate --config postgrest.conf
# Validate Docker setup
pgrestify validate --docker docker-compose.yml
# Comprehensive validation
pgrestify validate --all
Validation Checks
The validator checks for:
PostgREST Configuration:
- Valid database URI format
- Proper JWT secret length (minimum 32 characters)
- Correct role configuration
- Security settings validation
Docker Configuration:
- Service dependencies
- Network configuration
- Volume mounts
- Health checks
Environment Variables:
- Required variables present
- Secure defaults
- Production readiness
Validation Output
$ pgrestify validate --config postgrest.conf
✅ Configuration Validation Results
PostgREST Configuration:
✅ Database URI format valid
✅ JWT secret length adequate (32+ characters)
✅ Roles configured correctly
❌ CORS origins too permissive for production
⚠️ Log level set to 'info' (recommend 'error' for production)
Security Checks:
✅ No hardcoded passwords found
✅ Environment variables used properly
❌ JWT secret should use environment variable
Recommendations:
- Set CORS origins to specific domains
- Move JWT secret to environment variable
- Consider using JWT secret file in production
Issues Found: 2 errors, 1 warning
Configuration Templates
Custom Configuration Templates
Create reusable configuration templates:
# Create template from existing config
pgrestify api config template create my-template --from postgrest.conf
# Use template for new projects
pgrestify api config postgrest --template my-template
# List available templates
pgrestify api config template list
Best Practices
Security Configuration
- Never hardcode secrets in configuration files
- Use environment variables or secret files
- Set restrictive CORS origins in production
- Use minimum required permissions for database roles
- Enable prepared statements for performance and security
Performance Configuration
- Tune connection pool size based on expected load
- Set appropriate max rows limits
- Use read-committed isolation for most use cases
- Enable request timeout to prevent hanging requests
- Configure proper logging levels
Production Configuration
- Pin Docker image versions for reproducible deployments
- Use secrets management for sensitive data
- Configure resource limits for containers
- Set up proper health checks and monitoring
- Use SSL/TLS termination at load balancer or reverse proxy
Troubleshooting Configuration
Common Issues
Connection Issues
# Error: Connection refused
# Check database URI and network configuration
PGRST_DB_URI=postgresql://user:pass@correct-host:5432/database
Authentication Issues
# Error: JWT validation failed
# Ensure JWT secret matches between client and server
JWT_SECRET=same-secret-on-both-sides-min-32-chars
CORS Issues
# Error: CORS policy blocked
# Add client domain to allowed origins
server-cors-allowed-origins = "https://client-domain.com"
Testing Configuration
Test generated configurations:
# Test PostgREST config
postgrest postgrest.conf
# Test Docker setup
docker-compose up --dry-run
# Test environment variables
env | grep POSTGREST
Integration with Other Commands
Complete Workflow
# 1. Initialize project
pgrestify api init --template blog
# 2. Generate configuration
pgrestify api config postgrest --env production
pgrestify api config docker --env production
# 3. Set up environment
cp .env.example .env
# Edit .env with production values
# 4. Start services
docker-compose -f docker-compose.prod.yml up -d
# 5. Validate deployment
pgrestify validate --all
curl http://localhost:3000
Summary
PGRestify's configuration management provides comprehensive tools for setting up PostgREST deployments with proper security, performance optimization, and environment-specific configurations. The generated configurations follow best practices and can be easily customized for different deployment scenarios.