Skip to content

Configuration

Configure the goserve MongoDB example project.

Environment Variables

The application uses environment variables for configuration. All settings are loaded from .env files using Viper.

Database Configuration

MongoDB Settings

bash
# MongoDB Connection
DB_URI=mongodb://localhost:27017
DB_NAME=goserve_mongo
DB_TIMEOUT=30s

# Optional authentication
DB_USER=your_username
DB_PASSWORD=your_password

Redis Configuration

bash
# Redis Connection
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
REDIS_TIMEOUT=30s

JWT Configuration

RSA Key Setup

bash
# JWT Keys (generated by tools)
JWT_SECRET_KEY_PATH=keys/private.pem
JWT_PUBLIC_KEY_PATH=keys/public.pem

# Token expiry times
JWT_ACCESS_TOKEN_EXPIRY_MINUTES=15
JWT_REFRESH_TOKEN_EXPIRY_HOURS=24

Server Configuration

HTTP Server Settings

bash
# Server Configuration
SERVER_HOST=0.0.0.0
SERVER_PORT=8080
GO_ENV=development

# Request timeouts
SERVER_READ_TIMEOUT=30s
SERVER_WRITE_TIMEOUT=30s
SERVER_IDLE_TIMEOUT=60s

Cache Configuration

Redis Cache Settings

bash
# Cache TTL settings
SAMPLE_CACHE_TTL_MINUTES=60
USER_CACHE_TTL_MINUTES=30

API Configuration

Base Settings

bash
# API Configuration
API_BASE_URL=http://localhost:8080
API_VERSION=v1
API_TIMEOUT=30s

Complete .env File

bash
# ===========================================
# DATABASE CONFIGURATION
# ===========================================
DB_URI=mongodb://localhost:27017
DB_NAME=goserve_mongo
DB_TIMEOUT=30s
DB_USER=
DB_PASSWORD=

# ===========================================
# REDIS CONFIGURATION
# ===========================================
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
REDIS_TIMEOUT=30s

# ===========================================
# JWT CONFIGURATION
# ===========================================
JWT_SECRET_KEY_PATH=keys/private.pem
JWT_PUBLIC_KEY_PATH=keys/public.pem
JWT_ACCESS_TOKEN_EXPIRY_MINUTES=15
JWT_REFRESH_TOKEN_EXPIRY_HOURS=24

# ===========================================
# SERVER CONFIGURATION
# ===========================================
SERVER_HOST=0.0.0.0
SERVER_PORT=8080
GO_ENV=development
SERVER_READ_TIMEOUT=30s
SERVER_WRITE_TIMEOUT=30s
SERVER_IDLE_TIMEOUT=60s

# ===========================================
# CACHE CONFIGURATION
# ===========================================
SAMPLE_CACHE_TTL_MINUTES=60
USER_CACHE_TTL_MINUTES=30

# ===========================================
# API CONFIGURATION
# ===========================================
API_BASE_URL=http://localhost:8080
API_VERSION=v1
API_TIMEOUT=30s

Configuration Loading

The configuration is loaded using the following pattern:

go
package config

import (
    "os"
    "strconv"
    "time"

    "github.com/spf13/viper"
)

type Env struct {
    // Database
    DBURI      string
    DBName     string
    DBTimeout  time.Duration

    // Redis
    RedisHost     string
    RedisPort     int
    RedisPassword string
    RedisDB       int
    RedisTimeout  time.Duration

    // JWT
    JWTSecretKeyPath  string
    JWTPublicKeyPath  string
    JWTAccessExpiry   time.Duration
    JWTRefreshExpiry  time.Duration

    // Server
    ServerHost      string
    ServerPort      int
    GoEnv           string
    ServerReadTimeout  time.Duration
    ServerWriteTimeout time.Duration
    ServerIdleTimeout  time.Duration

    // Cache
    SampleCacheTTL time.Duration
    UserCacheTTL   time.Duration

    // API
    APIBaseURL string
    APIVersion string
    APITimeout time.Duration
}

func Load() *Env {
    viper.AutomaticEnv()

    return &Env{
        // Database Configuration
        DBURI:     getEnv("DB_URI", "mongodb://localhost:27017"),
        DBName:    getEnv("DB_NAME", "goserve_mongo"),
        DBTimeout: getEnvDuration("DB_TIMEOUT", 30*time.Second),

        // Redis Configuration
        RedisHost:     getEnv("REDIS_HOST", "localhost"),
        RedisPort:     getEnvInt("REDIS_PORT", 6379),
        RedisPassword: getEnv("REDIS_PASSWORD", ""),
        RedisDB:       getEnvInt("REDIS_DB", 0),
        RedisTimeout:  getEnvDuration("REDIS_TIMEOUT", 30*time.Second),

        // JWT Configuration
        JWTSecretKeyPath: getEnv("JWT_SECRET_KEY_PATH", "keys/private.pem"),
        JWTPublicKeyPath: getEnv("JWT_PUBLIC_KEY_PATH", "keys/public.pem"),
        JWTAccessExpiry:  time.Duration(getEnvInt("JWT_ACCESS_TOKEN_EXPIRY_MINUTES", 15)) * time.Minute,
        JWTRefreshExpiry: time.Duration(getEnvInt("JWT_REFRESH_TOKEN_EXPIRY_HOURS", 24)) * time.Hour,

        // Server Configuration
        ServerHost:        getEnv("SERVER_HOST", "0.0.0.0"),
        ServerPort:        getEnvInt("SERVER_PORT", 8080),
        GoEnv:             getEnv("GO_ENV", "development"),
        ServerReadTimeout:  getEnvDuration("SERVER_READ_TIMEOUT", 30*time.Second),
        ServerWriteTimeout: getEnvDuration("SERVER_WRITE_TIMEOUT", 30*time.Second),
        ServerIdleTimeout:  getEnvDuration("SERVER_IDLE_TIMEOUT", 60*time.Second),

        // Cache Configuration
        SampleCacheTTL: time.Duration(getEnvInt("SAMPLE_CACHE_TTL_MINUTES", 60)) * time.Minute,
        UserCacheTTL:   time.Duration(getEnvInt("USER_CACHE_TTL_MINUTES", 30)) * time.Minute,

        // API Configuration
        APIBaseURL: getEnv("API_BASE_URL", "http://localhost:8080"),
        APIVersion: getEnv("API_VERSION", "v1"),
        APITimeout: getEnvDuration("API_TIMEOUT", 30*time.Second),
    }
}

func getEnv(key, defaultValue string) string {
    if value := os.Getenv(key); value != "" {
        return value
    }
    return defaultValue
}

func getEnvInt(key string, defaultValue int) int {
    if value := os.Getenv(key); value != "" {
        if intValue, err := strconv.Atoi(value); err == nil {
            return intValue
        }
    }
    return defaultValue
}

func getEnvDuration(key string, defaultValue time.Duration) time.Duration {
    if value := os.Getenv(key); value != "" {
        if duration, err := time.ParseDuration(value); err == nil {
            return duration
        }
    }
    return defaultValue
}

Docker Configuration

docker-compose.yml

yaml
version: '3.8'
services:
  mongo:
    image: mongo:5
    ports:
      - "27017:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: password
    volumes:
      - mongo_data:/data/db
      - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - DB_URI=mongodb://admin:password@mongo:27017/goserve_mongo?authSource=admin
      - REDIS_HOST=redis
      - JWT_SECRET_KEY_PATH=/app/keys/private.pem
      - JWT_PUBLIC_KEY_PATH=/app/keys/public.pem
    volumes:
      - ./keys:/app/keys:ro
    depends_on:
      - mongo
      - redis

volumes:
  mongo_data:

MongoDB Initialization

init-mongo.js

javascript
db = db.getSiblingDB('goserve_mongo');

// Create collections
db.createCollection('samples');
db.createCollection('users');

// Create indexes
db.samples.createIndex({ "_id": 1, "status": 1 });
db.samples.createIndex({ "createdAt": -1 });
db.samples.createIndex({ "field": "text" });

db.users.createIndex({ "email": 1 }, { unique: true });
db.users.createIndex({ "_id": 1, "role": 1 });

// Insert sample data
db.samples.insertMany([
  {
    "_id": ObjectId(),
    "field": "Sample Document 1",
    "status": true,
    "createdAt": new Date(),
    "updatedAt": new Date()
  },
  {
    "_id": ObjectId(),
    "field": "Sample Document 2",
    "status": false,
    "createdAt": new Date(),
    "updatedAt": new Date()
  }
]);

// Create API key user
db.users.insertOne({
  "_id": ObjectId(),
  "email": "api@example.com",
  "name": "API User",
  "role": "admin",
  "verified": true,
  "createdAt": new Date(),
  "updatedAt": new Date()
});

Environment File Templates

.env (Development)

bash
DB_URI=mongodb://localhost:27017
DB_NAME=goserve_mongo
DB_TIMEOUT=30s

REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=0
REDIS_TIMEOUT=30s

JWT_SECRET_KEY_PATH=keys/private.pem
JWT_PUBLIC_KEY_PATH=keys/public.pem
JWT_ACCESS_TOKEN_EXPIRY_MINUTES=15
JWT_REFRESH_TOKEN_EXPIRY_HOURS=24

SERVER_HOST=0.0.0.0
SERVER_PORT=8080
GO_ENV=development
SERVER_READ_TIMEOUT=30s
SERVER_WRITE_TIMEOUT=30s
SERVER_IDLE_TIMEOUT=60s

SAMPLE_CACHE_TTL_MINUTES=60
USER_CACHE_TTL_MINUTES=30

API_BASE_URL=http://localhost:8080
API_VERSION=v1
API_TIMEOUT=30s

.test.env (Testing)

bash
DB_URI=mongodb://localhost:27017
DB_NAME=goserve_mongo_test
DB_TIMEOUT=30s

REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=1
REDIS_TIMEOUT=30s

JWT_SECRET_KEY_PATH=keys/private.pem
JWT_PUBLIC_KEY_PATH=keys/public.pem
JWT_ACCESS_TOKEN_EXPIRY_MINUTES=15
JWT_REFRESH_TOKEN_EXPIRY_HOURS=24

SERVER_HOST=0.0.0.0
SERVER_PORT=8081
GO_ENV=test
SERVER_READ_TIMEOUT=30s
SERVER_WRITE_TIMEOUT=30s
SERVER_IDLE_TIMEOUT=60s

SAMPLE_CACHE_TTL_MINUTES=5
USER_CACHE_TTL_MINUTES=5

API_BASE_URL=http://localhost:8081
API_VERSION=v1
API_TIMEOUT=30s

Configuration Best Practices

Environment Separation

  1. Development - Local development with relaxed settings
  2. Testing - Isolated test databases and short cache TTL
  3. Production - Secure credentials and optimized settings

Security Considerations

  1. Never commit secrets - Use environment variables for sensitive data
  2. Use strong passwords - For database and Redis connections
  3. Limit permissions - Database users should have minimal required permissions
  4. Rotate keys regularly - JWT keys and API secrets should be rotated

Performance Tuning

  1. Connection pooling - Configure appropriate pool sizes for your workload
  2. Timeout settings - Set reasonable timeouts to prevent hanging connections
  3. Cache TTL - Adjust cache expiration based on data volatility
  4. Database indexes - Ensure proper indexing for query performance

Next Steps

Released under the Apache 2.0 License