<commit_before>---
title: Deploy into Kubernetes
sidebar: documentation
permalink: documentation/reference/deploy_process/deploy_into_kubernetes.html
author: <NAME> <<EMAIL>>
---

werf is a compatible alternative to [Helm 2](https://helm.sh), which uses improved deploy process.

werf has 2 main commands to work with Kubernetes: [deploy]({{ site.baseurl }}/documentation/cli/main/deploy.html) — to install or upgrade app in the cluster, and [dismiss]({{ site.baseurl }}/documentation/cli/main/dismiss.html)  — to uninstall app from cluster.

Deployed resources are tracked with different configurable modes, logs and Kubernetes events are shown for the resources, images built by werf are integrated into deploy configuration [templates](#templates) seamlessly. werf can set arbitrary annotations and labels to all Kubernetes resources of the project being deployed.

Configuration is described with Helm compatible [chart](#chart).

## Chart

The chart is a collection of configuration files which describe an application. Chart files reside in the `.helm` directory in the root directory of the project:

```
.helm/
  templates/
    <name>.yaml
    <name>.tpl
  charts/
  secret/
  values.yaml
  secret-values.yaml
```

### Templates

Templates are placed in the `.helm/templates` directory.

Directory contains YAML files `*.yaml`. Each YAML file describes one or several Kubernetes resources specs separated by three hyphens `---`, for example:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydeploy
  labels:
    service: mydeploy
spec:
  selector:
    matchLabels:
      service: mydeploy
  template:
    metadata:
      labels:
        service: mydeploy
    spec:
      containers:
      - name: main
        image: ubuntu:18.04
        command: [ "/bin/bash", "-c", "while true; do date ; sleep 1 ; done" ]
---
apiVersion: v1
kind: ConfigMap
  metadata:
    name: mycm
  data:
    node.conf: |
      port 6379
      loglevel notice
```

Each YAML file also preprocessed using [Go templates](https://golang.org/pkg/text/template/#hdr-Actions).

With go templates user can:
 * generate different Kubernetes specs for different cases;
 * parametrize templates with [values](#values) for different environments;
 * define common text parts as named Go templates and reuse them in several places;
 * etc.

[Sprig functions](https://masterminds.github.io/sprig/) and [advanced functions](https://docs.helm.sh/developing_charts/#chart-development-tips-and-tricks), like `include` and `required`, can be used in templates.

Also user can place `*.tpl` files, which will not be rendered into Kubernetes specs. These files can be used to store arbitrary custom Go templates and definitions. All templates and definitions from `*.tpl` files will be available for the use in the `*.yaml` files.

#### Integration with built images

To use docker images in the chart resources specs user must specify full docker images names including docker repo and docker tag. But how to specify images from `werf.yaml` given that full docker images names for these images depends on the selected tagging strategy and specified images repo?

The second question is how to use [`imagePullPolicy` Kubernetes parameter](https://kubernetes.io/docs/concepts/containers/images/#updating-images) together with images from `werf.yaml`: should user set `imagePullPolicy` to `Always`, how to pull images only when there is a need to pull?

To answer these questions werf has runtime functions, `werf_container_image` and `werf_container_env`.  User must use these template functions to specify images from `werf.yaml` in the chart templates safely and correctly.

##### werf_container_image

The template function generates `image` and `imagePullPolicy` keys for the pod container.

A specific feature of the function is that `imagePullPolicy` is generated based on the `.Values.global.werf.is_branch` value, if tags are used, `imagePullPolicy: Always` is not set. So in the result images are pulled always only for the images tagged by git-branch names (because docker image id can be changed for the same docker image name).

The function may return multiple strings, which is why it must be used together with the `indent` construction.

The logic of generating the `imagePullPolicy` key:
* The `.Values.global.werf.is_branch=true` value means that an image is being deployed based on the `latest` logic for a branch.
  * In this case, the image for an appropriate docker tag must be updated through docker pull, even if it already exists, to get the current `latest` version of the respective tag.
  * In this case – `imagePullPolicy=Always`.
* The `.Values.global.werf.is_branch=false` value means that a tag or a specific image commit is being deployed.
  * In this case, the image for an appropriate docker tag doesn't need to be updated through docker pull if it already exists.
  * In this case, `imagePullPolicy` is not specified, which is consistent with the default value currently adopted in Kubernetes: `imagePullPolicy=IfNotPresent`.

> The images tagged by custom tag strategy (`--tag-custom`) processed like the images tagged by git branch tag strategy (`--tag-git-branch`)

An example of using the function in case multiple images exist in the `werf.yaml` config:
* `tuple <image-name> . | werf_container_image | indent <N-spaces>`

An example of using the function in case a single unnamed image exists in the config:
* `tuple . | werf_container_image | indent <N-spaces>`
* `werf_container_image . | indent <N-spaces>` (additional simplified entry format)

##### werf_container_env

Enables streamlining the release process if the image remains unchanged. Generates a block with the `DOCKER_IMAGE_ID` environment variable for the pod container. Image id will be set to real value only if `.Values.global.werf.is_branch=true`, because in this case the image for an appropriate docker tag might have been updated through its name remained unchanged. The `DOCKER_IMAGE_ID` variable contains a new id docker for an image, which forces Kubernetes to update an asset. The template may return multiple strings, which is why it must be used together with `indent`.

> The images tagged by custom tag strategy (`--tag-custom`) processed like the images tagged by git branch tag strategy (`--tag-git-branch`)

An example of using the function in case multiple images exist in the `werf.yaml` config:
* `tuple <image-name> . | werf_container_env | indent <N-spaces>`

An example of using the function in case a single unnamed image exists in the config:
* `tuple . | werf_container_env | indent <N-spaces>`
* `werf_container_env . | indent <N-spaces>` (additional simplified entry format)

##### Examples

To specify image named `backend` from `werf.yaml`:

{% raw %}
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  labels:
    service: backend
spec:
  selector:
    matchLabels:
      service: backend
  template:
    metadata:
      labels:
        service: backend
    spec:
      containers:<commit_msg>[docs] Fix werf_container_image/werf_container_env description doc<commit_after>---
title: Deploy into Kubernetes
sidebar: documentation
permalink: documentation/reference/deploy_process/deploy_into_kubernetes.html
author: <NAME> <<EMAIL>>
---

werf is a compatible alternative to [Helm 2](https://helm.sh), which uses improved deploy process.

werf has 2 main commands to work with Kubernetes: [deploy]({{ site.baseurl }}/documentation/cli/main/deploy.html) — to install or upgrade app in the cluster, and [dismiss]({{ site.baseurl }}/documentation/cli/main/dismiss.html)  — to uninstall app from cluster.

Deployed resources are tracked with different configurable modes, logs and Kubernetes events are shown for the resources, images built by werf are integrated into deploy configuration [templates](#templates) seamlessly. werf can set arbitrary annotations and labels to all Kubernetes resources of the project being deployed.

Configuration is described with Helm compatible [chart](#chart).

## Chart

The chart is a collection of configuration files which describe an application. Chart files reside in the `.helm` directory in the root directory of the project:

```
.helm/
  templates/
    <name>.yaml
    <name>.tpl
  charts/
  secret/
  values.yaml
  secret-values.yaml
```

### Templates

Templates are placed in the `.helm/templates` directory.

Directory contains YAML files `*.yaml`. Each YAML file describes one or several Kubernetes resources specs separated by three hyphens `---`, for example:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydeploy
  labels:
    service: mydeploy
spec:
  selector:
    matchLabels:
      service: mydeploy
  template:
    metadata:
      labels:
        service: mydeploy
    spec:
      containers:
      - name: main
        image: ubuntu:18.04
        command: [ "/bin/bash", "-c", "while true; do date ; sleep 1 ; done" ]
---
apiVersion: v1
kind: ConfigMap
  metadata:
    name: mycm
  data:
    node.conf: |
      port 6379
      loglevel notice
```

Each YAML file also preprocessed using [Go templates](https://golang.org/pkg/text/template/#hdr-Actions).

With go templates user can:
 * generate different Kubernetes specs for different cases;
 * parametrize templates with [values](#values) for different environments;
 * define common text parts as named Go templates and reuse them in several places;
 * etc.

[Sprig functions](https://masterminds.github.io/sprig/) and [advanced functions](https://docs.helm.sh/developing_charts/#chart-development-tips-and-tricks), like `include` and `required`, can be used in templates.

Also user can place `*.tpl` files, which will not be rendered into Kubernetes specs. These files can be used to store arbitrary custom Go templates and definitions. All templates and definitions from `*.tpl` files will be available for the use in the `*.yaml` files.

#### Integration with built images

To use docker images in the chart resources specs user must specify full docker images names including docker repo and docker tag. But how to specify images from `werf.yaml` given that full docker images names for these images depends on the selected tagging strategy and specified images repo?

The second question is how to use [`imagePullPolicy` Kubernetes parameter](https://kubernetes.io/docs/concepts/containers/images/#updating-images) together with images from `werf.yaml`: should user set `imagePullPolicy` to `Always`, how to pull images only when there is a need to pull?

To answer these questions werf has runtime functions, `werf_container_image` and `werf_container_env`.  User must use these template functions to specify images from `werf.yaml` in the chart templates safely and correctly.

##### werf_container_image

The template function generates `image` and `imagePullPolicy` keys for the pod container.

A specific feature of the function is that `imagePullPolicy` is generated based on the `.Values.global.werf.is_branch` value, if tags are used, `imagePullPolicy: Always` is not set. So in the result images are pulled always only for the images tagged by git-branch names (because docker image id can be changed for the same docker image name).

The function may return multiple strings, which is why it must be used together with the `indent` construction.

The logic of generating the `imagePullPolicy` key:
* The `.Values.global.werf.is_branch=true` value means that an image is being deployed based on the `latest` logic for a branch.
  * In this case, the image for an appropriate docker tag must be updated through docker pull, even if it already exists, to get the current `latest` version of the respective tag.
  * In this case – `imagePullPolicy=Always`.
* The `.Values.global.werf.is_branch=false` value means that a tag or a specific image commit is being deployed.
  * In this case, the image for an appropriate docker tag doesn't need to be updated through docker pull if it already exists.
  * In this case, `imagePullPolicy` is not specified, which is consistent with the default value currently adopted in Kubernetes: `imagePullPolicy=IfNotPresent`.

> The images tagged by custom tag strategy (`--tag-custom`) processed like the images tagged by git branch tag strategy (`--tag-git-branch`)

An example of using the function in the case when a **named** image (or multiple images) used in the `werf.yaml` config:
* `tuple <image-name> . | werf_container_image | indent <N-spaces>`

An example of using the function in the case when a single **unnamed** image used in the `werf.yaml` config:
* `tuple . | werf_container_image | indent <N-spaces>`
* `werf_container_image . | indent <N-spaces>` (additional simplified entry format)

##### werf_container_env

Enables streamlining the release process if the image remains unchanged. Generates a block with the `DOCKER_IMAGE_ID` environment variable for the pod container. Image id will be set to real value only if `.Values.global.werf.is_branch=true`, because in this case the image for an appropriate docker tag might have been updated through its name remained unchanged. The `DOCKER_IMAGE_ID` variable contains a new id docker for an image, which forces Kubernetes to update an asset. The template may return multiple strings, which is why it must be used together with `indent`.

> The images tagged by custom tag strategy (`--tag-custom`) processed like the images tagged by git branch tag strategy (`--tag-git-branch`)

An example of using the function in the case when a **named** image (or multiple images) used in the `werf.yaml` config:
* `tuple <image-name> . | werf_container_env | indent <N-spaces>`

An example of using the function in the case when a single **unnamed** image used in the `werf.yaml` config:
* `tuple . | werf_container_env | indent <N-spaces>`
* `werf_container_env . | indent <N-spaces>` (additional simplified entry format)

##### Examples

To specify image named `backend` from `werf.yaml`:

{% raw %}
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  labels:
    service: backend
spec:
  selector:
    matchLabels:
      service: backend
  template:
    metadata:
      labels:
        service: backend
    spec:
      containers:
{'fraction_non_alphanumeric': 0.08021089630931459, 'fraction_numerical': 0.001968365553602812, 'mean_word_length': 4.308208955223881, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 33, 'https://': 10, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6718936', 'n_tokens_mistral': 3897, 'n_tokens_neox': 3649, 'n_words': 1799}