'\" t .\" Automatically generated by Pandoc 3.1.11.1 .\" .TH "Katenary" "1" "2025-08-21" "mkdocs-manpage v2.0.1" "Katenary helm chart generator" .SH Basic Usage Basically, you can use \f[CR]katenary\f[R] to transpose a docker\-compose file (or any compose file compatible with \f[CR]podman\-compose\f[R] and \f[CR]docker\-compose\f[R]) to a configurable Helm Chart. This resulting helm chart can be installed with \f[CR]helm\f[R] command to your Kubernetes cluster. .PP For very basic compose files, without any specific configuration, Katenary will create a working helm chart using the simple command line: .IP .EX katenary convert .EE .PP This will create a \f[CR]chart\f[R] directory with the helm chart inside. .PP But, in general, you will need to add a few configurations to help Katenary to transpose the compose file to a working helm chart. .PP There are two ways to configure Katenary: .IP \[bu] 2 Using the compose files, adding labels to the services .IP \[bu] 2 Using a specific file named \f[CR]katenary.yaml\f[R] .PP The Katenary file \f[CR]katenary.yaml\f[R] has benefits over the labels in the compose file: .IP \[bu] 2 you can validate the configuration with a schema, and use completion in your editor .IP \[bu] 2 you separate the configuration and leave the compose file \[dq]intact\[dq] .IP \[bu] 2 the syntax is a bit simpler, instead of using \f[CR]katenary.v3/xxx: |\-\f[R] you can use \f[CR]xxx: ...\f[R] .PP But: \f[B]this implies that you have to maintain two files if the compose file changes.\f[R] .PP For example. With \[dq]labels\[dq], you should do: .IP .EX # in compose file services: webapp: image: php:7\-apache ports: \- 8080:80 environment: DB_HOST: database labels: katenary.v3/ingress: |\- hostname: myapp.example.com port: 8080 katenary.v3/map\-env: |\- DB_HOST: \[dq]{{ .Release.Name }}\-database\[dq] .EE .PP Using a Katenary file, you can do: .IP .EX # in compose file, no need to add labels services: webapp: image: php:7\-apache ports: \- 8080:80 environment: DB_HOST: database # in katenary.yaml webapp: ingress: hostname: myapp.example.com port: 8080 map\-env: DB_HOST: \[dq]{{ .Release.Name }}\-database\[dq] .EE .PP YAML in multiline label .PP Compose only accept text label. So, to put a complete YAML content in the target label, you need to use a pipe char (\f[CR]|\f[R] or \f[CR]|\-\f[R]) and to \f[B]indent\f[R] your content. .PP For example : .IP .EX labels: # your labels foo: bar # katenary labels with multiline katenary.v3/ingress: |\- hostname: my.website.tld port: 80 katenary.v3/ports: |\- \- 1234 .EE .PP Katenary transforms compose services this way: .IP \[bu] 2 Takes the service and create a \[dq]Deployment\[dq] file .IP \[bu] 2 if a port is declared, Katenary creates a service (\f[CR]ClusterIP\f[R]) .IP \[bu] 2 if a port is exposed, Katenary creates a service (\f[CR]NodePort\f[R]) .IP \[bu] 2 environment variables will be stored inside a \f[CR]ConfigMap\f[R] .IP \[bu] 2 image, tags, and ingresses configuration are also stored in \f[CR]values.yaml\f[R] file .IP \[bu] 2 if named volumes are declared, Katenary create \f[CR]PersistentVolumeClaims\f[R] \- not enabled in values file .IP \[bu] 2 \f[CR]depends_on\f[R] needs that the pointed service declared a port. If not, you can use labels to inform Katenary .PP For any other specific configuration, like binding local files as \f[CR]ConfigMap\f[R], bind variables, add values with documentation, etc. You\[aq]ll need to use labels. .PP Katenary can also configure containers grouping in pods, declare dependencies, ignore some services, force variables as secrets, mount files as \f[CR]configMap\f[R], and many others things. To adapt the helm chart generation, you will need to use some specific labels. .PP For more complete label usage, see the labels page. .PP Overriding file .PP It could be sometimes more convinient to separate the configuration related to Katenary inside a secondary file. .PP Instead of adding labels inside the \f[CR]compose.yaml\f[R] file, you can create a file named \f[CR]compose.katenary.yaml\f[R] and declare your labels inside. Katenary will detect it by default. .PP \f[B]No need to precise the file in the command line.\f[R] .SS Make conversion After having installed \f[CR]katenary\f[R], the standard usage is to call: .IP .EX katenary convert .EE .PP It will search standard compose files in the current directory and try to create a helm chart in \[dq]chart\[dq] directory. .PP Info .PP Katenary uses the compose\-go library which respects the Docker and Docker\-Compose specification. Keep in mind that it will find files exactly the same way as \f[CR]docker\-compose\f[R] and \f[CR]podman\-compose\f[R] do it. .PP Of course, you can provide others files than the default with (cumulative) \f[CR]\-c\f[R] options: .IP .EX katenary convert \-c file1.yaml \-c file2.yaml .EE .SS Some common labels to use Katenary proposes a lot of labels to configure the helm chart generation, but some are very important. .PP Info .PP For more complete label usage, see the labels page. .SS Work with Depends On? Kubernetes does not provide service or pod starting detection from others pods. But Katenary will create \f[CR]initContainer\f[R] to make you able to wait for a service to respond. But you\[aq]ll probably need to adapt a bit the compose file. .PP See this compose file: .IP .EX version: \[dq]3\[dq] services: webapp: image: php:8\-apache depends_on: \- database database: image: mariadb environment: MYSQL_ROOT_PASSWORD: foobar .EE .PP In this case, \f[CR]webapp\f[R] needs to know the \f[CR]database\f[R] port because the \f[CR]depends_on\f[R] points on it and Kubernetes has not (yet) solution to check the database startup. Katenary wants to create a \f[CR]initContainer\f[R] to hit on the related service. So, instead of exposing the port in the compose definition, let\[aq]s declare this to Katenary with labels: .IP .EX version: \[dq]3\[dq] services: webapp: image: php:8\-apache depends_on: \- database database: image: mariadb environment: MYSQL_ROOT_PASSWORD: foobar labels: katenary.v3/ports: |\- \- 3306 .EE .SS Declare ingresses It\[aq]s very common to have an Ingress resource on web application to deploy on Kubernetes. It allows exposing the service to the outside of the cluster (you need to install an ingress controller). .PP Katenary can create this resource for you. You just need to declare the hostname and the port to bind. .IP .EX services: webapp: image: ... ports: 8080:5050 labels: katenary.v3/ingress: |\- # the target port is 5050 wich is the \[dq]service\[dq] port port: 5050 hostname: myapp.example.com .EE .PP Note that the port to bind is the one used by the container, not the used locally. This is because Katenary create a service to bind the container itself. .SS Map environment to helm values A lot of framework needs to receive service host or IP in an environment variable to configure the connection. For example, to connect a PHP application to a database. .PP With a compose file, there is no problem as Docker/Podman allows resolving the name by container name: .IP .EX services: webapp: image: php:7\-apache environment: DB_HOST: database database: image: mariadb .EE .PP Katenary prefixes the services with \f[CR]{{ .Release.Name }}\f[R] (to make it possible to install the application several times in a namespace), so you need to \[dq]remap\[dq] the environment variable to the right one. .IP .EX services: webapp: image: php:7\-apache environment: DB_HOST: database labels: katenary.v3/mapenv: |\- DB_HOST: \[dq]{{ .Release.Name }}\-database\[dq] database: image: mariadb .EE .PP This label can be used to map others environment for any others reason. E.g. to change an informational environment variable. .IP .EX services: webapp: #... environment: RUNNING: docker labels: katenary.v3/mapenv: |\- RUNNING: kubernetes .EE .PP In the above example, \f[CR]RUNNING\f[R] will be set to \f[CR]kubernetes\f[R] when you\[aq]ll deploy the application with helm, and it\[aq]s \f[CR]docker\f[R] for \[dq]Podman\[dq] and \[dq]Docker\[dq] executions. .SH Labels documentation Katenary proposes labels to set in \f[CR]compose.yaml\f[R] files (or override files) to configure the Helm Chart generation. Because it is sometimes needed to have structured values, it is necessary to use the YAML syntax. While compose labels are string, we can use \f[I]here\-doc\f[R] syntax using \f[CR]|\f[R] to use YAML multiline as value. .IP .EX label\-name: |\- # this is actually a multiline string here key1: value1 key2: value2 .EE .PP Katenary will try to \f[I]Unmarshal\f[R] these labels. .SS Label list and types .PP .TS tab(@); l l l. T{ Label name T}@T{ Description T}@T{ Type T} _ T{ \f[CR]katenary.v3/configmap\-files\f[R] T}@T{ Inject files as Configmap. T}@T{ \f[CR][]string\f[R] T} T{ \f[CR]katenary.v3/cronjob\f[R] T}@T{ Create a cronjob from the service. T}@T{ \f[CR]object\f[R] T} T{ \f[CR]katenary.v3/dependencies\f[R] T}@T{ Add Helm dependencies to the service. T}@T{ \f[CR][]object\f[R] T} T{ \f[CR]katenary.v3/description\f[R] T}@T{ Description of the service T}@T{ \f[CR]string\f[R] T} T{ \f[CR]katenary.v3/env\-from\f[R] T}@T{ Add environment variables from another service. T}@T{ \f[CR][]string\f[R] T} T{ \f[CR]katenary.v3/exchange\-volumes\f[R] T}@T{ Add exchange volumes (empty directory on the node) to share data T}@T{ \f[CR][]object\f[R] T} T{ \f[CR]katenary.v3/health\-check\f[R] T}@T{ Health check to be added to the deployment. T}@T{ \f[CR]object\f[R] T} T{ \f[CR]katenary.v3/ignore\f[R] T}@T{ Ignore the service T}@T{ \f[CR]bool\f[R] T} T{ \f[CR]katenary.v3/ingress\f[R] T}@T{ Ingress rules to be added to the service. T}@T{ \f[CR]object\f[R] T} T{ \f[CR]katenary.v3/main\-app\f[R] T}@T{ Mark the service as the main app. T}@T{ \f[CR]bool\f[R] T} T{ \f[CR]katenary.v3/map\-env\f[R] T}@T{ Map env vars from the service to the deployment. T}@T{ \f[CR]map[string]string\f[R] T} T{ \f[CR]katenary.v3/ports\f[R] T}@T{ Ports to be added to the service. T}@T{ \f[CR][]uint32\f[R] T} T{ \f[CR]katenary.v3/same\-pod\f[R] T}@T{ Move the same\-pod deployment to the target deployment. T}@T{ \f[CR]string\f[R] T} T{ \f[CR]katenary.v3/secrets\f[R] T}@T{ Env vars to be set as secrets. T}@T{ \f[CR][]string\f[R] T} T{ \f[CR]katenary.v3/values\f[R] T}@T{ Environment variables to be added to the values.yaml T}@T{ \f[CR][]string or map[string]string\f[R] T} T{ \f[CR]katenary.v3/values\-from\f[R] T}@T{ Add values from another service. T}@T{ \f[CR]map[string]string\f[R] T} .TE .SS Detailed description .SS katenary.v3/configmap\-files Inject files as Configmap. .PP \f[B]Type\f[R]: \f[CR][]string\f[R] .PP It makes a file or directory to be converted to one or more ConfigMaps and mounted in the pod. The file or directory is relative to the service directory. .PP If it is a directory, all files inside it are added to the ConfigMap. .PP If the directory as subdirectories, so one configmap per subpath are created. .PP Warning .PP It is not intended to be used to store an entire project in configmaps. It is intended to be used to store configuration files that are not managed by the application, like nginx configuration files. Keep in mind that your project sources should be stored in an application image or in a storage. .PP \f[B]Example:\f[R] .IP .EX volumes \- ./conf.d:/etc/nginx/conf.d labels: katenary.v3/configmap\-files: |\- \- ./conf.d .EE .SS katenary.v3/cronjob Create a cronjob from the service. .PP \f[B]Type\f[R]: \f[CR]object\f[R] .PP This adds a cronjob to the chart. .PP The label value is a YAML object with the following attributes: \- command: the command to be executed \- schedule: the cron schedule (cron format or \[at]every where \[dq]every\[dq] is a duration like 1h30m, daily, hourly...) \- rbac: false (optionnal), if true, it will create a role, a rolebinding and a serviceaccount to make your cronjob able to connect the Kubernetes API .PP \f[B]Example:\f[R] .IP .EX labels: katenary.v3/cronjob: |\- command: echo \[dq]hello world\[dq] schedule: \[dq]* */1 * * *\[dq] # or \[at]hourly for example .EE .SS katenary.v3/dependencies Add Helm dependencies to the service. .PP \f[B]Type\f[R]: \f[CR][]object\f[R] .PP Set the service to be, actually, a Helm dependency. This means that the service will not be exported as template. The dependencies are added to the Chart.yaml file and the values are added to the values.yaml file. .PP It\[aq]s a list of objects with the following attributes: .IP \[bu] 2 name: the name of the dependency .IP \[bu] 2 repository: the repository of the dependency .IP \[bu] 2 alias: the name of the dependency in values.yaml (optional) .IP \[bu] 2 values: the values to be set in values.yaml (optional) .PP Info .PP Katenary doesn\[aq]t update the helm depenedencies by default. .PP Use \f[CR]\-\-helm\-update\f[R] (or \f[CR]\-u\f[R]) flag to update the dependencies. .PP example: \f[CR]katenary convert \-u\f[R] .PP By setting an alias, it is possible to change the name of the dependency in values.yaml. .PP \f[B]Example:\f[R] .IP .EX labels: katenary.v3/dependencies: |\- \- name: mariadb repository: oci://registry\-1.docker.io/bitnamicharts ## optional, it changes the name of the section in values.yaml # alias: mydatabase ## optional, it adds the values to values.yaml values: auth: database: mydatabasename username: myuser password: the secret password .EE .SS katenary.v3/description Description of the service .PP \f[B]Type\f[R]: \f[CR]string\f[R] .PP This replaces the default comment in values.yaml file to the given description. It is useful to document the service and configuration. .PP The value can be set with a documentation in multiline format. .PP \f[B]Example:\f[R] .IP .EX labels: katenary.v3/description: |\- This is a description of the service. It can be multiline. .EE .SS katenary.v3/env\-from Add environment variables from another service. .PP \f[B]Type\f[R]: \f[CR][]string\f[R] .PP It adds environment variables from another service to the current service. .PP \f[B]Example:\f[R] .IP .EX service1: image: nginx:1.19 environment: FOO: bar service2: image: php:7.4\-fpm labels: # get the congigMap from service1 where FOO is # defined inside this service too katenary.v3/env\-from: |\- \- myservice1 .EE .SS katenary.v3/exchange\-volumes Add exchange volumes (empty directory on the node) to share data .PP \f[B]Type\f[R]: \f[CR][]object\f[R] .PP This label allows sharing data between containres. The volume is created in the node and mounted in the pod. It is useful to share data between containers in a \[dq]same pod\[dq] logic. For example to let PHP\-FPM and Nginx share the same direcotory. .PP This will create: .IP \[bu] 2 an \f[CR]emptyDir\f[R] volume in the deployment .IP \[bu] 2 a \f[CR]voumeMount\f[R] in the pod for \f[B]each container\f[R] .IP \[bu] 2 a \f[CR]initContainer\f[R] for each definition .PP Fields: \- name: the name of the volume (manadatory) \- mountPath: the path where the volume is mounted in the pod (optional, default is \f[CR]/opt\f[R]) \- init: a command to run to initialize the volume with data (optional) .PP Warning .PP This is highly experimental. This is mainly useful when using the \[dq]same\-pod\[dq] label. .PP \f[B]Example:\f[R] .IP .EX nginx: # ... labels; katenary.v3/exchange\-volumes: |\- \- name: php\-fpm mountPath: /var/www/html php: # ... labels: katenary.v3/exchange\-volumes: |\- \- name: php\-fpm mountPath: /opt init: cp \-ra /var/www/html/* /opt .EE .SS katenary.v3/health\-check Health check to be added to the deployment. .PP \f[B]Type\f[R]: \f[CR]object\f[R] .PP Health check to be added to the deployment. .PP \f[B]Example:\f[R] .IP .EX labels: katenary.v3/health\-check: |\- livenessProbe: httpGet: path: /health port: 8080 .EE .SS katenary.v3/ignore Ignore the service .PP \f[B]Type\f[R]: \f[CR]bool\f[R] .PP Ingoring a service to not be exported in helm chart. .PP \f[B]Example:\f[R] .IP .EX labels: katenary.v3/ignore: \[dq]true\[dq] .EE .SS katenary.v3/ingress Ingress rules to be added to the service. .PP \f[B]Type\f[R]: \f[CR]object\f[R] .PP Declare an ingress rule for the service. The port should be exposed or declared with \f[CR]katenary.v3/ports\f[R]. .PP \f[B]Example:\f[R] .IP .EX labels: katenary.v3/ingress: |\- port: 80 hostname: mywebsite.com (optional) .EE .SS katenary.v3/main\-app Mark the service as the main app. .PP \f[B]Type\f[R]: \f[CR]bool\f[R] .PP This makes the service to be the main application. Its image tag is considered to be the Chart appVersion and to be the defaultvalue in Pod container image attribute. .PP Warning .PP This label cannot be repeated in others services. If this label is set in more than one service as true, Katenary will return an error. .PP \f[B]Example:\f[R] .IP .EX ghost: image: ghost:1.25.5 labels: # The chart is now named ghost, and the appVersion is 1.25.5. # In Deployment, the image attribute is set to ghost:1.25.5 if # you don\[aq]t change the \[dq]tag\[dq] attribute in values.yaml katenary.v3/main\-app: true .EE .SS katenary.v3/map\-env Map env vars from the service to the deployment. .PP \f[B]Type\f[R]: \f[CR]map[string]string\f[R] .PP Because you may need to change the variable for Kubernetes, this label forces the value to another. It is also particullary helpful to use a template value instead. For example, you could bind the value to a service name with Helm attributes: \f[CR]{{ tpl .Release.Name . }}\f[R]. .PP If you use \f[CR]__APP__\f[R] in the value, it will be replaced by the Chart name. .PP \f[B]Example:\f[R] .IP .EX env: DB_HOST: database RUNNING: docker OTHER: value labels: katenary.v3/map\-env: |\- RUNNING: kubernetes DB_HOST: \[aq]{{ include \[dq]__APP__.fullname\[dq] . }}\-database\[aq] .EE .SS katenary.v3/ports Ports to be added to the service. .PP \f[B]Type\f[R]: \f[CR][]uint32\f[R] .PP Only useful for services without exposed port. It is mandatory if the service is a dependency of another service. .PP \f[B]Example:\f[R] .IP .EX labels: katenary.v3/ports: |\- \- 8080 \- 8081 .EE .SS katenary.v3/same\-pod Move the same\-pod deployment to the target deployment. .PP \f[B]Type\f[R]: \f[CR]string\f[R] .PP This will make the service to be included in another service pod. Some services must work together in the same pod, like a sidecar or a proxy or nginx + php\-fpm. .PP Note that volume and VolumeMount are copied from the source to the target deployment. .PP \f[B]Example:\f[R] .IP .EX web: image: nginx:1.19 php: image: php:7.4\-fpm labels: katenary.v3/same\-pod: web .EE .SS katenary.v3/secrets Env vars to be set as secrets. .PP \f[B]Type\f[R]: \f[CR][]string\f[R] .PP This label allows setting the environment variables as secrets. The variable is removed from the environment and added to a secret object. .PP The variable can be set to the \f[CR]katenary.v3/values\f[R] too, so the secret value can be configured in values.yaml .PP \f[B]Example:\f[R] .IP .EX env: PASSWORD: a very secret password NOT_A_SECRET: a public value labels: katenary.v3/secrets: |\- \- PASSWORD .EE .SS katenary.v3/values Environment variables to be added to the values.yaml .PP \f[B]Type\f[R]: \f[CR][]string or map[string]string\f[R] .PP By default, all environment variables in the \[dq]env\[dq] and environment files are added to configmaps with the static values set. This label allows adding environment variables to the values.yaml file. .PP Note that the value inside the configmap is \f[CR]{{ tpl vaname . }}\f[R], so you can set the value to a template that will be rendered with the values.yaml file. .PP The value can be set with a documentation. This may help to understand the purpose of the variable. .PP \f[B]Example:\f[R] .IP .EX env: FOO: bar DB_NAME: mydb TO_CONFIGURE: something that can be changed in values.yaml A_COMPLEX_VALUE: example labels: katenary.v3/values: |\- # simple values, set as is in values.yaml \- TO_CONFIGURE # complex values, set as a template in values.yaml with a documentation \- A_COMPLEX_VALUE: |\- This is the documentation for the variable to configure in values.yaml. It can be, of course, a multiline text. .EE .SS katenary.v3/values\-from Add values from another service. .PP \f[B]Type\f[R]: \f[CR]map[string]string\f[R] .PP This label allows adding values from another service to the current service. It avoid duplicating values, environment or secrets that should be the same. .PP The key is the value to be added, and the value is the \[dq]key\[dq] to fetch in the form \f[CR]service_name.environment_name\f[R]. .PP \f[B]Example:\f[R] .IP .EX database: image: mariadb:10.5 environment: MARIADB_USER: myuser MARIADB_PASSWORD: mypassword labels: # we can declare secrets katenary.v3/secrets: |\- \- MARIADB_PASSWORD php: image: php:7.4\-fpm environment: # it\[aq]s duplicated in docker / podman DB_USER: myuser DB_PASSWORD: mypassword labels: # removes the duplicated, use the configMap and secrets from \[dq]database\[dq] katenary.v3/values\-from: |\- DB_USER: database.MARIADB_USER DB_PASSWORD: database.MARIADB_PASSWORD .EE