github.com/goreleaser/goreleaser@v1.25.1/www/docs/blog/posts/2023-01-30-goreleaser-ko.md (about)

     1  ---
     2  date: 2023-01-30
     3  slug: goreleaser-ko
     4  categories:
     5    - tutorials
     6  authors:
     7    - developerguy
     8  ---
     9  
    10  # Fast and Furious Building OCI compatible Container Images with GoReleaser and ko
    11  
    12  GoReleaser and [ko][] are popular open-source, well-recognized projects, especially in the containerization and open-source ecosystem for Go applications.
    13  Many people use these projects for their Go applications because they are pretty straightforward and CI-friendly tools that make your releasing artifacts (binary and container image) process super elegant, which also helps you focus more on developing the business logic rather than planning to release software type of works.
    14  
    15  <!-- more -->
    16  
    17  I’m so glad to announce that we finally [integrated these fantastic projects](/customization/ko)!
    18  
    19  > If you are interested in learning more about the development process of that
    20  > feature, here is the [PR](https://github.com/goreleaser/goreleaser/pull/3653/) you can take a look.
    21  
    22  As a result, starting from [GoReleaser v1.15](https://github.com/goreleaser/goreleaser/milestone/17), you can build container images by setting configuration options for ko in GoReleaser without having ko installed on your environment.
    23  
    24  This post will be a quick walkthrough to guide people about how things work.
    25  
    26  Before diving into that, let’s refresh our minds about these projects with a quick recap.
    27  
    28  GoReleaser is a tool for creating and releasing Go projects. It automates the
    29  process of building, packaging, and publishing Go binaries and container images,
    30  basically the [fanciest way of releasing Go projects](https://medium.com/trendyol-tech/the-fanciest-way-of-releasing-go-binaries-with-goreleaser-dbbd3d44c7fb).
    31  It is a super user-friendly, easy-to-use, go-to CLI tool and also provides
    32  [GitHub Actions](https://github.com/goreleaser/goreleaser-action) to be
    33  CI-friendly. It also includes a bunch of features for mitigating the risks of
    34  the software supply chain attacks, such as [generating
    35  SBOMs](/customization/sbom), [signing the artifacts](/customization/sign), and
    36  many others.
    37  To get more detail, here is the [blog post](/blog/supply-chain-security) for
    38  you.
    39  
    40  On the other hand, [ko][] is specifically designed for building and publishing
    41  container images for Go projects. But the utmost vital features in ko are that
    42  it doesn’t require you to run any Docker daemon or write well-designed
    43  Dockerfiles to make the build process cache-efficient, fast and secure. The good
    44  news is that ko will consider all these and build OCI-compatible container
    45  images with all the security options enabled by default, [such as using build
    46  arguments while making Go binaries for
    47  reproducibility](https://ko.build/configuration/#overriding-go-build-settings),
    48  [generating SBOMs, and uploading them to the OCI registry](https://ko.build/features/sboms/),
    49  using the
    50  [smallest and CVE-less base
    51  image](https://github.com/ko-build/ko/blob/453bf803e379696a0b9142c772402ba4599cff34/pkg/commands/options/build.go#L35)
    52  from [Chainguard images](https://github.com/chainguard-images/images) and
    53  providing base information using OCI [base image
    54  annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md)
    55  and also it [makes easier multi-platform
    56  builds](https://ko.build/features/multi-platform/) by using the
    57  cross-compilation in Go. To get more detail, here is the [blog post](https://blog.kubesimplify.com/getting-started-with-ko-a-fast-container-image-builder-for-your-go-applications) for you.
    58  
    59  It is worth mentioning that [ko applied to become a CNCF sandbox project the last year](https://opensource.googleblog.com/2022/10/ko-applies-to-become-a-cncf-sandbox-project.html),
    60  and glad to see that this application [got accepted by the CNCF](https://lists.cncf.io/g/cncf-toc/message/7743),
    61  which means that ko is now officially a CNCF Sandbox project.
    62  
    63  Without further ado, let’s dive into the details of the integration by showing it in a real-world example.
    64  
    65  > You will find all the source code in GitHub repository,
    66  > [here](https://github.com/developer-guy/goreleaser-with-ko).
    67  
    68  Let’s start with creating a proper directory to host the source code:
    69  
    70  ```bash
    71  $ mkdir -p goreleaser-with-ko
    72  $ cd goreleaser-with-ko
    73  ```
    74  
    75  Next, initialize the project:
    76  
    77  ```bash
    78  go mod init github.com/<username>/goreleaser-with-ko
    79  cat <<EOF > main.go
    80  package main
    81  
    82  import (
    83    "fmt"
    84    "os"
    85  )
    86  var (
    87    // Version is the current version of the application.
    88    Version = "main"
    89  )
    90  func main() {
    91    fmt.Fprintf(os.Stdout, "GoReleaser supports ko! Version: %s", Version)
    92  }
    93  EOF
    94  ```
    95  
    96  It is time to create the configuration file for GoReleaser, which is
    97  [.goreleaser.yml](/customization).
    98  
    99  The easiest way of creating that file is run: `goreleaser init`, which requires
   100  GoReleaser CLI to be installed on your environment; please refer to the
   101  installation page [here](/install) to install it.
   102  
   103  ```bash
   104  # it will create the .goreleaser.yml configuration file
   105  # with bunch of default configuration options.
   106  $ goreleaser init
   107  • Generating .goreleaser.yaml file
   108  • config created; please edit accordingly to your needs file=.goreleaser.yaml
   109  ```
   110  
   111  Next, set ko configuration options into .goreleaser.yml. Fortunately, we have
   112  good documentation explaining how we can do this [here](/customization/ko).
   113  
   114  ```bash
   115  $ cat <<EOF >> .goreleaser.yml
   116  kos:
   117    - id: goreleaser-with-ko
   118      platforms:
   119      - linux/amd64
   120      - linux/arm64
   121      tags:
   122      - latest
   123      - '{{.Tag}}'
   124      bare: true
   125      flags:
   126      - -trimpath
   127      ldflags:
   128      - -s -w
   129      - -extldflags "-static"
   130      - -X main.Version={{.Tag}}
   131  EOF
   132  ```
   133  
   134  Finally, we’ll automate this workflow on the GitHub Actions platform.
   135  To do this, we need to create a proper folder structure, `.github/workflows` and
   136  put the workflow file into it:
   137  
   138  ```bash
   139  $ mkdir -p .github/workflows
   140  $ cat <<EOF > .github/workflows/release.yaml
   141  name: Releasing artifacts with GoReleaser and ko
   142  on:
   143    push:
   144      tags:
   145        - 'v*'
   146  permissions:
   147     contents: write # needed to write releases
   148     packages: write # needed for ghcr access
   149  jobs:
   150    release:
   151      runs-on: ubuntu-latest
   152      steps:
   153        - uses: actions/checkout@v3
   154          with:
   155            fetch-depth: 0 # this is important, otherwise it won't checkout the full tree (i.e. no previous tags)
   156        - uses: actions/setup-go@v3
   157          with:
   158            go-version: 1.19
   159            cache: true
   160        - uses: goreleaser/goreleaser-action@v4 # run goreleaser
   161          with:
   162            version: latest
   163            args: release --rm-dist
   164          env:
   165            KO_DOCKER_REPO: ghcr.io/${{ github.repository_owner }}/goreleaser-with-ko
   166            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
   167  EOF
   168  ```
   169  
   170  As you saw from the file above, we didn’t do anything special about ko
   171  installation, but in case you need to install it into your workflow, you can use
   172  the [setup-ko](https://github.com/ko-build/setup-ko) GitHub Action for that. But how?
   173  
   174  Since ko’s core packages that provide such building and publishing capabilities
   175  are exported functions, you can use them in your own Go projects to get more
   176  detail [here](https://ko.build/advanced/go-packages/).
   177  The following projects are great examples of that:
   178  
   179  - [terraform-provider-ko](https://github.com/ko-build/terraform-provider-ko/blob/main/internal/provider/resource_ko_image.go)
   180  - [miniko](https://github.com/imjasonh/miniko)
   181  - And now, [GoReleaser](https://github.com/goreleaser/goreleaser/blob/main/internal/pipe/ko/ko.go)
   182  
   183  And that’s it. All you need to do at that point is give a tag to your project and wait for the GitHub workflow to be completed to release your software.
   184  
   185  ```bash
   186  $ git commit -m"initial commit" -s
   187  $ git tag v0.1.0 -m"first release"
   188  $ git push origin v0.1.0
   189  ```
   190  
   191  One last note: please remember to use this feature and provide feedback to help us improve this process. Thanks for reading; I hope you enjoyed it; see you in the next blog posts.
   192  
   193  [ko]: https://ko.build/