2019-09-04 21:01:54 +05:30
---
2020-06-23 00:09:42 +05:30
stage: Verify
2021-09-04 01:27:46 +05:30
group: Pipeline Execution
2022-11-25 23:54:43 +05:30
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
2019-09-04 21:01:54 +05:30
type: howto
---
2021-09-30 23:02:18 +05:30
# Use kaniko to build Docker images **(FREE)**
2018-11-18 11:00:15 +05:30
2020-06-23 00:09:42 +05:30
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/45512) in GitLab 11.2. Requires GitLab Runner 11.2 and above.
2018-11-18 11:00:15 +05:30
[kaniko ](https://github.com/GoogleContainerTools/kaniko ) is a tool to build
container images from a Dockerfile, inside a container or Kubernetes cluster.
kaniko solves two problems with using the
2022-03-02 08:16:31 +05:30
[Docker-in-Docker build ](using_docker_build.md#use-docker-in-docker )
2021-11-18 22:05:49 +05:30
method:
2018-11-18 11:00:15 +05:30
2020-06-23 00:09:42 +05:30
- Docker-in-Docker requires [privileged mode ](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities )
2021-01-03 14:25:43 +05:30
to function, which is a significant security concern.
2020-06-23 00:09:42 +05:30
- Docker-in-Docker generally incurs a performance penalty and can be quite slow.
2018-11-18 11:00:15 +05:30
## Requirements
2021-01-03 14:25:43 +05:30
To use kaniko with GitLab, [a runner ](https://docs.gitlab.com/runner/ ) with one
of the following executors is required:
2019-09-04 21:01:54 +05:30
- [Kubernetes ](https://docs.gitlab.com/runner/executors/kubernetes.html ).
- [Docker ](https://docs.gitlab.com/runner/executors/docker.html ).
- [Docker Machine ](https://docs.gitlab.com/runner/executors/docker_machine.html ).
2018-11-18 11:00:15 +05:30
## Building a Docker image with kaniko
When building an image with kaniko and GitLab CI/CD, you should be aware of a
few important details:
- The kaniko debug image is recommended (`gcr.io/kaniko-project/executor:debug`)
because it has a shell, and a shell is required for an image to be used with
GitLab CI/CD.
2021-12-11 22:18:48 +05:30
- The entrypoint needs to be [overridden ](using_docker_images.md#override-the-entrypoint-of-an-image ),
2021-02-22 17:27:13 +05:30
otherwise the build script doesn't run.
2018-11-18 11:00:15 +05:30
2019-09-04 21:01:54 +05:30
In the following example, kaniko is used to:
1. Build a Docker image.
2019-12-04 20:38:33 +05:30
1. Then push it to [GitLab Container Registry ](../../user/packages/container_registry/index.md ).
2018-11-18 11:00:15 +05:30
2021-02-22 17:27:13 +05:30
The job runs only when a tag is pushed. A `config.json` file is created under
2018-12-13 13:39:08 +05:30
`/kaniko/.docker` with the needed GitLab Container Registry credentials taken from the
2021-09-30 23:02:18 +05:30
[predefined CI/CD variables ](../variables/index.md#predefined-cicd-variables )
2022-10-11 01:57:18 +05:30
GitLab CI/CD provides. These are automatically read by the Kaniko tool.
2019-09-04 21:01:54 +05:30
In the last step, kaniko uses the `Dockerfile` under the
2018-11-18 11:00:15 +05:30
root directory of the project, builds the Docker image and pushes it to the
project's Container Registry while tagging it with the Git tag:
```yaml
build:
stage: build
image:
2022-10-11 01:57:18 +05:30
name: gcr.io/kaniko-project/executor:v1.9.0-debug
2018-11-18 11:00:15 +05:30
entrypoint: [""]
script:
2022-10-11 01:57:18 +05:30
- /kaniko/executor
2021-12-11 22:18:48 +05:30
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
2021-02-22 17:27:13 +05:30
rules:
- if: $CI_COMMIT_TAG
2018-11-18 11:00:15 +05:30
```
2019-02-15 15:39:39 +05:30
2022-06-21 17:19:12 +05:30
If you authenticate against the [Dependency Proxy ](../../user/packages/dependency_proxy/index.md#authenticate-within-cicd ),
you must add the corresponding CI/CD variables for authentication to the `config.json` file:
```yaml
2023-03-17 16:20:25 +05:30
- echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"},\"$CI_DEPENDENCY_PROXY_SERVER\":{\"auth\":\"$(printf "%s:%s" ${CI_DEPENDENCY_PROXY_USER} "${CI_DEPENDENCY_PROXY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
2022-06-21 17:19:12 +05:30
```
2021-03-08 18:12:59 +05:30
### Building an image with kaniko behind a proxy
If you use a custom GitLab Runner behind an http(s) proxy, kaniko needs to be set
up accordingly. This means:
2021-03-11 19:13:27 +05:30
- Passing the `http_proxy` environment variables as build arguments so the Dockerfile
2021-03-08 18:12:59 +05:30
instructions can use the proxy when building the image.
The previous example can be extended as follows:
```yaml
build:
stage: build
2022-10-11 01:57:18 +05:30
variables:
http_proxy: < your-proxy >
https_proxy: < your-proxy >
no_proxy: < your-no-proxy >
2021-03-08 18:12:59 +05:30
image:
2022-10-11 01:57:18 +05:30
name: gcr.io/kaniko-project/executor:v1.9.0-debug
2021-03-08 18:12:59 +05:30
entrypoint: [""]
script:
2022-10-11 01:57:18 +05:30
- /kaniko/executor
2021-12-11 22:18:48 +05:30
--context "${CI_PROJECT_DIR}"
2022-10-11 01:57:18 +05:30
--build-arg http_proxy=$http_proxy
--build-arg https_proxy=$https_proxy
--build-arg no_proxy=$no_proxy
2021-12-11 22:18:48 +05:30
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
2021-09-04 01:27:46 +05:30
rules:
- if: $CI_COMMIT_TAG
2021-03-08 18:12:59 +05:30
```
2022-08-27 11:52:29 +05:30
## Build a multi-arch image
You can build [multi-arch images ](https://www.docker.com/blog/multi-arch-build-and-images-the-simple-way/ )
inside a container by using [`manifest-tool` ](https://github.com/estesp/manifest-tool ).
2023-06-20 00:43:36 +05:30
For a detailed guide on how to build a multi-arch image, read [Building a multi-arch container image in unprivileged containers ](https://blog.siemens.com/2022/07/building-a-multi-arch-container-image-in-unprivileged-containers/ ).
2022-08-27 11:52:29 +05:30
2019-02-15 15:39:39 +05:30
## Using a registry with a custom certificate
When trying to push to a Docker registry that uses a certificate that is signed
by a custom CA, you might get the following error:
2020-03-13 15:44:24 +05:30
```shell
2019-02-15 15:39:39 +05:30
$ /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --no-push
INFO[0000] Downloading base image registry.gitlab.example.com/group/docker-image
error building image: getting stage builder for stage 0: Get https://registry.gitlab.example.com/v2/: x509: certificate signed by unknown authority
```
This can be solved by adding your CA's certificate to the kaniko certificate
store:
```yaml
2020-11-24 15:15:51 +05:30
before_script:
- |
echo "-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----" >> /kaniko/ssl/certs/additional-ca-cert-bundle.crt
2019-02-15 15:39:39 +05:30
```
2019-09-04 21:01:54 +05:30
2020-05-24 23:13:21 +05:30
## Video walkthrough of a working example
The [Least Privilege Container Builds with Kaniko on GitLab ](https://www.youtube.com/watch?v=d96ybcELpFs )
video is a walkthrough of the [Kaniko Docker Build ](https://gitlab.com/guided-explorations/containers/kaniko-docker-build )
Guided Exploration project pipeline. It was tested on:
2021-09-30 23:02:18 +05:30
- [GitLab.com shared runners ](../runners/index.md )
2020-11-24 15:15:51 +05:30
- [The Kubernetes runner executor ](https://docs.gitlab.com/runner/executors/kubernetes.html )
2020-05-24 23:13:21 +05:30
The example can be copied to your own group or instance for testing. More details
on what other GitLab CI patterns are demonstrated are available at the project page.
2021-02-22 17:27:13 +05:30
## Troubleshooting
2019-09-04 21:01:54 +05:30
2021-02-22 17:27:13 +05:30
### 403 error: "error checking push permissions"
2019-09-04 21:01:54 +05:30
2021-02-22 17:27:13 +05:30
If you receive this error, it might be due to an outside proxy. Setting the `http_proxy`
and `https_proxy` [environment variables ](../../administration/packages/container_registry.md#running-the-docker-daemon-with-a-proxy )
can fix the problem.