Production Secrets Management with docker/build-push-action

Overview

In a production system, the management of secrets is crucial for ensuring security and maintaining the integrity of applications. This document describes how secrets may be utilized within the context of building and pushing Docker images using the docker/build-push-action in conjunction with other components such as Docker and Go applications.

Secret Storage

Secrets can be managed using a variety of methods. In this scenario, we will illustrate how secrets might be stored and used within a Docker ecosystem:

  1. Environment Variables: This is one of the simplest methods to pass secrets to your application. The secrets are set as environment variables in the CI/CD pipeline.

  2. Docker Secrets: For containerized applications, Docker Swarm and Kubernetes provide secure ways to manage secrets.

Example Implementation

Step 1: Define Secrets in CI/CD Pipeline

In your workflow file, define the secrets you want to use in GitHub Actions. These secrets can be accessed in the environment of the action.

name: Build and Push Docker Image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Build and push Docker image
        uses: docker/build-push-action@v2
        with:
          context: .
          push: true
          tags: my-image:latest
        env:
          MY_SECRET: ${{ secrets.MY_SECRET }}

Step 2: Use Environment Variables in Dockerfile

You can leverage the passed secrets by declaring environment variables in your Dockerfile.

# syntax=docker/dockerfile:1
FROM alpine

ARG MY_SECRET

RUN echo "Using secret: $MY_SECRET"

In this example, $MY_SECRET will hold the value of the secret defined in the CI/CD pipeline.

Step 3: Integrate with Go Application

In a Go application, you can retrieve the environment variable as follows:

package main

import (
    "fmt"
    "os"
)

func main() {
    secret := os.Getenv("MY_SECRET")
    fmt.Printf("The secret is: %s\n", secret)
}

Step 4: Build and Deploy

With the docker-compose.yml, manage your application’s deployment context:

services:
  nexus:
    image: sonatype/nexus3:${NEXUS_VERSION:-latest}
    volumes:
      - "./data:/nexus-data"
    ports:
      - "8081:8081"
      - "8082:8082"

Run the following command to start your services:

docker-compose up -d

Conclusion

The approach detailed here demonstrates effective practices for managing secrets in production environments with docker/build-push-action. By using environment variables, secured secrets can be seamlessly integrated into your Docker images and Go applications without compromising security.

Source: github.com/docker/build-push-action/test/go