Reloading the Krakend configuration with Reflex and Docker

A recurrent question when we go around is if KrakenD configuration can be hot-reloaded, this is changing endpoints, backends, or any other configuration of the gateway while it’s running. The short answer is: No, you can’t. You must restart the server. And although we might have something to alleviate this, let us explain first why we don’t support such a feature:

  • Performance: This is the #1 reason, and strong enough. KrakenD is focused on performance, we never take choices lightly. All decision process from beginning to end, the pipes, are built at start up time and when it finishes starts serving the traffic. This means KrakenD will do this job only once and there is no need to calculate routes or what to do when serving. This makes a huge difference.
  • Simplicity: Because we believe an API contract must go under the version control system and after that be released (and through CI/CD if possible), but never altered at runtime by throwing curls or whatever. Are you familiar with POLA?
  • Consistency: Imagine yourself distributing configuration updates in an ecosystem like the one KrakenD is offering: independent, non-coordinated and state-less. It would require you to develop consistency strategies that are far out of the scope of an API Gateway. And not to mention that this would come with some restrictions making the hot-reload feature less attractive and the system very error-prone.
  • Why us?: You never demanded such a feature in Varnish, Apache, Nginx or any other major service. All of them are reloaded when configuration changes, and the Internet is still running.

We could keep going, but with just this in mind, it’s clear that KrakenD won’t support a feature were you can push the new configuration at runtime. But we heard you! So we have built a small solution to automate the KrakenD reloading task, at least in development.

Check the Github repository for the code used in this post.

Enters krakend:config-watcher mode

We have published a new Docker tag :config-watcher in the existing KrakenD Docker, you can get it with:

docker pull devopsfaith/krakend:config-watcher

This image starts the service from the reflex watcher.

What is reflex?

Reflex is a small tool that watches a directory and reruns a command when certain files change (e.g using a regexp). Since it’s written in golang it has no dependencies. Take the opportunity to look to this amazing tool!

By having reflex as the entrypoint when the configuration changes KrakenD is reloaded. This is very convenient while you are developing as it allows you to test new changes without having to restart manually and making the process less tedious.

Pull it or build it yourself

This is the Dockerfile that generates our config-watcher image today:

FROM devopsfaith/krakend:latest

LABEL maintainer="dortiz@devops.faith"

ENV KRAKEND_CONFIG krakend.json

ADD reflex /usr/bin/reflex
ADD entrypoint.sh /

WORKDIR /etc/krakend

ENTRYPOINT [ "/entrypoint.sh" ]

As you can see it uses the latest KrakenD version available (at the moment of writing 0.5.1), adds the reflex binary, defines the KRAKEND_CONFIG environment variable and adds the entrypoint script to launch everything.

Note: Reflex binary needs to be the alpine version, since KrakenD container uses it as base.

And the entrypoint script is as follows:

#!/bin/sh

KRAKEND_CFG=${KRAKEND_CONFIG:-krakend.json}

cd /etc/krakend
/usr/bin/reflex -g "$KRAKEND_CFG" -s  -- /usr/bin/krakend run -c /etc/krakend/${KRAKEND_CFG} -d

It executes reflex with the file pattern to look for (in the same directory) and launches the command as a service. If you don’t want to use Docker, you can just use the entrypoint.sh as start script.

Let’s develop! Running the Docker image

To run the container you need to mount a volume with your configuration file mapped to the /etc/krakend directory. Optionally you can pass the environment variable KRAKEND_CONFIG if the configuration file you are using is not named krakend.json.

Example:

docker run -it --rm -v $PWD:/etc/krakend -e KRAKEND_CONFIG=krakend.json devopsfaith/krakend:config-watcher

IMPORTANT: The volume needs to be shared as a directory, and not as a file because the changes wouldn’t be notified inside the container (it’s a Docker thing)

Now play with your configuration file as much as you want, KrakenD will be restarted every time!

config-test

Conclusion

We don’t support hot reloading in production, but we have shared this blog post to help you test your KrakenD configurations while you are developing. We also hope you discovered an amazing tools like Reflex or have given you ideas of the kind of stuff you can do with Docker.

Just try to keep it simple! Thanks for reading! If you like our product don’t forget to star our project!

Stay up to date with KrakenD releases and important updates