diff --git a/.github/workflows/publish-site.yaml b/.github/workflows/publish-site.yaml new file mode 100644 index 0000000000..18ca1fd550 --- /dev/null +++ b/.github/workflows/publish-site.yaml @@ -0,0 +1,16 @@ +name: publish +on: + workflow_dispatch: + push: + branches: ['main'] + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.x + - run: pip install mkdocs-material + - run: mkdocs gh-deploy --force \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..c6b7a9f30b --- /dev/null +++ b/docs/README.md @@ -0,0 +1,26 @@ +# Docs for https://ko.build + +## Development + +Update `.md` files to update content. + +Update `mkdocs.yml` to update sidebar headers and ordering. + +To run locally: + +- [install `mkdocs` and `mkdocs-material`](https://squidfunk.github.io/mkdocs-material/getting-started/) and run `mkdocs serve`, or +- `docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material` + - on an M1 Mac, use `ghcr.io/afritzler/mkdocs-material` instead. + +This will start a local server on localhost:8000 that autoupdates as you make changes. + +## Deployment + +When PRs are merged, the site will be rebuilt and published automatically. + +### Credits + +The site is powered by [mkdocs-material](https://squidfunk.github.io/mkdocs-material). The code and theme are released under the MIT license. + +Content is licensed [CC-BY](https://creativecommons.org/licenses/by/4.0/). + diff --git a/docs/advanced/faq.md b/docs/advanced/faq.md new file mode 100644 index 0000000000..4566dc7348 --- /dev/null +++ b/docs/advanced/faq.md @@ -0,0 +1,113 @@ +# Frequently Asked Questions + +## How can I set `ldflags`? + +[Using -ldflags](https://blog.cloudflare.com/setting-go-variables-at-compile-time/) is a common way to embed version info in go binaries (In fact, we do this for `ko`!). +Unfortunately, because `ko` wraps `go build`, it's not possible to use this flag directly; however, you can use the `GOFLAGS` environment variable instead: + +```sh +GOFLAGS="-ldflags=-X=main.version=1.2.3" ko build . +``` + +Currently, there is a limitation that does not allow to set multiple arguments in `ldflags` using `GOFLAGS`. +Using `-ldflags` multiple times also does not work. +In this use case, it works best to use the [`builds` section](./../configuration) in the `.ko.yaml` file. + +## Why are my images all created in 1970? + +In order to support [reproducible builds](https://reproducible-builds.org), `ko` doesn't embed timestamps in the images it produces by default. + +However, `ko` does respect the [`SOURCE_DATE_EPOCH`](https://reproducible-builds.org/docs/source-date-epoch/) environment variable, which will set the container image's timestamp accordingly. + +Similarly, the `KO_DATA_DATE_EPOCH` environment variable can be used to set the _modtime_ timestamp of the files in `KO_DATA_PATH`. + +For example, you can set the container image's timestamp to the current timestamp by executing: + +```sh +export SOURCE_DATE_EPOCH=$(date +%s) +``` + +or set the timestamp of the files in `KO_DATA_PATH` to the latest git commit's timestamp with: + +```sh +export KO_DATA_DATE_EPOCH=$(git log -1 --format='%ct') +``` + +## Can I build Windows containers? + +Yes, but support for Windows containers is new, experimental, and tenuous. Be prepared to file bugs. 🐛 + +The default base image does not provide a Windows image. +You can try out building a Windows container image by [setting the base image](./../configuration) to a Windows base image and building with `--platform=windows/amd64` or `--platform=all`: + +For example, to build a Windows container image, update your `.ko.yaml` to set the base image: + +```plaintext +defaultBaseImage: mcr.microsoft.com/windows/nanoserver:ltsc2022 +``` + +And build for `windows/amd64`. + +```sh +ko build ./ --platform=windows/amd64 +``` + +### Known issues 🐛 + +- Symlinks in `kodata` are ignored when building Windows images; only regular files and directories will be included in the Windows image. + +## Can I optimize images for [eStargz support](https://github.com/containerd/stargz-snapshotter/blob/v0.7.0/docs/stargz-estargz.md)? + +Yes! Set the environment variable `GGCR_EXPERIMENT_ESTARGZ=1` to produce eStargz-optimized images. + +## Does `ko` support autocompletion? + +Yes! `ko completion` generates a Bash/Zsh/Fish/PowerShell completion script. +You can get how to load it from help document. + +```sh +ko completion [bash|zsh|fish|powershell] --help +``` + +Or, you can source it directly: + +```bash +source <(ko completion) +``` + +## Does `ko` work with [Kustomize](https://kustomize.io/)? + +Yes! `ko resolve -f -` will read and process input from stdin, so you can have `ko` easily process the output of the `kustomize` command. + +```sh +kustomize build config | ko resolve -f - +``` + +## Does `ko` integrate with other build and development tools? + +Oh, you betcha. Here's a partial list: + +- `ko` support in [Carvel's `kbld`](https://carvel.dev/kbld/docs/latest/config/#ko) +- `ko` support in [Skaffold](https://skaffold.dev/docs/pipeline-stages/builders/ko/) +- `ko` extension for [Tilt](https://github.com/tilt-dev/tilt-extensions/tree/master/ko) +- `ko` support for [goreleaser](https://github.com/goreleaser/goreleaser/pull/2564) (proposed) + +## Does `ko` work with [OpenShift Internal Registry](https://docs.openshift.com/container-platform/latest/registry/registry-options.html#registry-integrated-openshift-registry_registry-options)? + +Yes! Follow these steps: + +1. [Connect to your OpenShift installation](https://docs.openshift.com/container-platform/latest/cli_reference/openshift_cli/getting-started-cli.html#cli-logging-in_cli-developer-commands) +1. [Expose the OpenShift Internal Registry](https://docs.openshift.com/container-platform/latest/registry/securing-exposing-registry.html) so you can push to it: +1. Export your token to `$HOME/.docker/config.json`: + +```sh +oc registry login --to=$HOME/.docker/config.json +``` + +1. Create a namespace where you will push your images, i.e: `ko-images` +1. Execute this command to set `KO_DOCKER_REPO` to publish images to the internal registry. + +```sh +export KO_DOCKER_REPO=$(oc registry info --public)/ko-images +``` + diff --git a/docs/advanced/go-packages.md b/docs/advanced/go-packages.md new file mode 100644 index 0000000000..3982b2a101 --- /dev/null +++ b/docs/advanced/go-packages.md @@ -0,0 +1,6 @@ +# Go Packages + +`ko`'s functionality can be consumed as a library in a Go application. + +To build an image, use [`pkg/build`](https://pkg.go.dev/github.com/google/ko/pkg/build), and publish it with [`pkg/publish`](https://pkg.go.dev/github.com/google/ko/pkg/publish). + diff --git a/docs/advanced/limitations.md b/docs/advanced/limitations.md new file mode 100644 index 0000000000..c3cde8c206 --- /dev/null +++ b/docs/advanced/limitations.md @@ -0,0 +1,12 @@ +# Limitations + +`ko` works best when your application has no dependencies on the underlying image. + +This means `ko` is ideal when you don't require [cgo](https://pkg.go.dev/cmd/cgo), and builds are executed with `CGO_ENABLED=0` by default. + +To install other OS packages, make those available in your [configured base image](./../configuration). + +`ko` only supports Go applications. +For a similar tool targeting Java applications, try [Jib](https://github.com/GoogleContainerTools/jib). +For other languages, try [apko](https://github.com/chainguard-dev/apko) and [melange](https://github.com/chainguard-dev/melange). + diff --git a/docs/advanced/migrating-from-dockerfile.md b/docs/advanced/migrating-from-dockerfile.md new file mode 100644 index 0000000000..af6058f818 --- /dev/null +++ b/docs/advanced/migrating-from-dockerfile.md @@ -0,0 +1,64 @@ +# Migrating from Dockerfile + +If your `Dockerfile` looks like either of the examples in the [official tutorial for writing a Dockerfile to containerize a Go application](https://docs.docker.com/language/golang/build-images/), you can easily migrate to use `ko` instead. + +Let's review the best practice multi-stage Dockerfile in that tutorial first: + +```plaintext +# syntax=docker/dockerfile:1 + +## +## Build +## +FROM golang:1.16-buster AS build + +WORKDIR /app + +COPY go.mod ./ +COPY go.sum ./ +RUN go mod download + +COPY *.go ./ + +RUN go build -o /docker-gs-ping + +## +## Deploy +## +FROM gcr.io/distroless/base-debian10 + +WORKDIR / + +COPY --from=build /docker-gs-ping /docker-gs-ping + +EXPOSE 8080 + +USER nonroot:nonroot + +ENTRYPOINT ["/docker-gs-ping"] +``` + +This `Dockerfile`: + +1. pulls the `golang:1.16` image +1. `COPY`s your local source into the container environment (`COPY`ing `go.mod` and `go.sum` first and running `go mod download`, to cache dependencies in the container environment) +1. `RUN`s `go build` on your source, inside the container, to produce an executable +1. `COPY`s the executable built in the previous step into a new image, on top of a minimal [distroless](https://github.com/GoogleContainerTools/distroless) base image. + +The result is a Go application built on a minimal base image, with an optimally cached build sequence. + +After running `docker build` on this `Dockerfile`, don't forget to push that image to the registry so you can deploy it. + +--- + +## Migrating to `ko` + +If your Go source is laid out as described in the tutorial, and you've [installed](./../install) and [set up your environment](./../get-started), you can simply run `ko build ./` to build and push the container image to your registry. + +You're done. You can delete your `Dockerfile` and uninstall `docker`. + +`ko` takes advantage of your local [Go build cache](./../features/build-cache) without needing to be told to, and it sets the `ENTRYPOINT` and uses a nonroot distroless base image by default. + +To build a multi-arch image, simply add `--platform=all`. +Compare this to the [equivalent Docker instructions](https://docs.docker.com/desktop/multi-arch/). + diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000000..a43f23662e --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,114 @@ +# Configuration + +## Basic Configuration + +Aside from `KO_DOCKER_REPO`, you can configure `ko`'s behavior using a +`.ko.yaml` file. The location of this file can be overridden with +`KO_CONFIG_PATH`. + +### Overriding Base Images + +By default, `ko` bases images on `gcr.io/distroless/static:nonroot`. This is a +small image that provides the bare necessities to run your Go binary. + +You can override this base image in two ways: + +1. To override the base image for all images `ko` builds, add this line to your + `.ko.yaml` file: + +```yaml +defaultBaseImage: registry.example.com/base/image +``` + +2. To override the base image for certain importpaths: + +```yaml +baseImageOverrides: + github.com/my-user/my-repo/cmd/app: registry.example.com/base/for/app + github.com/my-user/my-repo/cmd/foo: registry.example.com/base/for/foo +``` + +### Overriding Go build settings + +By default, `ko` builds the binary with no additional build flags other than +`-trimpath`. You can replace the default build +arguments by providing build flags and ldflags using a +[GoReleaser](https://github.com/goreleaser/goreleaser) influenced `builds` +configuration section in your `.ko.yaml`. + +```yaml +builds: +- id: foo + dir: . # default is . + main: ./foobar/foo + env: + - GOPRIVATE=git.internal.example.com,source.developers.google.com + flags: + - -tags + - netgo + ldflags: + - -s -w + - -extldflags "-static" + - -X main.version={{.Env.VERSION}} +- id: bar + dir: ./bar + main: . # default is . + env: + - GOCACHE=/workspace/.gocache + ldflags: + - -s + - -w +``` + +If your repository contains multiple modules (multiple `go.mod` files in +different directories), use the `dir` field to specify the directory where +`ko` should run `go build`. + +`ko` picks the entry from `builds` based on the import path you request. The +import path is matched against the result of joining `dir` and `main`. + +The paths specified in `dir` and `main` are relative to the working directory +of the `ko` process. + +The `ldflags` default value is `[]`. + +> 💡 **Note:** Even though the configuration section is similar to the +[GoReleaser `builds` section](https://goreleaser.com/customization/build/), +only the `env`, `flags` and `ldflags` fields are currently supported. Also, the +templating support is currently limited to using environment variables only. + +## Naming Images + +`ko` provides a few different strategies for naming the image it pushes, to +workaround certain registry limitations and user preferences: + +Given `KO_DOCKER_REPO=registry.example.com/repo`, by default, +`ko build ./cmd/app` will produce an image named like +`registry.example.com/repo/app-`, which includes the MD5 hash of the full +import path, to avoid collisions. + +- `--preserve-import-path` (`-P`) will include the entire importpath: + `registry.example.com/repo/github.com/my-user/my-repo/cmd/app` +- `--base-import-paths` (`-B`) will omit the MD5 portion: + `registry.example.com/repo/app` +- `--bare` will only include the `KO_DOCKER_REPO`: `registry.example.com/repo` + +## Local Publishing Options + +`ko` is normally used to publish images to container image registries, +identified by `KO_DOCKER_REPO`. + +`ko` can also load images to a local Docker daemon, if available, by setting +`KO_DOCKER_REPO=ko.local`, or by passing the `--local` (`-L`) flag. + +Local images can be used as a base image for other `ko` images: + +```yaml +defaultBaseImage: ko.local/example/base/image +``` + +`ko` can also load images into a local [KinD](https://kind.sigs.k8s.io) +cluster, if available, by setting `KO_DOCKER_REPO=kind.local`. By default this +loads into the default KinD cluster name (`kind`). To load into another KinD +cluster, set `KIND_CLUSTER_NAME=my-other-cluster`. + diff --git a/docs/custom/main.html b/docs/custom/main.html new file mode 100644 index 0000000000..18e6d90bb9 --- /dev/null +++ b/docs/custom/main.html @@ -0,0 +1,10 @@ +{% extends "base.html" %} + +{% block site_meta %} + {{ super() }} + {% if page and page.meta and page.meta.ko_meta %} + + + + {% endif %} +{% endblock %} diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 0000000000..913a40e5a7 --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,61 @@ +# Deployment + +_See [Kubernetes Integration](./features/k8s) for information about deploying to Kubernetes._ + +Because the output of `ko build` is an image reference, you can easily pass it to other tools that expect to take an image reference. + +### [`docker run`](https://docs.docker.com/engine/reference/run/) + +To run the container locally: + +```plaintext +docker run -p 8080:8080 $(ko build ./cmd/app) +``` + +--- + +### [Google Cloud Run](https://cloud.google.com/run) + +```plaintext +gcloud run deploy --image=$(ko build ./cmd/app) +``` + +> 💡 **Note:** The image must be pushed to [Google Container Registry](https://cloud.google.com/container-registry) or [Artifact Registry](https://cloud.google.com/artifact-registry). + +--- + +### [fly.io](https://fly.io) + +```plaintext +flyctl launch --image=$(ko build ./cmd/app) +``` + +> 💡 **Note:** The image must be publicly available. + +--- + +### [AWS Lambda](https://aws.amazon.com/lambda/) + +```plaintext +aws lambda update-function-code \ + --function-name=my-function-name \ + --image-uri=$(ko build ./cmd/app) +``` + +> 💡 **Note:** The image must be pushed to [ECR](https://aws.amazon.com/ecr/), based on the AWS provided base image, and use the [`aws-lambda-go`](https://github.com/aws/aws-lambda-go) framework. +See [official docs](https://docs.aws.amazon.com/lambda/latest/dg/go-image.html) for more information. + +--- + +### [Azure Container Apps](https://azure.microsoft.com/services/container-apps/) + +```plaintext +az containerapp update \ + --name my-container-app + --resource-group my-resource-group + --image $(ko build ./cmd/app) +``` + +> 💡 **Note:** The image must be pushed to [ACR](https://azure.microsoft.com/services/container-registry/) or other registry service. +See [official docs](https://docs.microsoft.com/azure/container-apps/) for more information. + diff --git a/docs/features/build-cache.md b/docs/features/build-cache.md new file mode 100644 index 0000000000..7e1a07bf7c --- /dev/null +++ b/docs/features/build-cache.md @@ -0,0 +1,9 @@ +# Build Cache + +Because `ko` just runs `go build` in your normal development environment, it automatically reuses your [`go build` cache](https://pkg.go.dev/cmd/go#hdr-Build_and_test_caching) from previous builds, making iterative development faster. + +`ko` also avoids pushing blobs to the remote image registry if they're already present, making pushes faster. + +You can make `ko` even faster by setting the `KOCACHE` environment variable. +This tells `ko` to store a local mapping between the `go build` inputs to the image layer that they produce, so `go build` can be skipped entirely if the layer is already present in the image registry. + diff --git a/docs/features/k8s.md b/docs/features/k8s.md new file mode 100644 index 0000000000..928ee1cd62 --- /dev/null +++ b/docs/features/k8s.md @@ -0,0 +1,96 @@ +# Kubernetes Integration + +You _could_ stop at just building and pushing images. + +But, because building images is so _easy_ with `ko`, and because building with +`ko` only requires a string importpath to identify the image, we can integrate +this with YAML generation to make Kubernetes use cases much simpler. + +## YAML Changes + +Traditionally, you might have a Kubernetes deployment, defined in a YAML file, +that runs an image: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment +spec: + replicas: 3 + ... + template: + spec: + containers: + - name: my-app + image: registry.example.com/my-app:v1.2.3 +``` + +...which you apply to your cluster with `kubectl apply`: + +```plaintext +kubectl apply -f deployment.yaml +``` + +With `ko`, you can instead reference your Go binary by its importpath, prefixed +with `ko://`: + +```yaml + ... + spec: + containers: + - name: my-app + image: ko://github.com/my-user/my-repo/cmd/app +``` + +## `ko resolve` + +With this small change, running `ko resolve -f deployment.yaml` will instruct +`ko` to: + +1. scan the YAML file(s) for values with the `ko://` prefix, +2. for each unique `ko://`-prefixed string, execute `ko build ` to + build and push an image, +3. replace `ko://`-prefixed string(s) in the input YAML with the fully-specified + image reference of the built image(s), as above. +4. Print the resulting resolved YAML to stdout. + +The result can be redirected to a file, to distribute to others: + +```plaintext +ko resolve -f config/ > release.yaml +``` + +Taken together, `ko resolve` aims to make packaging, pushing, and referencing +container images an invisible implementation detail of your Kubernetes +deployment, and let you focus on writing code in Go. + +## `ko apply` + +To apply the resulting resolved YAML config, you can redirect the output of +`ko resolve` to `kubectl apply`: + +```plaintext +ko resolve -f config/ | kubectl apply -f - +``` + +Since this is a relatively common use case, the same functionality is available +using `ko apply`: + +```plaintext +ko apply -f config/ +``` + +**NB:** This requires that `kubectl` is available. + +## `ko delete` + +To teardown resources applied using `ko apply`, you can run `ko delete`: + +```plaintext +ko delete -f config/ +``` + +This is purely a convenient alias for `kubectl delete`, and doesn't perform any +builds, or delete any previously built images. + diff --git a/docs/features/multi-platform.md b/docs/features/multi-platform.md new file mode 100644 index 0000000000..f18c3beedd --- /dev/null +++ b/docs/features/multi-platform.md @@ -0,0 +1,12 @@ +# Multi-Platform Images + +Because Go supports cross-compilation to other CPU architectures and operating systems, `ko` excels at producing multi-platform images. + +To build and push an image for all platforms supported by the configured base image, simply add `--platform=all`. +This will instruct `ko` to look up all the supported platforms in the base image, execute `GOOS= GOARCH= GOARM= go build` for each platform, and produce a manifest list containing an image for each platform. + +You can also select specific platforms, for example, `--platform=linux/amd64,linux/arm64`. + +`ko` also has experimental support for building for Windows images. +See [FAQ](./../advanced/faq#can-i-build-windows-containers). + diff --git a/docs/features/sboms.md b/docs/features/sboms.md new file mode 100644 index 0000000000..2730e622e0 --- /dev/null +++ b/docs/features/sboms.md @@ -0,0 +1,11 @@ +# SBOMs + +A [Software Bill of Materials (SBOM)](https://en.wikipedia.org/wiki/Software_bill_of_materials) is a list of software components that a software artifact depends on. +Having a list of dependencies can be helpful in determining whether any vulnerable components were used to build the software artifact. + +**From v0.9+, `ko` generates and uploads an SBOM for every image it produces by default.** + +ko will generate an SBOM in the [SPDX](https://spdx.dev/) format by default, but you can select the [CycloneDX](https://cyclonedx.org/) format instead with the `--sbom=cyclonedx` flag. To disable SBOM generation, pass `--sbom=none`. + +These SBOMs can be downloaded using the [`cosign download sbom`](https://github.com/sigstore/cosign/blob/main/doc/cosign_download_sbom.md) command. + diff --git a/docs/features/static-assets.md b/docs/features/static-assets.md new file mode 100644 index 0000000000..6de9656137 --- /dev/null +++ b/docs/features/static-assets.md @@ -0,0 +1,41 @@ +# Static Assets + +`ko` can also bundle static assets into the images it produces. + +By convention, any contents of a directory named `/kodata/` will be +bundled into the image, and the path where it's available in the image will be +identified by the environment variable `KO_DATA_PATH`. + +As an example, you can bundle and serve static contents in your image: + +``` +cmd/ + app/ + main.go + kodata/ + favicon.ico + index.html +``` + +Then, in your `main.go`: + +```go +func main() { + http.Handle("/", http.FileServer(http.Dir(os.Getenv("KO_DATA_PATH")))) + log.Fatal(http.ListenAndServe(":8080", nil)) +} +``` + +You can simulate `ko`'s behavior outside of the container image by setting the +`KO_DATA_PATH` environment variable yourself with `KO_DATA_PATH=cmd/app/kodata/ go run ./cmd/app`. + +> 💡 **Tip:** Symlinks in `kodata` are followed and included as well. For example, +you can include Git commit information in your image with `ln -s -r .git/HEAD ./cmd/app/kodata/` + +Also note that `http.FileServer` will not serve the `Last-Modified` header +(or validate `If-Modified-Since` request headers) because `ko` does not embed +timestamps by default. + +This can be supported by manually setting the `KO_DATA_DATE_EPOCH` environment +variable during build ([See FAQ](./../advanced/faq#why-are-my-images-all-created-in-1970)). + diff --git a/docs/get-started.md b/docs/get-started.md new file mode 100644 index 0000000000..20d8585d64 --- /dev/null +++ b/docs/get-started.md @@ -0,0 +1,45 @@ +# Get Started + +## Setup + +First, [install `ko`](./install). + +### Authenticate + +`ko` depends on the authentication configured in your Docker config (typically `~/.docker/config.json`). + +✨ **If you can push an image with `docker push`, you are already authenticated for `ko`!** ✨ + +Since `ko` doesn't require `docker`, `ko login` also provides a surface for logging in to a container image registry with a username and password, similar to [`docker login`](https://docs.docker.com/engine/reference/commandline/login/). + +Additionally, even if auth is not configured in the Docker config, `ko` includes built-in support for authenticating to the following container registries using credentials configured in the environment: + +- Google Container Registry and Artifact Registry, using [Application Default Credentials](https://cloud.google.com/docs/authentication/production) or auth configured in `gcloud`. +- Amazon Elastic Container Registry, using [AWS credentials](https://github.com/awslabs/amazon-ecr-credential-helper/#aws-credentials) +- Azure Container Registry, using [environment variables](https://github.com/chrismellard/docker-credential-acr-env/) +- GitHub Container Registry, using the `GITHUB_TOKEN` environment variable + +### Choose Destination + +`ko` depends on an environment variable, `KO_DOCKER_REPO`, to identify where it should push images that it builds. Typically this will be a remote registry, e.g.: + +- `KO_DOCKER_REPO=gcr.io/my-project`, or +- `KO_DOCKER_REPO=ghcr.io/my-org/my-repo`, or +- `KO_DOCKER_REPO=my-dockerhub-user` + +## Build an Image + +`ko build ./cmd/app` builds and pushes a container image, and prints the resulting image digest to stdout. + +In this example, `./cmd/app` must be a `package main` that defines `func main()`. + +```plaintext +$ ko build ./cmd/app +... +registry.example.com/my-project/app-099ba5bcefdead87f92606265fb99ac0@sha256:6e398316742b7aa4a93161dce4a23bc5c545700b862b43347b941000b112ec3e +``` + +> 💡 **Note**: Prior to v0.10, the command was called `ko publish` -- this is equivalent to `ko build`, and both commands will work and do the same thing. + +The executable binary that was built from `./cmd/app` is available in the image at `/ko-app/app` -- the binary name matches the base import path name -- and that binary is the image's entrypoint. + diff --git a/docs/images/android-icon-192x192.png b/docs/images/android-icon-192x192.png new file mode 100644 index 0000000000..a4feccdf32 Binary files /dev/null and b/docs/images/android-icon-192x192.png differ diff --git a/docs/images/apple-icon-180x180.png b/docs/images/apple-icon-180x180.png new file mode 100644 index 0000000000..a4feccdf32 Binary files /dev/null and b/docs/images/apple-icon-180x180.png differ diff --git a/docs/images/apple-icon.png b/docs/images/apple-icon.png new file mode 100644 index 0000000000..a4feccdf32 Binary files /dev/null and b/docs/images/apple-icon.png differ diff --git a/docs/images/demo.png b/docs/images/demo.png new file mode 100644 index 0000000000..5d4f32c9c8 Binary files /dev/null and b/docs/images/demo.png differ diff --git a/docs/images/favicon-16x16.png b/docs/images/favicon-16x16.png new file mode 100644 index 0000000000..a4feccdf32 Binary files /dev/null and b/docs/images/favicon-16x16.png differ diff --git a/docs/images/favicon-32x32.png b/docs/images/favicon-32x32.png new file mode 100644 index 0000000000..a4feccdf32 Binary files /dev/null and b/docs/images/favicon-32x32.png differ diff --git a/docs/images/favicon-96x96.png b/docs/images/favicon-96x96.png new file mode 100644 index 0000000000..a4feccdf32 Binary files /dev/null and b/docs/images/favicon-96x96.png differ diff --git a/docs/images/ms-icon-144x144.png b/docs/images/ms-icon-144x144.png new file mode 100644 index 0000000000..a4feccdf32 Binary files /dev/null and b/docs/images/ms-icon-144x144.png differ diff --git a/docs/images/og.png b/docs/images/og.png new file mode 100644 index 0000000000..1ed77c166e Binary files /dev/null and b/docs/images/og.png differ diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000..9f84ecb03e --- /dev/null +++ b/docs/index.md @@ -0,0 +1,35 @@ +--- +ko_meta: true +--- + +# Introduction + +`ko` makes building Go container images easy, fast, and secure by default. + +![Demo of ko build](./images/demo.png) + +`ko` is a simple, fast container image builder for Go applications. + +It's ideal for use cases where your image contains a single Go application without many dependencies on the OS base image (e.g., no cgo, no OS package dependencies). + +`ko` builds images by executing `go build` on your local machine, and as such doesn't require `docker` to be installed. +This can make it a good fit for lightweight CI/CD use cases. + +`ko` also includes support for simple YAML templating which makes it a powerful tool for [Kubernetes applications](./features/k8s). + +--- + +> 🏃 [Install `ko`](./install) and [get started](./get-started)! + +--- + +`ko` is used and loved by these open source projects: + +- [Knative](https://knative.dev) +- [Tekton](https://tekton.dev) +- [Karpenter](https://karpenter.sh) +- [Sigstore](https://sigstore.dev) +- [Shipwright](https://shipwright.io) + +[_Add your project here!_](https://github.com/imjasonh/ko.build/edit/main/docs/index.md) + diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 0000000000..8a4e6e7d3f --- /dev/null +++ b/docs/install.md @@ -0,0 +1,45 @@ +# Installation + +### Install from [GitHub Releases](https://github.com/google/ko/releases) + +```plaintext +VERSION=TODO # choose the latest version +OS=Linux # or Darwin, Windows +ARCH=x86_64 # or arm64, i386, s390x +curl -L https://github.com/google/ko/releases/download/v${VERSION}/ko_${VERSION}_${OS}_${ARCH}.tar.gz | tar xzf - ko +chmod +x ./ko +``` + +### Install using [Homebrew](https://brew.sh) + +```plaintext +brew install ko +``` + +### Install on [Alpine Linux](https://www.alpinelinux.org) + +Installation on Alpine requires using the [`testing` repository](https://wiki.alpinelinux.org/wiki/Enable_Community_Repository#Using_testing_repositories) + +``` +echo https://dl-cdn.alpinelinux.org/alpine/edge/testing/ >> /etc/apk/repositories +apk update +apk add ko +``` + +### Build and Install from source + +With Go 1.16+, build and install the latest released version: + +```plaintext +go install github.com/google/ko@latest +``` + +### Setup on GitHub Actions + +You can use the [setup-ko](https://github.com/imjasonh/setup-ko) action to install ko and setup auth to [GitHub Container Registry](https://github.com/features/packages) in a GitHub Action workflow: + +```plaintext +steps: +- uses: imjasonh/setup-ko@v0.4 +``` + diff --git a/doc/ko.md b/docs/reference/ko.md similarity index 100% rename from doc/ko.md rename to docs/reference/ko.md diff --git a/doc/ko_apply.md b/docs/reference/ko_apply.md similarity index 100% rename from doc/ko_apply.md rename to docs/reference/ko_apply.md diff --git a/doc/ko_build.md b/docs/reference/ko_build.md similarity index 100% rename from doc/ko_build.md rename to docs/reference/ko_build.md diff --git a/doc/ko_create.md b/docs/reference/ko_create.md similarity index 100% rename from doc/ko_create.md rename to docs/reference/ko_create.md diff --git a/doc/ko_delete.md b/docs/reference/ko_delete.md similarity index 100% rename from doc/ko_delete.md rename to docs/reference/ko_delete.md diff --git a/docs/reference/ko_deps.md b/docs/reference/ko_deps.md new file mode 100644 index 0000000000..3eb5ae1827 --- /dev/null +++ b/docs/reference/ko_deps.md @@ -0,0 +1,39 @@ +## ko deps + +Print Go module dependency information about the ko-built binary in the image + +### Synopsis + +This sub-command finds and extracts the executable binary in the image, assuming it was built by ko, and prints information about the Go module dependencies of that executable, as reported by "go version -m". + +If the image was not built using ko, or if it was built without embedding dependency information, this command will fail. + +``` +ko deps IMAGE [flags] +``` + +### Examples + +``` + + # Fetch and extract Go dependency information from an image: + ko deps docker.io/my-user/my-image:v3 +``` + +### Options + +``` + -h, --help help for deps + --sbom string Format for SBOM output (supports: spdx, cyclonedx, go.version-m). (default "spdx") +``` + +### Options inherited from parent commands + +``` + -v, --verbose Enable debug logs +``` + +### SEE ALSO + +* [ko](ko.md) - Rapidly iterate with Go, Containers, and Kubernetes. + diff --git a/doc/ko_login.md b/docs/reference/ko_login.md similarity index 100% rename from doc/ko_login.md rename to docs/reference/ko_login.md diff --git a/doc/ko_resolve.md b/docs/reference/ko_resolve.md similarity index 100% rename from doc/ko_resolve.md rename to docs/reference/ko_resolve.md diff --git a/doc/ko_run.md b/docs/reference/ko_run.md similarity index 100% rename from doc/ko_run.md rename to docs/reference/ko_run.md diff --git a/doc/ko_version.md b/docs/reference/ko_version.md similarity index 100% rename from doc/ko_version.md rename to docs/reference/ko_version.md diff --git a/hack/presubmit.sh b/hack/presubmit.sh index 43102ba4b9..dfa1b6a307 100755 --- a/hack/presubmit.sh +++ b/hack/presubmit.sh @@ -29,4 +29,4 @@ find . -name "*.go" | grep -v vendor/ | xargs gofmt -d -e -l # Verify that generated Markdown docs are up-to-date. tmpdir=$(mktemp -d) go run cmd/help/main.go --dir "$tmpdir" -diff -Naur -I '###### Auto generated' "$tmpdir" doc/ +diff -Naur -I '###### Auto generated' "$tmpdir" docs/reference/ diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 16347299f1..401fce3012 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -26,4 +26,4 @@ trap popd EXIT go mod tidy go mod vendor -go run $PROJECT_ROOT/cmd/help/main.go --dir=$PROJECT_ROOT/doc/ +go run $PROJECT_ROOT/cmd/help/main.go --dir=$PROJECT_ROOT/docs/reference/ diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000000..85e7d6ed34 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,41 @@ +site_name: 'ko: Easy Go Containers' +site_url: https://ko.build +repo_url: https://github.com/google/ko + +theme: + name: material + logo: images/favicon-96x96.png + favicon: images/favicon-96x96.png + custom_dir: docs/custom/ + palette: + primary: light blue + +nav: + - index.md + - install.md + - get-started.md + - configuration.md + - deployment.md + - Features: + - features/multi-platform.md + - features/sboms.md + - features/k8s.md + - features/static-assets.md + - features/build-cache.md + - Advanced: + - advanced/go-packages.md + - advanced/limitations.md + - advanced/migrating-from-dockerfile.md + - advanced/faq.md + - CLI Reference: + - 'ko': reference/ko.md + - 'ko apply': reference/ko_apply.md + - 'ko build': reference/ko_build.md + - 'ko create': reference/ko_create.md + - 'ko delete': reference/ko_delete.md + - 'ko deps': reference/ko_deps.md + - 'ko login': reference/ko_login.md + - 'ko resolve': reference/ko_resolve.md + - 'ko run': reference/ko_run.md + - 'ko version': reference/ko_version.md + - Releases: "https://github.com/google/ko/releases"