This documentation provides a step-by-step guide to configuring Docker within the development environment of FluxCD/Flux2. The examples and configurations outlined here are intended to support expert developers in effectively setting up and managing Docker for local development.

Dockerfile Configuration

The Dockerfile for the Flux CLI is configured to build from an Alpine base and install kubectl. Below is the detailed Dockerfile.

FROM alpine:3.19 as builder

RUN apk add --no-cache ca-certificates curl

ARG ARCH=linux/amd64
ARG KUBECTL_VER=1.28.6

RUN curl -sL https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VER}/bin/${ARCH}/kubectl \
    -o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl && \
    kubectl version --client=true

FROM alpine:3.19 as flux-cli

RUN apk add --no-cache ca-certificates

COPY --from=builder /usr/local/bin/kubectl /usr/local/bin/
COPY --chmod=755 flux /usr/local/bin/

USER 65534:65534
ENTRYPOINT [ "flux" ]

Explanation:

  • First stage (builder): Utilizes Alpine Linux and installs curl for downloading kubectl.
  • Second stage (flux-cli): Copies the compiled kubectl binary and the flux binary into a new image for the CLI tool.

Building and Running the Docker Image

To streamline the local environment setup, a Makefile is employed. Below are the relevant commands for building and running the Docker container.

Makefile Commands:

# Makefile

.PHONY: all build-dev
all: build-dev

build-dev:
    docker build -t flux-cli .

Usage:

Execute the following command in the terminal to build the Docker container:

make all

Running Tests with Docker

When working with Docker in the context of testing in FluxCD/Flux2, it is important to consider build constraints. The tests can be run with different tags that are defined within the project. Use the following command to run unit tests:

go test -tags=unit ./...

For end-to-end (e2e) tests, similarly, execute:

go test -tags=e2e ./...

Example of a Test Function:

func setupRegistryServer(ctx context.Context) error {
    config := &configuration.Configuration{}
    port, err := freeport.GetFreePort()
    if err != nil {
        return fmt.Errorf("failed to get free port: %s", err)
    }

    dockerReg = fmt.Sprintf("localhost:%d", port)
    config.HTTP.Addr = fmt.Sprintf("127.0.0.1:%d", port)
    config.HTTP.DrainTimeout = time.Duration(10) * time.Second
    config.Storage = map[string]configuration.Parameters{"inmemory": map[string]interface{}{}}

    dockerRegistry, err := registry.NewRegistry(ctx, config)
    if err != nil {
        return fmt.Errorf("failed to create docker registry: %w", err)
    }

    go dockerRegistry.ListenAndServe()
    return nil
}

Working with Docker Credentials

To manage credentials for private repositories hosted on DockerHub, GitHub, Quay, etc., Kubernetes secrets can be created using the following command:

kubectl create secret docker-registry regcred \
--docker-server=<DOCKER_SERVER> \
--docker-username=<USERNAME> \
--docker-password=<PASSWORD>

Injecting Secrets into Kubernetes Resources

When defining a repository or Helm chart in your Kubernetes manifests, include a secretRef to the created Docker registry secret as follows:

apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
  name: my-helm-repo
spec:
  type: oci
  secretRef:
    name: regcred

Artifact Management

Flux CLI offers commands for building and pulling artifacts, facilitating smoother integration with Docker. Below are examples of using Flux commands to manage OCI artifacts:

Building an Artifact:

flux build artifact --path ./deploy --output tmp/artifact.tgz

Pulling an Artifact:

flux pull artifact oci://docker.io/org/app-config:v1.0.0 --output ./manifests

Pushing an Artifact to Docker

To push a local directory as an OCI artifact:

flux push artifact oci://docker.io/org/app-config:v1.0.0 \
--source="$(git config --get remote.origin.url)" \
--revision="sha1:$(git rev-parse HEAD)" \
--path="./deploy"

Conclusion

The use of Docker within the development environment of FluxCD/Flux2 facilitates a streamlined and reproducible setup for developers. By adhering to these configurations and commands, one can effectively utilize Docker to enhance their local development workflow.

Sources:

  • Dockerfile, Makefile, RFC documents containing OCI artifact commands, and various Go files as outlined above.