Kanboard with Docker and Watchtower on Ubuntu 18.10
January 21, 2019I've never liked Docker. In fact, I've always kind of hated it. The reason is simple - I'm an operational engineer. I do operations, not development. And when Docker first came out, everyone jumped on the technology and praised it for making development so much easier. And I agree - containers can make development easier. However, at the time people were setting up Docker containers for everything. And standard prosedure was to set up a container, and forget it. That is a really bad practice, operations-wise. In operations we like things that are automatically maintained, and most tutorials I came across only told you how to get the Docker image up and running. It said nothing about how it should be maintained, and how you could automate that task.
This is still kinda true today. But, as I've come to learn with time, best practices have developed, and there exists multiple systems that can maintain your Docker containers for you. I recently received a tip to check out Watchtower, and it seems like a simple and nice tool that can pull the latest version of your images, and run them automatically.. I have come across Watchtower before, but as I've mostly been igroring everything Docker, I've silently ignored this as well.
Below I will explain how to set up Docker and Watchtower, and lastly, how to set up Kanboard with Watchtower so that it is automatically maintained. Why Kanboard? Just because I want to try it out, and it's a good example of a simple application that can be deployed with Docker.
Installing Docker
Some of this has been stolen from Digital Oceans article on How To Install and Use Docker on Ubuntu 18.04, which I recommend you read. Also, some is from Dockers own official documentation.
In the article, they want you to add Dockers own repositories. However, I like to use Ubuntus own repositories (just for the maintainability), so I will use that.
First off, update your syste.
$ sudo apt update
$ sudo apt dist-upgrade
Then we can install the Docker-package.
$ sudo apt install docker.io
And that's it. Let's check the version.
$ docker --version
Docker version 18.06.1-ce, build e68fc7a
Sweet.
Also, we should add our own user to the docker
-group, so we can use Docker
without sudo
. Also, we need to log into the new group.
$ sudo adduser username docker
$ newgrp docker
You should now be able to control Docker with your own user.
Testing Docker
You can test Docker by simply running the following
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
This tries to start the image hello-world
. Docker can't find the image locally
(because we haven't downloaded any images), so it fetches it from
Dockerhub, and runs it.
I will probably add another article later with more info on how to actually use Docker, and how to create your own Docker containers. And also how to build them continously.
Installing Watchtower
Watchtower is itself packaged as a Docker container, which makes "installation" rather easy. It is actually apparently as simple as this:
$ docker run -d \
--name watchtower \
-v /var/run/docker.sock:/var/run/docker.sock \
v2tec/watchtower
We can use docker ps
to see if it is running
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d7b9cba16215 v2tec/watchtower "/watchtower" 3 seconds ago Up 3 seconds watchtower
Initializing Watchtower, and other containers
This however, is no way to run a Docker container on a permanent basis. If we reboot the host, the Docker container will stop.
Docker has a way around this. You can specify --restart [no|on-failure|unless-stopped|always]
. But this means that you get two
init-systems you need to be aware of on your host - both systemd and Docker.
Another alternative is to write a systemd-service file for Watchtower, and every other Docker container that you will be running permanently. If you do this, you also have a nice place to put environmental variables and such as well. Personally, I think I prefer this.
Here is a systemd-service for Watchtower:
{{< highlight systemd >}} [Unit] Description=Watchtower Docker container Requires=network.target docker.service After=docker.service
[Service]
Don't restart - it will conflict with Watchtower.
Restart=never
Start with removing old images
ExecStartPre=-/usr/bin/docker rm -f watchtower
ExecStart=/usr/bin/docker run --rm
--name watchtower
-v /var/run/docker.sock:/var/run/docker.sock
v2tec/watchtower
--schedule "0 32 4 * * *"
--cleanup
ExecStop=/usr/bin/docker stop -t 2 watchtower
[Install] WantedBy=default.target {{< / highlight >}}
Installing Kanboard
Alright. Now that we have Docker working, and Watchtower set up, we can set up Kanboard.
I plan on using a systemd-service and Watchtower for Kanboard as well, so let's
start with creating some directories. I plan on using /var/local
to store
files for Docker.
$ sudo mkdir -p /var/local/docker-kanboard/{data,app,ssl}
When that's done, we can create our database. I use postgres. {{< highlight postgresql >}} sudo -u postgres psql psql (10.6 (Ubuntu 10.6-0ubuntu0.18.10.1)) Type "help" for help.
postgres=# create database kanboard; CREATE DATABASE postgres=# create user kanboard with encrypted password 'LALALA'; CREATE ROLE postgres=# grant all on database kanboard to kanboard; GRANT postgres=# \q {{< / highlight >}} Also, we need to be able to connect to postgres, so you need to make sure that postgres listens to the right address (I just listen to all interfaces, and use a firewall to make sure no-one can connect externally). And our new Kanboard-user needs permissions to connect from the Docker network.
I've added this line in /etc/postgresql/10/main/pg_hba.conf
:
host kanboard kanboard 172.17.0.0/16 scram-sha-256
This means that any host
with an adress in 172.17.0.0/16
can connect to the
database kanboard
with the user kanboard
, using scram-sha-256
as the
auth-method.
Now I need a systemd-service for kanboard.
{{< highlight systemd >}} Description=Kanboard Docker container Requires=network.target docker.service watchtower.service After=watchtower.service
[Service]
Don't restart - it will conflict with Watchtower.
Restart=no
#env
Start with removing old images
ExecStartPre=-/usr/bin/docker rm -f kanboard
ExecStart=/usr/bin/docker run --rm
--name kanboard
-e DATABASE_URL="postgres://kanboard:LALALA@server-hostname:5432/kanboard"
-v /var/local/docker-kanboard/data:/var/www/app/data
-v /var/local/docker-kanboard/plugins:/var/www/app/plugins
-v /var/local/docker-kanboard/ssl:/etc/nginx/ssl
-p 8002:80
kanboard/kanboard
ExecStop=/usr/bin/docker stop -t 2 kanboard
[Install]
WantedBy=default.target
{{< / highlight >}}
And that's kinda it. If I run systemctl start kanboard.service
now, I will
have kanboard available on port 8002. I can now set up nginx as a reverse proxy
for this, so kanboard becomes available on kanboard.example.net.
Now all I need is something to continously build any Docker image I create! I will try to write an article about this some time in the future.