Overview

Docker provides a streamlined way to isolate and manage the development environment for helixml/helix. The following sections describe step-by-step instructions on how Docker is configured within the development environment, focusing specifically on the Dockerfile that defines the build process.

Dockerfile Breakdown

The Dockerfile sets up the environment for both the backend (written in Go) and the frontend (written in TypeScript/JavaScript). Below is a detailed breakdown of each stage of the Dockerfile.

Backend Build

FROM golang:1.22 AS go-build-env
WORKDIR /app

COPY go.mod .
COPY go.sum .

RUN go mod download

COPY api ./api
COPY .git /.git

WORKDIR /app/api

RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o /helix
  1. Base Image: The build begins with the Golang base image golang:1.22. This provides the necessary tools and libraries for Go development.

  2. Working Directory: The working directory is set to /app, where the application’s source code will reside.

  3. Dependency Management:

    • Copy go.mod and go.sum files to the workspace to manage dependencies.
    • Execute go mod download to download the Go module dependencies defined in those files.
  4. Source Code Copying: The api directory and .git directory are copied into the container for building the backend.

  5. Final Build Stage:

    • Change the working directory to /app/api.
    • Build the Go application with the go build command. The CGO_ENABLED=0 flag ensures a statically linked binary, which is crucial for compatibility and minimalism in the Docker image.

Frontend Build

FROM node:21-alpine AS ui-build-env

WORKDIR /app

RUN echo "installing apk packages" && \
  apk update && \
  apk upgrade && \
  apk add \
    bash \
    git \
    curl \
    openssh

COPY ./frontend/*.json /app/
COPY ./frontend/yarn.lock /app/yarn.lock

RUN yarn install

COPY ./frontend /app

RUN yarn build
  1. Base Image for Frontend: The Node.js base image node:21-alpine is used for building the frontend components.

  2. Working Directory: Transition to the /app directory for frontend code management.

  3. Package Installation:

    • Update Alpine packages and install essential tools such as bash, git, curl, and openssh using apk. This makes sure the environment is equipped for building and managing dependencies.
  4. Dependency Management for Frontend:

    • The JSON configuration files and yarn.lock are copied into the working directory.
    • yarn install is executed to install all Node.js dependencies specified in package.json and locked in yarn.lock.
  5. Building the Frontend:

    • The rest of the frontend source code is copied.
    • Finally, yarn build compiles the frontend application into static files for production.

Final Image

FROM alpine:3.17
RUN apk --update add ca-certificates

COPY --from=go-build-env /helix /helix
COPY --from=ui-build-env /app/dist /www

ENV FRONTEND_URL=/www

ENTRYPOINT ["/helix", "serve"]
  1. Base Image: The final image is based on alpine:3.17, chosen for its minimal size and security.

  2. Certificate Installation: The command apk --update add ca-certificates ensures that the application can make HTTPS requests.

  3. Final Artifacts:

    • The built Go binary is copied from the go-build-env stage.
    • The compiled frontend static files are copied from the ui-build-env.
  4. Environment Configuration: The environment variable FRONTEND_URL points to the location of the frontend assets.

  5. Entrypoint Configuration: The container is set to run the helix binary with the serve command as the entry point.

Conclusion

This detailed breakdown highlights how Docker is utilized within the development environment for helixml/helix. Each build stage is carefully crafted to optimize both the backend and frontend environments using the appropriate tools and configurations.

(Source: Helix Dockerfile)