Continuous Build and Deployment of Go Applications with Google Cloud Build

Setup

Building Go web apps and daemons (services)

Dockerfile

FROM golang:1.17 AS build WORKDIR /app/agent 
COPY . .
RUN CGO_ENABLED=0 go build -o /app/agent/agent
FROM alpine
LABEL maintainer="ACME Engineering <acme@example.com>"

RUN mkdir /app
# Copy any other files required in the final image here
COPY --from=build /app/agent/agent /app/agent
ENTRYPOINT ["/app/agent"]
package utils var ( 
Commit string = "dev"
)
FROM golang:1.17 AS build 
ARG SHORT_SHA
WORKDIR /app/agent
COPY . .
RUN CGO_ENABLED=0 go build -o /app/agent/agent -ldflags="-X 'github.com/acme/example/agent/utils.Commit=${SHORT_SHA}'"
FROM alpine
LABEL maintainer="ACME Engineering <acme@example.com>"
RUN mkdir /app
# Copy any other files required in the final image here
COPY --from=build /app/agent/agent /app/agent
ENTRYPOINT ["/app/agent"]

cloudbuild.json

{ 
"steps": [
{
"name": "gcr.io/kaniko-project/executor:latest",
"id": "agent",
"args": [
"--context=./agent",
"--destination=gcr.io/$PROJECT_ID/agent:$SHORT_SHA",
"--build-arg=SHORT_SHA=$SHORT_SHA",
"--cache=true", "--cache-ttl=5h"
]
},
{
"name": "gcr.io/cloud-builders/gcloud",
"id": "agent-retag",
"waitFor": [
"agent"
],
"args": [
"--quiet",
"container",
"images",
"add-tag",
"gcr.io/$PROJECT_ID/ct-agent:$SHORT_SHA",
"gcr.io/$PROJECT_ID/ct-agent:latest"
]
}
]
}

Cloud Build Setup (triggers)

Bonus Step (deployment to Kubernetes)

{ 
"name": "gcr.io/cloud-builders/gke-deploy",
"args": [
"run",
"--filename=deployment.yml",
"--location=us-east4-a",
"--cluster=example"
]
}

Building Go CLI apps

Cross-Platform Builds

steps: 
- id: go-build-mac
name: "gcr.io/cloud-builders/go"
args: ["build", "-o", "mycli_darwin_$TAG_NAME", "-ldflags=-X 'github.com/example/mycli/cmd.Version=$TAG_NAME' -X 'github.com/example/mycli/cmd.Commit=$SHORT_SHA'", "."]
env: ['PROJECT_ROOT=ctx', "GOOS=darwin", "GOARCH=amd64"]
- id: go-build-linux
name: "gcr.io/cloud-builders/go"
args: ["build", "-o", "mycli_linux_$TAG_NAME", "-ldflags=-X 'github.com/example/mycli/cmd.Version=$TAG_NAME' -X 'github.com/example/mycli/cmd.Commit=$SHORT_SHA'", "."]
env: ['PROJECT_ROOT=ctx', "GOOS=linux", "GOARCH=amd64"]
- id: replace-version
name: "gcr.io/cloud-builders/gcloud"
entrypoint: "bash"
args:
- "replace.sh"
- "$TAG_NAME"
artifacts:
objects:
location: 'gs://example_bucket/ctx/'
paths: ['mycli_darwin_$TAG_NAME', 'mycli_linux_$TAG_NAME', 'version.json']

Optional Step: Generate version files

  1. A version.json file that contains the latest version number of the tool.
  2. Some simple Go code to download version.json and compare the latest version with the executable's version.
#!/bin/bash version=$1 
sed_pattern='s/\$VERSION/'$version'/'
sed $sed_pattern version.template.json > version.json
{ 
"version": "$VERSION"
}

--

--

DevOps-as-a-Service to help developers build, deploy and maintain apps on any Cloud. Sign-up for a free trial by visting: www.cloud66.com

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store