Project ⏱ 18 min read

13 · Build & Deploy

make build, Dockerfile, GitLab CI, Argo Rollouts blue/green

Building the Binary

# Compile to bin/api with version string injected
make build

# Equivalent command:
go build -ldflags "-X main.Version=$(git describe --tags --always)" -o bin/api .

# Run the binary directly
./bin/api

The Version variable in main.go gets the git tag at build time. It appears in the /health and / responses so you know exactly which version is running.

Dockerfile

# Multi-stage build: builder stage compiles, final stage is minimal
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download          # cache dependencies as a layer
COPY . .
RUN go build -o bin/api .

FROM alpine:latest           # minimal final image (~10MB)
COPY --from=builder /app/bin/api /api
ENTRYPOINT ["/api"]

Multi-stage builds keep the final image small — no Go compiler, no source code. Only the binary.

GitLab CI Pipeline

Defined in .gitlab-ci.yml. Key stages:

stages:
  - test      # go test ./...
  - build     # docker build + push to registry
  - deploy    # update Argo Rollout image tag → triggers blue/green

# Deploy stage sets the new image on the Rollout resource
deploy:
  script:
    - kubectl argo rollouts set image <rollout-name>
        api=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

The image tag is the commit SHA — every push creates a unique, traceable image. Setting a new image on the Rollout automatically starts a blue/green update: the new version goes to the preview pod while the active pod keeps serving customers.

Blue/Green with Argo Rollouts

Argo Rollouts extends Kubernetes with a Rollout resource that manages blue/green and canary strategies. In blue/green mode it maintains two pods: active (serving 100% of customer traffic) and preview (new version, reachable only via the preview service URL). You deploy to preview, run sanity tests, then either promote or abort.

Active
v1.2.3
● 100% customer traffic
Preview
idle
Deploy → sanity test → choose outcome
Sanity result:
1. CI sets new image tag on Rollout resource
2. Argo creates preview pod with v1.3.0 — active unchanged
3. Sanity tests run against preview service URL
Zero customer impact: Active pod keeps serving 100% of traffic throughout the entire deploy. Only after an explicit promote does traffic shift — and it shifts atomically, not gradually.

Key Takeaways