[Go] Build Go container images using ko

Sarvsav Sharma
goismo
Published in
5 min readMar 28, 2024

Build your Go application container images easy, fast, and secure by default using ko — open source CNCF sandbox project.

Source: ko

Introduction

What is ko ?

It is an open source container image builder for your go applications. It is not dependent on the docker and produces SBOMs by default. Google has applied this project as a part of sandbox cncf.

What is SBOM?

SBOM stands for Software Bill of Materials. Think of it like a grocery list but for software. It’s a list that shows all the ingredients or components that make up a piece of software. Just like you’d want to know what’s in your food, people in tech want to know what’s in their software to understand its makeup and potential vulnerabilities. It helps them keep track of what’s inside and stay on top of any updates or security fixes needed.

How it builds?

It builds the images by executing go build command on your local machine and will easily be integrated to the CI/CD environment.

What is lacking?

It doesn’t support cgo and os package dependencies. It only supports Go .

Installation

My system details are below

OS: Ubuntu 22.04.04 LTS
Go: go version go1.22.0 linux/amd64
Docker Desktop: 4.20.1

The recommended way to install it using the go install as it doesn’t require root access. Run the below command in your terminal.

go install github.com/google/ko@latest

Once installed, you can verify it by running the ko help in your terminal.

Demo

ko reads the configuration from the ~/.docker/config.json to push the generated container images to container registry. If the credentials are available, then it will push the image to registry. For our demo purpose, we will set the environment variable KO_DOCKER_REPO and publish locally.

Start with your go project, or you can clone this project — learnyougo.

git clone git@github.com:sarvsav/learnyougo.git

Once the project is cloned, cd to project directory, and try to run using go .

$ cd learnyougo
$ go mod tidy
$ go work use . # If you are using go workspace
$ go run main.go
Welcome to learnyougo. We are glad to have you here, and congratulations on taking the first step of your journey to learn Go!

Nice, everything looks good so far. Time to export the variables,

## Find the location for your docker.sock file
$ netstat -lnp | grep docker.sock | awk '{print $NF}'
/home/sarvsav/.docker/desktop/docker.sock

## We need to update the docker host, by default ko will look inside /var/run/docker.sock
$ export DOCKER_HOST="unix://${HOME}/.docker/desktop/docker.sock"

## Inform ko to store docker image locally
$ export KO_DOCKER_REPO=ko.local

Build the container image,

ko icon
$ ko build .                                  
2024/03/28 11:09:40 Using base cgr.dev/chainguard/static:latest@sha256:739aaf25ce9c6ba75c3752d7fde4a94de386c6f44eba27239d2b98e91752e3ff for github.com/sarvsav/learnyougo
2024/03/28 11:09:42 Building github.com/sarvsav/learnyougo for linux/amd64
2024/03/28 11:09:43 Loading ko.local/learnyougo-6f63146ad33f5c470f887a0763549b51:5904bb23cd4b2561af1de6dbfc05dac44f24870a97d1fa7c7991dd4a39af7015
2024/03/28 11:09:45 Loaded ko.local/learnyougo-6f63146ad33f5c470f887a0763549b51:5904bb23cd4b2561af1de6dbfc05dac44f24870a97d1fa7c7991dd4a39af7015
2024/03/28 11:09:45 Adding tag latest
2024/03/28 11:09:45 Added tag latest
ko.local/learnyougo-6f63146ad33f5c470f887a0763549b51:5904bb23cd4b2561af1de6dbfc05dac44f24870a97d1fa7c7991dd4a39af7015

Verification

The image will be available, with the image name <registry-name>/<app-name>-md5 hash, md5 hash of the full import path, and tag as latest. In our case, it should be

registry name: ko.local
app name: learnyougo
md5 hash: xxxx
tag: latest

and same has been printed as an output for ko build command. Locate the image, using docker images command.

$ docker images | grep learnyougo
ko.local/learnyougo-6f63146ad33f5c470f887a0763549b51 5904bb23cd4b2561af1de6dbfc05dac44f24870a97d1fa7c7991dd4a39af7015 7cfe73869e82 3 days ago 22.3MB
ko.local/learnyougo-6f63146ad33f5c470f887a0763549b51 latest 7cfe73869e82 3 days ago 22.3MB

And, run the image now to verify the output.

$ docker run ko.local/learnyougo-6f63146ad33f5c470f887a0763549b51:latest 
Welcome to learnyougo. We are glad to have you here, and congratulations on taking the first step of your journey to learn Go!

Demo using harbor (Without docker enginer)

Source: Harbor

Harbor is an open source project and code is found on github. It is an open source trusted cloud native registry project that stores, signs, and scans content.

Create an account here: Harbor Demo to store the artifacts.

Source: Demo Harbor

Once signed up, login with the credentials. It will open a projects page, and click on New Project . For example, let’s create a project named medium-demo .

Source: harbor demo

Adding new project.

Source: harbor demo

Now, we can access the project page for medium-demo .

Source: Harbor demo

Click on push command, and get the value for url to publish.

Source: Harbor demo

Copy the registry name, as we need to export this variable to ko . In our case, it would be: demo.goharbor.io/medium-demo/

$ export KO_DOCKER_REPO=demo.goharbor.io/medium-demo/

Use the same credentials to login for ko binary.

$ ko login demo.goharbor.io -u sarvsav -p <password>
2024/05/20 14:06:33 logged in via C:\Users\sarvsav\.docker\config.json

And, finally build it using ko build . .

$ ko build .
2024/05/20 14:30:33 Using base cgr.dev/chainguard/static:latest@sha256:110b6918893ea3df0eec04b2f469f3af07e5439900ed259076c55cefb1ec3965 for github.com/sarvsav/tictactoe-ui/example
2024/05/20 14:30:35 current folder is not a git repository. Git info will not be available
2024/05/20 14:30:35 Building github.com/sarvsav/tictactoe-ui/example for linux/amd64
2024/05/20 14:30:37 Publishing demo.goharbor.io/medium-demo/example-30840f2fe20f0e504ce7880e9939c3de:latest
2024/05/20 14:30:39 pushed blob: sha256:250c06f7c38e52dc77e5c7586c3e40280dc7ff9bb9007c396e06d96736cf8542
2024/05/20 14:30:39 pushed blob: sha256:f2c441468d5f3936093918f0bd0ada616b41cf323b9132d52da6856c89df3fd6
2024/05/20 14:30:39 pushed blob: sha256:b82003a4b7a394ff329daac8220396650b0e35c2c4ac3634c5f4759231bc5e94
2024/05/20 14:30:39 pushed blob: sha256:d9426566d01b6852465e6afa3cc2e4cde32dbfaa4b37df9eff3bacc96fae51d9
2024/05/20 14:30:39 demo.goharbor.io/medium-demo/example-30840f2fe20f0e504ce7880e9939c3de:sha256-c1529e6772a58cf1b17dc9e72ca7379b6ec08fb87bfad74a96e78d631c2e4805.sbom: digest: sha256:b5d15200fbb5e5a2ad8bdb00bda6acb46814bb06e4f87b4288b497c72f5a18ba size: 373
2024/05/20 14:30:39 Published SBOM demo.goharbor.io/medium-demo/example-30840f2fe20f0e504ce7880e9939c3de:sha256-c1529e6772a58cf1b17dc9e72ca7379b6ec08fb87bfad74a96e78d631c2e4805.sbom
2024/05/20 14:30:40 pushed blob: sha256:2dd2311f16903d5a56695cfd551787771fa9cf6e42d82cfb461cc43ebb54093c
2024/05/20 14:30:41 pushed blob: sha256:731d0fcf7e38d9b77d911e438eccdf6b1235e035dec5b312f02483241b98305e
2024/05/20 14:30:41 demo.goharbor.io/medium-demo/example-30840f2fe20f0e504ce7880e9939c3de:latest: digest: sha256:c1529e6772a58cf1b17dc9e72ca7379b6ec08fb87bfad74a96e78d631c2e4805 size: 1210
2024/05/20 14:30:41 Published demo.goharbor.io/medium-demo/example-30840f2fe20f0e504ce7880e9939c3de@sha256:c1529e6772a58cf1b17dc9e72ca7379b6ec08fb87bfad74a96e78d631c2e4805
demo.goharbor.io/medium-demo/example-30840f2fe20f0e504ce7880e9939c3de@sha256:c1529e6772a58cf1b17dc9e72ca7379b6ec08fb87bfad74a96e78d631c2e4805Troubleshooting

The image can be visible on the projects page.

Source: harbor

You can also go to image description and get the pull command for docker or podman .

Source: harbor

Troubleshooting

  1. While building, Error: failed to publish images: error publishing : error loading image: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
    Verify that you have exported the DOCKER_HOST variable and pointing to docker.sock file.

Hope you enjoyed the article.

Shower your love ❤

Clap guide in summary:

1–2 Claps — An average article

3–10 Claps — Very good article

11–20 Claps — Very helpful and value addition

21+ Claps — Supporting your efforts :)

Thank you for reading.

--

--

Sarvsav Sharma
goismo
Writer for

Mostly writes about Go, GitHub, and DevSecOps. Interested in distributed systems. GitHub:sarvsav Maintainer:go-feature-flag/gofeatureflag-lint-action