Part 2 - Working with multiple containers
In part 1 we looked at starting, inspecting and interacting with a single container that had both an attached volume and a FIP to expose a port publicly. In this section we’ll look at how to work with multiple containers by using the perennial Wordpress example.
Note If you’re familiar with Docker Compose, this will seem like a lot of manual work. Don’t worry, we’ll get to Hyper Compose in the next section!
By now you’ll probably be able to guess the next steps, but let’s walk through them anyway.
$ hyper run --name mysqldb -e MYSQL_ROOT_PASSWORD=12345678 -d mysql Unable to find image 'mysql:latest' in the current region latest: Pulling from library/mysql (Output cut to save space) 75a822cd7888: Pull complete Digest: sha256:de1570492c641112fdb94db9c788f6a400f71f25a920da95ec88c3848450ed57 Status: Downloaded newer image for mysql:latest 34856a35232f9044c93adaa4dd286b117412bf9580462d0e58a6c43055af9c81
Now let’s use
hyper ps to check that the MySQL container is running:
$ hyper ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES PUBLIC IP 34856a35232f mysql "docker-entrypoint.sh" 12 seconds ago Up 4 seconds mysqldb
All looks good. If you check
hyper volume ls though, you’ll see something that you perhaps didn’t expect.
$ hyper volume ls DRIVER VOLUME NAME SIZE CONTAINER hyper 0492591e7602076e1240dbbcdead666945218049dfcd4f58e62dad4ce647c24 10 GB 34856a35232f
The hyper run command has automatically created and attached a 10GB Hyper Volume to the MySQL container.
As we mentioned before, Hyper Volumes are analogous to Amazon EBS mounts and allow you to decouple the lifetime of your data from the lifetime of the container. This is probably desirable for a database, but why did this happen without our explicit consent?
To answer is that we need to look at the Dockerfile that created the MySQL Docker image. The important line is below:
When there is a
VOLUME line in a Dockerfile, the Docker engine will automatically create a volume when the container is started. Hyper mirrors this behaviour, but because you pay per-second with Hyper, it’s always good to know what you’re paying for.
If you would like to disable this behaviour entirely you can always do that during the run command with the
--noauto-volume flag, for example:
$ hyper run --name mysqldb -e MYSQL_ROOT_PASSWORD=12345678 --noauto-volume -d mysql
If you choose not to automatically create volumes all data will be written to the rootFS volume in the container that is deleted when your container is killed.
Next we’ll start the Wordpress container. The key point here is that the Wordpress container will need to find the MySQL container in order to connect to it. This is achieved via the
--link flag for the
hyper run command.
$ hyper run --name mywordpress --link mysqldb:mysql -p 8080:80 -d wordpress
If we now check the Wordpress container’s logs we will see that it is happily starting up:
$ hyper logs mywordpress WordPress not found in /var/www/html - copying now... Complete! WordPress has been successfully copied to /var/www/html [Fri Dec 23 17:03:23.226477 2016] [mpm_prefork:notice] [pid 6] AH00163: Apache/2.4.10 (Debian) PHP/5.6.29 configured -- resuming normal operations [Fri Dec 23 17:03:23.231231 2016] [core:notice] [pid 6] AH00094: Command line: 'apache2 -D FOREGROUND'
So what exactly did
--link do? Well actually it does two things. Firstly it exposes the environments variables from the MySQL container to the Wordpress container as we can see using
$ hyper exec mywordpress env | grep -i mysql MYSQL_PORT_3306_TCP_PROTO=tcp MYSQL_ENV_MYSQL_MAJOR=5.7 MYSQL_PORT_3306_TCP=tcp://172.16.0.30:3306 MYSQL_ENV_MYSQL_ROOT_PASSWORD=12345678 MYSQL_PORT=tcp://172.16.0.30:3306 MYSQL_PORT_3306_TCP_ADDR=172.16.0.30 MYSQL_ENV_MYSQL_VERSION=5.7.17-1debian8 MYSQL_ENV_GOSU_VERSION=1.7 MYSQL_NAME=mysql MYSQL_PORT_3306_TCP_PORT=3306
--link creates an entry in the
/etc/hosts file on the Wordpress container so that it can resolve the MySQL container’s IP address:
$ hyper exec mywordpress cat /etc/hosts | grep -i mysql 172.16.0.30 mysql
Note on linking containers The whole reason why linking works in this case is because the MySQL container knows to look for certain environment variables at start up time. Although this is a common container pattern, make sure you check the startup scripts of any containers that you’re using to see what information they expect.
You could now go ahead and connect your Wordpress container to an FIP and connect to it from the internet, but we already covered that in section 1 so that’s left up to you.
In this section we’ve seen how by using
--link we can share environment variables and dns information between containers so that they can work together.
Final note Don’t forget to clean up your resources from part 2!
In Part 3 we'll look at using Hyper Compose, which makes dealing with multiple containers much simpler.