Docker: Apache container with sidecar

Why would you use a sidecar?

e.g. to add something to an existing container without rewriting it.

Assuming you’ve run a container with Apache as in this post: Docker: Apache container then you’ll have an environment variable, APP_ID.

You can use this to run a sidecar container that adds a health metric. E.g.

docker run --pid=container:${APP_ID} -p 8081:8081 brendanburns/topz:db0fa58 /server --addr=

and now you have a sidecar container running. E.g.

curl localhost:8081

91 9.937410610507195 0.02218294 /server --addr=
1 0 0.0024320167 httpd -DFOREGROUND
7 0 0.005011428 httpd -DFOREGROUND
8 0 0.0008106722 httpd -DFOREGROUND
9 0 0.0009335013 httpd -DFOREGROUND



Docker: Apache container

Running Apache in Docker from Ubuntu

Install Docker

curl -fsSL | sh


To allow you to use Docker as a user

sudo usermod -aG docker <username>


Run Docker with Apache image:

sudo docker run -dit –name apache -p 8080:80 -v /tmp/webroot:/usr/local/apache2/htdocs/ httpd:2.4

This will overwrite anything you’ve written to local webroot path.

Also, 8080:80 is host:container.

See also docker container run


And docker stop <your container name> will not delete that volume. It persists.


Test from local machine with:

curl localhost:8080


Note: you can access your container ID if you know the container name. E.g. assuming the container name is apache then you can use:

APP_ID=docker ps | grep apache | awk '{print $1}'


Docker swarm

What is Docker swarm used for?

This SO post is pretty useful (albeit by a Kubernetes guy):


Swarm is an effort by Docker to extend the existing Docker API to make a cluster of machines look like a single Docker API. Fundamentally, our experience at Google and elsewhere indicates that the node API is insufficient for a cluster API. You can see a bunch of discussion on this here: and here:

docker: automatically restart a container

Say you need to restart a VM or restart Docker. How do you restart a container?

E.g. you have:

then restarting Docker (e.g. on the Mac you can click the Docker icon in the toolbar and select Docker > Restart) you get:

whilst Docker is restarting and:

after the restart (i.e. no containers).


You can use --restart always

docker container run --restart always -d <image id> sleep 1d

to restart after a docker reboot.




See also


More on Restart Policies

There are 4 restart policies: no, on-failure, unless-stopped, always.

no is the default. i.e. don’t restart if a container stops.

The others are:


We’ve seen this before. E.g. let’s say we have a script:

Note: exit 1 indicates an error (exit 0 would indicate success).

which we use as follows:


We can build and run with:

This will exit.

To restart with always restart policy use:

docker container run --restart always -d testing_restarts

Now, when it crashes, under docker ps you’ll see:



Here we can restart a container if it exits with a non-zero exit code. We can also specify a number of retries. E.g.

--restart on-failure:3

docker container run --restart on-failure:3 -d testing_restarts


  • the container will not restart if you do a docker stop <container id>
  • the container (and oddly even any containers that have stopped as a result of completing the on-failure number of retries – although only the first time the daemon was restarted) WILL restart if you restart the docker daemon



Behaves the same as always except if a container is stopped.

Note: if you manually stop a container its restart policy is ignored until the Docker daemon restarts.


Ensuring Containers Are Always Running with Docker’s Restart Policy


Live Restore

Lets you keep containers alive when the daemon becomes unavailable,.

However, doing this on my installation of Docker gave:

because I was running a swarm service.


I had to restore to Factory Defaults which means signing in to again.


DockerFile: WordPress

Let’s take a look at Docker‘izing WordPress.


The Docker pull command is:

docker pull wordpress

pull: pulls an image or a repository from a registry. It doesn’t run it. It just means you have the image locally.


You can actually run the image using:

docker run --name some-wordpress --link some-mysql:mysql -d wordpress

some-wordpress is going to be the name of the container.

--link is a bit old school. It connects one container to another. i.e. MySQL to WordPress. Nowadays we use user-defined networks – e.g. overlays.

WordPress Docker Repo:


However, before you can run it you’ll need MySQL. So:

docker pull mysql:5.7.24

(Aside: why not use mysql or mysql:latest? ‘cos MySQL 8 changed the password authentication method. See below.)

and then run it with:

docker run --name test-mysql -e MYSQL_ROOT_PASSWORD=test -d mysql:5.7.24

--name is the name you’re giving to the container,

MYSQL_ROOT_PASSWORDis an environment variable that you set which is read in the container. Note: with MySQL this is done programmatically via – . For more on ARG, Environment variables:

and -d means detach.

To specify a tagged version just add it after the image using a colon. E.g. mysql:5.7.24.


Once you’ve run it you can test it by exec‘ing in with

docker exec -it test-mysql bash

and running:

mysql -u root -p test

or check logs with:

docker logs test-mysql


2018-12-03T14:24:57.091306Z 0 [Note] mysqld: ready for connections.
Version: '5.7.24' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)


Or even mysql in via another MySQL container using:

docker run -it --link test-mysql:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'


So, getting back to WordPress let’s run it now with:

docker run --name test-wordpress --link test-mysql:mysql -d wordpress

and check the logs with:

You should then be able to access your WordPress site on http://localhost:8080



Conflict. The container name “/test-wordpress” is already in use by container

You run

docker run --name test-wordpress --link test-mysql:mysql -d wordpress

and get:

docker: Error response from daemon: Conflict. The container name "/test-wordpress" is already in use by container "0ea70abdaf306d896eb71f3ab585961359f27af23a243b81370bf407d3dd846d". You have to remove (or rename) that container to be able to reuse that name.

You’ve already got a container with that name.

Remove it with: docker rm test-wordpress

This might happen if the container exited and you try and relaunch it.


Site can’t be reached

You plug http://localhost:8080 into the web browser but get:

Checking the WordPress logs with docker logs test-wordpress I can see:

however this is a secondary problem. Why are we getting this?

‘cos MySQL 8 introduced a different type of authentication –

If you are getting this then you need to use: docker pull mysql:5.7.24 or use a different auth method.


Back to the problem at hand – we should still be able to see a (non-functioning) WordPress site on that port. i.e. Apache should be running.

Let’s just do a sanity check:

This>80/tcp means the docker host port 8080 is mapped to the container port 80.

so http://localhost:8080 is correct.


It seems the problem really was the lack of MySQL. Using 5.7.24 and looking at the WordPress logs showed (for a successful installation):


Installing MySQL and WordPress in under a minute:






Monitoring containers with Prometheus and Grafana

Architecting Monitoring for Containerized Applications

Why not use Nagios?

Can’t use same method as traditional servers. E.g. putting an agent into a container doesn’t really work.

/metrics exposed for container runtime. Docker uses Prometheus format (i.e. simple text with Key Value format)

Prometheus stores data in time series database.

Prometheus configuration

Is in YAML. E.g.




- job_name: <name here>


scrape_interval: 60s

Prometheus Dashboard

Status > Targets: lists all monitored targets

Graph > Graph > select from insert metric at cursor


Collecting Metrics with Prometheus

Exposing Runtime Metrics with Prometheus

Exposing Application Metrics to Prometheus

Exposing Docker Metrics to Prometheus

Building Dashboards with Grafana