Development Environment Setup

Docker Compose Configuration

The docker-compose.yml file outlines the services to be run within the Docker Compose environment. Below is an examination of the provided docker-compose.yml configuration.

Example: docker-compose.yml

services:
  frontend:
    image: nginx
    container_name: frontend
    volumes:
      - project-data:/data

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

In this configuration:

  • The frontend service utilizes the nginx image, specifying the container name as frontend.
  • A volume named project-data is created to bind to the /data directory within the frontend container. This facilitates data persistence and sharing between the host machine and the container.
  • The volume is configured with local driver options allowing it to bind to a specified directory set by the ${TEST_DIR} environment variable.

Dockerfile Structure

The Dockerfile contains several stages for building and testing the Go application. Below is an overview of the primary stages in the Dockerfile.

Example: Dockerfile

# syntax=docker/dockerfile:1

ARG GOLANGCI_LINT_VERSION=v1.55.2
ARG BUILD_TAGS="e2e"
ARG DOCS_FORMATS="md,yaml"

FROM --platform=${BUILDPLATFORM} tonistiigi/xx:${XX_VERSION} AS xx
FROM crazymax/osxcross:11.3-alpine AS osxcross
FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint
FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine AS base

COPY --from=xx / /
RUN apk add --no-cache \
      clang \
      docker \
      file \
      findutils \
      git \
      make \
      protoc \
      protobuf-dev

WORKDIR /src
ENV CGO_ENABLED=0

In the initial stage:

  • Multiple ARGs are defined for configuring versions and build tags.
  • It initializes tonistiigi/xx and crazymax/osxcross images for cross-compilation.
  • The Go environment is set up using the Golang image while installing necessary dependencies via apk.

Building and Running the Application

To initiate the development environment, it is common to use a Makefile that abstracts the build and test commands into simpler functions. Below is a representative section of a Makefile.

Example: Makefile

Available functions in Makefile: 
- build-and-e2e-compose-standalone
- build
- e2e-compose
- mocks
- validate-docs
- go-mod-tidy
- check-dependencies
- validate-go-mod
- e2e-compose-standalone
- validate-headers
- binary-with-coverage
- docs
- build-and-e2e-compose
- help
- install
- binary
- all
- validate
- pre-commit
- build-and-e2e
- lint
- test
- e2e
- cross
- cache-clear

Key Makefile targets include:

  • build: Compiles the Go application.
  • test: Runs unit tests to validate the software’s behavior.
  • lint: Executes linters on the codebase to enforce style guidelines and catch potential bugs.
  • docs: Generates documentation from the source code.

Usage of these targets can be executed in the terminal as follows:

make build
make test
make lint

Conclusion

This setup emphasizes a streamlined development process utilizing Docker for building, testing, and validating a Go application within containers. Utilizing docker-compose for service orchestration alongside a structured Dockerfile and Makefile allows for efficient development workflows.

Source: The provided information regarding Docker and Makefile configurations.