Environment Variable Secrets Management

In production deployments, managing sensitive information such as API keys, passwords, and other secrets securely is essential. When using Docker/Compose and Golang, environment variables are a common method for injecting secrets into your application during runtime.

Step 1: Define Environment Variables in .env File

First, create a .env file in your project root directory:

# .env
API_KEY=your_api_key_here
DB_PASSWORD=your_db_password_here

Step 2: Reference the Variables in docker-compose.yml

You can use the ${VARIABLE_NAME} syntax in your docker-compose.yml to pass these variables to the services:

version: '3.8'

services:
  frontend:
    image: nginx
    container_name: frontend
    environment:
      - API_KEY=${API_KEY}
      - DB_PASSWORD=${DB_PASSWORD}
    volumes:
      - project-data:/data

volumes:
  project-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "${TEST_DIR}"

Step 3: Accessing Environment Variables in Golang

In your Golang code, use the os package to access these environment variables:

package main

import (
    "fmt"
    "os"
)

func main() {
    apiKey := os.Getenv("API_KEY")
    dbPassword := os.Getenv("DB_PASSWORD")
    
    fmt.Println("API Key:", apiKey)
    fmt.Println("Database Password:", dbPassword)
}

Using Docker Secrets with Docker Swarm

For sensitive information, it is advisable to use Docker Secrets, especially when deploying in a Docker Swarm environment.

Step 1: Create Docker Secrets

You can create secrets via the CLI:

echo "your_api_key_here" | docker secret create api_key -
echo "your_db_password_here" | docker secret create db_password -

Step 2: Reference Secrets in docker-compose.yml

In your docker-compose.yml, specify the secrets under the relevant service:

version: '3.8'

services:
  frontend:
    image: nginx
    container_name: frontend
    secrets:
      - api_key
      - db_password
    volumes:
      - project-data:/data

secrets:
  api_key:
    external: true
  db_password:
    external: true

volumes:
  project-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "${TEST_DIR}"

Step 3: Accessing Docker Secrets in Golang

When the secrets are available, they are made available under /run/secrets/<secret_name> in the container:

package main

import (
    "io/ioutil"
    "log"
)

func main() {
    apiKey, err := ioutil.ReadFile("/run/secrets/api_key")
    if err != nil {
        log.Fatalf("Error reading secret: %v", err)
    }

    dbPassword, err := ioutil.ReadFile("/run/secrets/db_password")
    if err != nil {
        log.Fatalf("Error reading secret: %v", err)
    }

    log.Println("API Key:", string(apiKey))
    log.Println("Database Password:", string(dbPassword))
}

Conclusion

By following these steps, you can securely manage secrets in production for applications built with Docker/Compose and Golang. Utilizing environment variables for lightweight configurations and Docker Secrets for sensitive information provides a robust approach to secrets management.

Quote: Source information available from the context provided.