Using Docker containers as Systemd services

If you've read any of my recent posts, you'll know I've recently swithed from MacOSX to Linux. One of the things this has done is made me realise just how much stuff I had installed with brew on MacOSX - for example; Redis, which I use a lot.

As much as I love the concept of having docker-compose files in all of my applications, and starting/stopping docker configurations for each of these applications - some times I just want to be able to dart around between different microservices and run my tests locally on my machine, without spinning up the whole stack. This is why I ended up running things like Redis and RabbitMQ on my host machine too. I'm taking those rapid feedback principals of continuous integration to the N'th degree!

Installing the world

One of my goals is to abstract my working and development from the operating system of my laptop as much as possible. IE I want to be able to switch between different distros, and get back up and running as quickly as possible.

I also don't want to bloat my laptop with needless packages, files jotted around here there and everywhere. Nor do I want to install all the dependencies required for each of these applications, and deal with any potential conflicts.

So how do I tackle this in production - Docker. How should I tackle them locally? Docker too?

SystemD

I still want to be able to start and stop things as if they're services on my laptop. I want to be able to track dependencies too, so I leverage Systemd service files to do this. These systemd files simply wrap docker commands, and name the image accordingly.

Below is an example of my redis service:

[Unit]
Description=Redis Key Value store
Requires=docker.service

[Service]
ExecStartPre=/bin/sleep 1
ExecStartPre=/bin/docker pull redis:latest
ExecStart=/bin/docker run --restart=always --name=systemd_redis -p=6379:6379 redis:latest
ExecStop=/bin/docker stop systemd_redis
ExecStopPost=/bin/docker rm -f systemd_redis
ExecReload=/bin/docker restart systemd_redis

[Install]
WantedBy=multi-user.target

I save this file as /etc/systemd/system/redis.service, and execute systemctl daemon-reload, type systemctl start redis and voilla, I have redis running.

The -p 6379:6379 binds the port to my host, so my code can access it on 127.0.0.1:6379.