Skip to content

Production Deployment Guide

This guide outlines the steps to deploy the SaaS Auth API to a production environment.

Prerequisites

  • Docker and Docker Compose
  • A server or cloud environment (AWS, GCP, Azure, etc.)
  • Domain name and SSL certificate (recommended)
  • PostgreSQL database (can be deployed as part of the stack or managed service)
  • Redis instance (can be deployed as part of the stack or managed service)

Security Considerations

Before deploying to production, ensure you have addressed these security considerations:

  1. Change default secrets and passwords:

    • JWT secret
    • Password salt
    • Database passwords
    • Redis passwords
  2. Secure your environment variables:

    • Use a secret management service where possible
    • Don’t commit secrets to version control
  3. Set up proper TLS/SSL:

    • Use a valid SSL certificate
    • Configure proper HTTPS
    • Implement HTTP to HTTPS redirection
  4. Configure firewalls and network security:

    • Limit access to the database and Redis to only your application servers
    • Use VPCs or equivalent network isolation where appropriate

Production Configuration

Create a production configuration file (config/config.prod.yaml) with appropriate settings:

app:
name: saas-auth-api
version: 0.1.0
env: production
port: 3000
database:
host: your-db-host
port: 5432
user: db_user
password: secure_password
name: saas_auth
sslmode: require # Use SSL in production
max_open_conns: 50
max_idle_conns: 10
conn_max_lifetime: 30m
redis:
host: your-redis-host
port: 6379
password: secure_redis_password
db: 0
jwt:
secret: your_very_long_and_random_secret_key
access_ttl: 15m
refresh_ttl: 24h
auth:
password_salt: your_random_password_salt
api_key_prefix: sk-
api_key_length: 32
rate_limit:
enabled: true
requests: 100
duration: 1m

Deployment Options

Docker Compose Deployment

For simpler deployments or smaller environments, you can use Docker Compose:

  1. Create production docker-compose file (included in the project as docker-compose.yml).

  2. Deploy using Docker Compose:

    Terminal window
    docker-compose up -d

Kubernetes Deployment

For production environments, Kubernetes is recommended:

  1. Create Kubernetes manifests:

    deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: saas-auth-api
    labels:
    app: saas-auth-api
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: saas-auth-api
    template:
    metadata:
    labels:
    app: saas-auth-api
    spec:
    containers:
    - name: saas-auth-api
    image: your-registry/saas-auth-api:latest
    ports:
    - containerPort: 3000
    env:
    - name: APP_ENV
    value: "production"
    - name: DB_HOST
    valueFrom:
    secretKeyRef:
    name: saas-auth-secrets
    key: db-host
    - name: DB_PORT
    valueFrom:
    secretKeyRef:
    name: saas-auth-secrets
    key: db-port
    - name: DB_USER
    valueFrom:
    secretKeyRef:
    name: saas-auth-secrets
    key: db-user
    - name: DB_PASSWORD
    valueFrom:
    secretKeyRef:
    name: saas-auth-secrets
    key: db-password
    - name: DB_NAME
    valueFrom:
    secretKeyRef:
    name: saas-auth-secrets
    key: db-name
    - name: REDIS_HOST
    valueFrom:
    secretKeyRef:
    name: saas-auth-secrets
    key: redis-host
    - name: REDIS_PORT
    valueFrom:
    secretKeyRef:
    name: saas-auth-secrets
    key: redis-port
    - name: REDIS_PASSWORD
    valueFrom:
    secretKeyRef:
    name: saas-auth-secrets
    key: redis-password
    - name: JWT_SECRET
    valueFrom:
    secretKeyRef:
    name: saas-auth-secrets
    key: jwt-secret
    livenessProbe:
    httpGet:
    path: /health
    port: 3000
    initialDelaySeconds: 30
    periodSeconds: 10
    readinessProbe:
    httpGet:
    path: /health
    port: 3000
    initialDelaySeconds: 5
    periodSeconds: 5

    service.yaml:

    apiVersion: v1
    kind: Service
    metadata:
    name: saas-auth-api
    spec:
    selector:
    app: saas-auth-api
    ports:
    - port: 80
    targetPort: 3000
    type: ClusterIP

    ingress.yaml:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: saas-auth-api
    annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    spec:
    tls:
    - hosts:
    - auth-api.yourdomain.com
    secretName: auth-api-tls
    rules:
    - host: auth-api.yourdomain.com
    http:
    paths:
    - path: /
    pathType: Prefix
    backend:
    service:
    name: saas-auth-api
    port:
    number: 80

    secrets.yaml:

    apiVersion: v1
    kind: Secret
    metadata:
    name: saas-auth-secrets
    type: Opaque
    data:
    db-host: base64-encoded-value
    db-port: base64-encoded-value
    db-user: base64-encoded-value
    db-password: base64-encoded-value
    db-name: base64-encoded-value
    redis-host: base64-encoded-value
    redis-port: base64-encoded-value
    redis-password: base64-encoded-value
    jwt-secret: base64-encoded-value
  2. Apply the manifests:

    Terminal window
    kubectl apply -f deployment.yaml
    kubectl apply -f service.yaml
    kubectl apply -f ingress.yaml
    kubectl apply -f secrets.yaml

Building for Production

  1. Build the Docker image:

    Terminal window
    docker build -t your-registry/saas-auth-api:latest .
  2. Push to your container registry:

    Terminal window
    docker push your-registry/saas-auth-api:latest

Database Migration in Production

Always back up your database before running migrations in production:

Terminal window
# Run migrations
migrate -path ./migrations -database "postgres://user:password@your-db-host:5432/saas_auth?sslmode=require" up

Alternatively, the application can run migrations automatically on startup, but this approach should be used with caution in a multi-instance environment to avoid multiple instances attempting migrations simultaneously.

Scaling Considerations

Horizontal Scaling

The application is designed to scale horizontally. Consider the following when scaling:

  1. Database Connection Pooling:

    • Adjust max_open_conns and max_idle_conns based on the number of instances
    • Consider using a connection pooler like PgBouncer for large-scale deployments
  2. Redis Connection Management:

    • Similar to database connections, monitor and adjust Redis connection settings
  3. Session Management:

    • The application uses Redis for session storage, which allows for stateless instances
  4. Rate Limiting:

    • Rate limiting is implemented with Redis, which works across multiple instances

Monitoring and Logging

Set up proper monitoring and logging:

  1. Application Logs:

    • Configure a centralized logging system (ELK Stack, Loki, etc.)
    • Set appropriate log levels in production (info or warn)
  2. Metrics:

    • Set up Prometheus metrics collection
    • Monitor API response times, error rates, and resource usage
  3. Alerting:

    • Configure alerts for high error rates, slow response times, and resource constraints

SSL/TLS Configuration

For production, always use HTTPS. You have several options:

  1. Terminate SSL at Load Balancer/Ingress (Recommended):

    • Configure SSL in your load balancer or Kubernetes ingress
    • Use Let’s Encrypt for free, auto-renewing certificates
  2. Application-level SSL:

    • Configure SSL directly in the application
    • This is not recommended as it adds overhead to the application

Backup Strategy

Implement a regular backup strategy:

  1. Database Backups:

    • Schedule regular full backups
    • Consider point-in-time recovery options
    • Test restoration procedures regularly
  2. Configuration Backups:

    • Keep configuration files in version control
    • Document all environment-specific settings

Production Checklist

Before going live, ensure you’ve addressed these items:

  • Secure all credentials and secrets
  • Configure proper TLS/SSL
  • Set up database backups
  • Implement monitoring and alerting
  • Test horizontal scaling
  • Perform load testing
  • Implement proper logging
  • Set up automated health checks
  • Create runbooks for common operational tasks
  • Document the production environment

Maintenance Operations

Rolling Updates

To perform zero-downtime updates:

  1. With Kubernetes:

    Terminal window
    kubectl set image deployment/saas-auth-api saas-auth-api=your-registry/saas-auth-api:new-version

    Kubernetes will perform a rolling update.

  2. With Docker Compose:

    Terminal window
    docker-compose pull
    docker-compose up -d

    This will recreate containers one at a time.

Database Maintenance

Schedule regular maintenance tasks:

  1. Vacuum and Analyze PostgreSQL:

    VACUUM ANALYZE;
  2. Index Maintenance:

    REINDEX DATABASE saas_auth;
  3. Redis Cache Maintenance: Monitor memory usage and consider setting appropriate eviction policies.

Troubleshooting Production Issues

Common issues and solutions:

  1. High Database Load:

    • Check slow queries using PostgreSQL logs
    • Review indexes and query optimization
    • Consider read replicas for read-heavy workloads
  2. Memory Leaks:

    • Monitor container memory usage
    • Set appropriate memory limits
    • Check for goroutine leaks
  3. Connection Issues:

    • Verify network connectivity
    • Check firewall rules
    • Ensure service discovery is working properly
  4. High Response Times:

    • Monitor application metrics
    • Check database query performance
    • Review application logs for bottlenecks

Disaster Recovery

Prepare for the worst by having a disaster recovery plan:

  1. Database Recovery:

    • Document the process to restore from backups
    • Regularly test restoration procedures
  2. Application Recovery:

    • Maintain infrastructure as code
    • Document the steps to recreate the entire environment
  3. Failover Procedures:

    • If using multiple regions, document failover procedures
    • Test failover regularly