Putting a UI around Docker with Portainer

Nils De Moor
Containerizers
Published in
6 min readJan 9, 2017

--

Since we’re smart programmers and ops peeps, every task we execute, we do it through a terminal command, right? But from time to time a little visual feedback doesn’t hurt, right? The people at portainer.io felt the same way and provided an open-source user interface around Docker and Docker Swarm. Let’s take a look.

As in other demos we’ve done, what we’re going to do is set up a full application stack, being the example-voting-app. And we’re going to use Play with Docker to set up the entire cluster. We’ll work with a Docker Swarm environment with five Docker nodes: one manager and four workers.

Let’s run portainer:

docker run -d --name portainer \
-p 9000:9000 \
-v /var/run/docker.sock:/var/run/docker.sock \
portainer/portainer

We run this container as a daemon (`-d`), and publish it on port 9000. We also need to bind mount the Docker socket (`/var/run/docker.sock`) into this container from the `portainer/portainer` image, since it needs to get information coming from the Docker runtime.

On a side note, one of the newer features, in Play with Docker is that now every published port from a Docker container or every published service in Docker Swarm will be announced in the UI in a little jellybean. Clicking that will proxy you directly to that service, without any routing/proxying setup needed (in earlier demo’s we used ngrok for this purpose)!

By clicking that, you will first get a quick setup wizard to set an admin password and to define what environment you want to control. Just pick the local one. After this wizard just log in with the password you just picked and you will be greeted by the Portainer UI.

This will show all information about my current Docker set up. What containers are running? What images have been pulled in on this machine? What volumes have been created? And which the networks have been set up?

Another cool feature is App Templates: if you want a quick way
to set up a certain application, you can do it at the touch of a button through this interface. Let’s set up an Nginx container.

Just click the ‘nginx’ button. You can leave all the settings to default. When the container is launched you’ll see it running in the ‘Containers’ tab in the Portainer UI. In play with Docker, 2 new port jellybeans will be available: one randomly assigned port to publish container port 80 (http), and one for port 443 (https). Clicking the one publishing port 80 will result in the nginx greeting page (getting https to work requires more configuration).

Let’s take it one step further. Another way of running Portainer is running it as a service in after setting up Swarm Mode. So, I’m going to create a service, also named portainer, published on port 9090. It’s very important that this constrained to managers in the swarm, since these are the only nodes who can get information about the Swarm.

docker service create \
--name portainer \
-p 9090:9000 \
--constraint 'node.role == manager' \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
portainer/portainer -H unix:///var/run/docker.sock

After this search is launched, open it up, and you’ll see the Portainer UI again, only this time it looks a little different. On the main dashboard, you’ll see a box ‘Swarm info’ and in the navigation, there are now tabs for ‘Services’ and ‘Swarm’.

Swarm Mode Portainer UI

On to our application now:

The example voting app will feature 2 networks in which we’ll launch 5 services: 2 frontends (voting-app and result-app), 2 databases (redis and postgres) and a worker, to make the bridge between both sides.

First we’ll create the ‘vote’ network by going into the ‘Networks’ tab. In the ‘Add a network’ fill in the name: vote. All other configurations can be left to their default settings. Click ‘create’. A new network, named vote, should now appear in the list of networks below.

Next step, the first service. Go to the ‘Services’ tab, and click ‘Add service’. Here we’re going to configure the vote-app services by filling in some fields and ticking some boxes (leave all other options to their defaults):

# Name: voteapp
# Image: docker/example-voting-app-vote
# Replicas: 3
# Port mapping:
# host: 8080 -> container: 80
# Network: vote

The moment you’ll launch this, your voteapp service will appear in the services list, and when you click it you’ll get a view on the runtime configuration of the service. Below you’ll see the containers the service consists of and once they all have ‘running’ status, your service will be available, and you’ll see the 8080 jellybean in the Play with Docker interface on all nodes thanks to the routing mesh that load balances traffic to the service containers in the Docker Swarm. Clicking that should bring you to the votingapp frontend with a poll to choose between cats and dogs.

On to the next one… now we need to back up our frontend application with a persistent storage layer that will queue the votes and we’re going to do that with redis. So let’s create a new service:

# Name: redis
# Image: redis
# Replicas: 1
# Network: vote

When this is launched the voting side of the app will function correctly without any errors. So now it’s time to launch the result side. Start by creating a new network ‘result’. Then we’ll launch 2 new services. First a Postgres database:

# Name: db
# Image: postgres
# Replicas: 1
# Network: result

Then the resultapp frontend:

# Name: resultapp
# Image: ndemoor/example-voting-app-result
# Replicas: 2
# Port mapping:
# host: 8081 -> container: 80
# host: 5858 -> container: 5858
# Network: result

Finally, to make the bridge between the 2 applications, we’ll launch the worker that will pick up the votes in the redis queue and store them into the postgres database:

# Name: worker
# Image: docker/example-voting-app-worker
# Replicas: 1
# Network: vote
# Extra network: result

With the entire stack up and running, you can now test the full end to end flow by casting a vote in the voteapp and seeing the percentages change in the result app.

To get insights on the realtime performance of your containers, go into the ‘Containers’ tab and click one of the containers. You’ll be presented a detailed view of that specific container, see its stdout and stderr logs, get graphs on CPU/Memory/Network usage of the container and even dive into a terminal to execute live commands on that container.vcbnC

And that’s it! Portainer provides another way to set up applications easily and monitor their behaviour. Make sure to test it out yourself or check out the video on our YouTube channel in which will run you through this entire demo.

If you enjoyed this tutorial, and want to continue the learning journey, I encourage you to head over to this Docker Course, which will take you through numerous topics in the ecosystem to become a Docker Master!

--

--

Having fun with the tech stuff at @woorank. Alter ego's: entrepreneur, positivist, #DockerCaptain