X
Popular Searches

How to Deploy Docker Compose Stacks to Kubernetes with Kompose

Illustration showing the Docker and Kubernetes logos

Docker Compose lets you define stacks of containers that you can manage collectively. It’s a relatively simple tool that originally focused on local Docker installations.

Kubernetes is a container orchestrator that comes with its own toolchain and manifest files. It’s usually seen as more complex than a regular Docker workflow, but its capabilities facilitate scalable container deployments in production.

Kompose is a tool that lets you take Docker Compose files and deploy them to Kubernetes clusters. It’s developed as part of the Kubernetes project.

Current Kompose versions are limited to YAML file conversions. You must apply the converted Kubernetes resource manifests to your cluster using a tool like Kubectl. Older Kompose versions had a built-in up command that could deploy straight to your cluster without an intermediary conversion step. This was removed due to growing technical complexity.

Getting Started

Kompose is available for Windows, macOS, and most popular Linux distributions. Pre-built binaries are available from its GitHub repository. Download the latest release, set the executable permission bit, and move the binary into a directory that’s in your path. Several package managers are supported, too.

curl -L https://github.com/kubernetes/kompose/releases/download/v1.23.0/kompose-linux-amd64 -o kompose
chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose
Advertisement

Try running kompose in your terminal. You’ll see some basic information about the available commands. Running kompose version checks the Kompose version that you’re using.

Now, make sure that you have a docker-compose.yml file available. Here’s a basic example that sets up an Apache web server with a MySQL database:

version: "3"

services:
  apache:
    image: httpd:latest
    ports:
      - 80:80
  mysql:
    image: mysql:latest
    expose:
      - 3306
    volumes:
      - mysql:/var/lib/mysql

volumes:
  mysql:

You also need a Kubernetes cluster to deploy to. Either create a new cluster with a public cloud provider or spin up your own using a project like MicroK8s.

Converting Your Stack

The kompose convert command accepts the path to a Docker Compose file and emits equivalent Kubernetes resource manifests. It uses the docker-compose.yml in your working directory when no path is given. Multiple files are accepted via the -f flag.

kompose convert -f docker-compose.yml -f docker-compose-dev.yml

You’ll see a few lines of output as Kompose writes manifest files for each of the resources in your Compose stack. Individual files are created for each component of your docker-compose.yml. They’ll be placed into your working directory.

Here’s the result of converting the docker-compose.yml shown above:

A Kubernetes deployment and service has been created for each of the Compose services. These resources define the Pods to create as well as their network routing rules.

Advertisement

A PersistentVolumeClaim also exists for the MySQL container. This represents the volume configured in the docker-compose.yml, providing persistent storage for the MySQL database that outlasts any individual Pod.

If you inspect the YAML files, you’ll see that they’re just regular Kubectl-compatible Kubernetes manifests. Here’s the converted apache-deployment.yaml file:

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kompose.cmd: kompose convert
    kompose.version: 1.23.0 (bc7d9f4f)
  creationTimestamp: null
  labels:
    io.kompose.service: apache
  name: apache
spec:
  replicas: 1
  selector:
    matchLabels:
      io.kompose.service: apache
  strategy: {}
  template:
    metadata:
      annotations:
        kompose.cmd: kompose convert
        kompose.version: 1.23.0 (bc7d9f4f)
      creationTimestamp: null
      labels:
        io.kompose.service: apache
    spec:
      containers:
        - image: httpd:latest
          name: apache
          ports:
            - containerPort: 80
          resources: {}
      restartPolicy: Always
status: {}

The deployment’s spec is quite similar to the Apache container’s definition in the original docker-compose.yml. In the case of this simple service, it’s easily mapped to a Kubernetes object. The remainder of the file is mostly setting metadata, including Kompose-specific annotations that let you identify resources created with the tool.

Deploying to Your Cluster

Deploy the set of manifest files in the usual way with kubectl apply. It’s a good idea to store them in a separate directory to your docker-compose.yml, so that kubectl doesn’t try to pick that incompatible file, too.

kubectl apply .

The resources will be provisioned inside your cluster. It could take a few minutes for your services to get running. Inspect your deployment with kubectl get deployments. When the AVAILABLE column shows 1, your workload should be accessible.

Now, you can update your deployment by editing the generated manifests and re-running kubectl apply. If you wanted to scale Apache to three replicas, you’d open apache-deployment.yaml, change the replicas field to 3, and apply the modified manifest.

Advertisement

You can keep updating your Docker Compose file, too. Run kompose convert again to get the latest Kubernetes interpretation of its content, and then reapply the output to your cluster. Be aware that this will overwrite any changes that you’ve manually applied since.

Limitations

Kompose usually works well with Docker Compose files using the most common features and best practices. It can create containers, expose ports, and provide persistent storage via volumes.

Not every conversion will be perfect, though. Some Compose capabilities have no direct equivalent in the Kubernetes world, while others will map in a way that might not fulfill your needs. The use of deployments and services in this example is one such case—if you were deploying directly to Kubernetes, you might use an Ingress rule to expose your service, but this isn’t created by Kompose. Opinionated decisions are resolved by taking the simplest option.

You’ll also run into issues around volumes. Docker Compose files can bind mount files and folders from the host into containers. This isn’t possible with Kubernetes, so you’ll need an alternative solution. In addition, although Kompose can create resources for PersistentVolumeClaims, it won’t create the actual PersistentVolumes. You’ll need to have a volume already available within your cluster before you try to deploy your manifests.

A complete table of supported features and conversion details is offered as part of the Kompose documentation. It’s worth checking that the Docker Compose features you use are supported before you begin any conversion effort.

Conclusion

Kompose simplifies migrating away from Docker Compose to a Kubernetes cluster. It automates steps that were previously tedious, time-consuming, and error-prone. It’s a good assistive aid, although not a tool that should be run without a degree of oversight.

Advertisement

Kompose conversions aren’t universally applicable, so they won’t be suitable for all environments. It’s always worth checking the emitted manifests before you apply them to your cluster. In some cases, it’s best to use Kompose as a reference—convert your docker-compose.yml, see what the result is, and then use that as a starting point to construct manifests that are fully compatible with your application and cluster.

James Walker James Walker
James Walker is a CloudSavvy IT contributor. He is the founder of Heron Web, a UK-based digital agency providing bespoke software development services to SMEs. He has experience managing complete end-to-end web development workflows with DevOps, CI/CD, Docker, and Kubernetes. Read Full Bio »

The above article may contain affiliate links, which help support CloudSavvy IT.