💾 Archived View for hoseki.iensu.me › posts › docker-compose-to-kubernetes.gmi captured on 2023-09-08 at 15:37:19. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

Docker Compose to Kubernetes with Kompose

I really love using docker compose for local development. Whenever I start writing a service with any kind of external dependencies (databases, containerized APIs etc), I quickly setup a `docker-compose.yaml' for the project to allow me to try it out locally. I've heard murmurings that this is not what you should do anymore, instead you should use Kubernetes to do this. While I do like Kubernetes, I definitely prefer the simplicity of the docker-compose.yaml format. Writing a simple `docker-compose.yaml' file takes a few minutes, writing the correct Kubernetes manifests to achieve the same thing takes considerably longer.

Today I stumbled across [Kompose] which allows me to generate all the necessary Kubernetes manifests from a `docker-compose.yaml' file, so maybe I'll transition to using Kubernetes now. In the end I managed to author a `docker-compose.yaml' which works pretty much in both contexts and thought I'd write down the process and some learnings here. The main idea is to run Minikube locally and deploying services there.

Kompose

Workflow

My first learning was that you can use `kubectl apply` on a whole directory! Seems kind of obvious in retrospect, but I hadn't thought about it until now. This means I can apply the manifests in one go:

kompose convert -o ./kubernetes/; kubectl apply -f ./kubernetes/

Using local images

With Docker Compose you can deploy a local image based on a Dockerfile without the need to fiddle with setting up a local container registry:

services:
  my-api:
    build:
      context: .
      dockerfile: ./Dockerfile
    # ...

By running `docker compose up --build` you can ensure that you build a new image before starting up.

To use local images with Kubernetes you need to make the image available before applying your Kubernetes manifests, otherwise you will end up with an image pull error. You achieve this by building your image using the same Docker context as Minikube, read `minikube docker-env --help` for how to do this in your shell. Now when you build you need to give the image the name you gave the service in `docker-compose.yaml' so it matches what the generated Kubernetes manifests expect.

docker build -t my-api .

Now your Minikube should be able to find the image but you still need to stop Kubernetes from trying to pull the image, which means you need to set `pod.spec.containers.imagePullPolicy` to `Never` in the deployment manifest. You can achieve this by adding Kompose labels to the service declaration in `docker-compose.yaml':

services:
  my-api:
    build:
      context: .
      dockerfile: ./Dockerfile
    labels:
      kompose.image-pull-policy: "Never"
    # ...

Conclusion

I ended up not using this workflow for obvious reasons: it's just so much simpler to setup and run a `docker-compose.yaml' file for local development than faffing around with Kubernetes. It was an interesting exercise though.

イェンス - 2022-10-20

hoseki.iensu.me