Update from Dockerland: Fruitful Collaboration and Some Security News

A Productive Nine Months

It’s been around 9 months since we did the first cut of our own MySQL Docker images, and it is time for a bit of an update on where we are in Dockerland these days, and also to talk about some important security related improvements we made to the images lately.

whale-dolphin

When we started this activity, we set three goals for ourselves:

  • We wanted to contribute to the amazingly popular community maintained MySQL Docker images.
  • We wanted to roll our own images as well, so we could go in some new directions and implement some features that the existing community might not be that interested in.
  • We wanted to take the experience from our Docker work back to our own products so we can improve the way MySQL works inside containers.

Throughout, we have made sure to work as much as possible inside the Docker community, keeping up with community image changes and contributing back any changes and improvements from our own images to the community. This has proved very fruitful, and the results so far include much better docs for both images, more robust image startup and improvements to security. More on some recent, specific improvements below.

Meanwhile, we have made a number of adjustments to MySQL that make us a better fit for containerization. An example is that MySQL 5.7 has a new --initialize option that will create the data directory and populate the tables in the MySQL system database on initial startup. With pre-5.7 versions of MySQL Perl must be available in the container because initialization is done by a Perl script called mysql_install_db. We have also made several changes to how MySQL behaves on startup, in order to fix both robustness and security issues on container startup … and more is on the horizon as we start development for the next major version of MySQL.

Let me say a big thank you to the Docker community who have welcomed us and been very supportive of our Docker related efforts.

Some Important Security News

Secure your containers!
Secure your containers!

I’ll go on to highlight some important improvements that we’ve made lately, and that have also recently gone into the community maintained images. Previously, the only way you could set a password for the MySQL root admin user on initial container startup was to pass the MYSQL_ROOT_PASSWORD environment variable on the docker run command line. This may be fine when you are doing automated deployments using e.g. orchestration tools like Docker Compose, but if you start your container manually from the command line, giving the root password in clear text is a security problem.

To improve security, there is now a new, strongly recommended way of starting the container manually (breaking backward compatibility is of course a no-go, so the old MySQL_ROOT_PASSWORD way is still supported). By setting the new environment variable MYSQL_RANDOM_ROOT_PASSWORD to yes on the docker run command line, if desired in combination with MYSQL_ONETIME_PASSWORD=yes, you will be able to hide the admin password from prying eyes.

Here is an example:

docker run --name my-container-name -e MYSQL_RANDOM_ROOT_PASSWORD=yes -e MYSQL_ONETIME_PASSWORD=yes -d mysql/mysql-server:tag

This starts the container my-container-name. A strong random password gets generated on container startup, and this password gets written to stdout inside the container, which means that it ends up in the Docker log of the container. Grab it as follows:

docker logs my-container-name

Look for the line starting with GENERATED ROOT PASSWORD in the output, and there it is.

If you also set MYSQL_ONETIME_PASSWORD=yes on the command line, you will need to change the password on first login. Start a mysql client session against the MySQL instance in the container; in this example we will do this from a shell inside the container itself:

docker exec -it my-container-name bash

Start a mysql client session and use the randomly generated root password to log in:

mysql -u root -p

Then set a new, secure password on the mysql client command line:

ALTER USER root IDENTIFIED BY 'my-new-pw';

As you can see, this more secure way of running your container involves a few more steps than the old one, but we strongly recommend doing it this way for any use case of importance.

Rounding Off

Oh, and just one more thing. One of the most frequent types of request for improvements to the community images seems to be addition of docker run environment variables that can be used to control the behaviour of MySQL. This can quite easily be accomplished through a (strangely little known) feature of the MySQL images: any options given at the end of the docker run command line will simply be passed to the mysqld process running inside the container. A popular example includes setting the default charset and collation for all databases in the containerized MySQL instance:

docker run --name my-container-name -d mysql/mysql-server --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci

This sets the default charset and collation to full 4-byte UTF-8.

Thanks for reading. We’d be delighted to hear from you if you are a MySQL-on-Docker user, so drop us a line in the comments section below or comment on our main page on Docker Hub. And in case you should encounter any issues or have concrete feature or improvement requests: file a bug in the MySQL bug database.

Yngve Svendsen

About Yngve Svendsen

Yngve Svendsen has been part of the MySQL organization since 2008. Based in Trondheim, Norway, he is Senior Director of MySQL Engineering Services and responsible for Release Engineering, QA and development lab IT services for the MySQL org at Oracle. Back in the mists of time he majored in mathematics before the dot com wave swept him into the devops field, first at the database startup company Clustra Inc. and then for Sun Microsystems. In 2005 he joined the Dark Side by becoming a manager in Sun's Database Group which was merged into the MySQL org when Sun acquired MySQL in 2008.

7 thoughts on “Update from Dockerland: Fruitful Collaboration and Some Security News

  1. I am experimenting with MySQL docker and its i nitial setup looks really good.

    Can we setup replication or other HA / fault tolerant environment using MySQL docker.

    Are this technology production ready?

    1. Hi, Nirav.

      It would certainly be possible to set up and run MySQL replication using Docker, and it would be an interesting way to utilize Docker. We have not at this time, however, developed specific images or recipes for this kind of usage. As regards robustness of MySQL on Docker in general, we test the images before releasing, and there have been very few reports of significant issues from the user community, both for our own images and for the community maintained images. But there are of course a vast number of possible setups with Docker, and Docker itself is a fairly new platform, so your mileage may of course vary.

  2. Thanks for this update. Some of the info here are going to be a great time saver!

    I have a request about password management. The variable MYSQL_RANDOM_ROOT_PASSWORD is only useful for manual operations on the container, but not so much for scripting. When I need to set up many servers, it is easier to use MYSQL_ROOT_PASSWORD. However, this variable is passed on the command line, which may lead to security issues. Is it possible to use a file instead of a variable to pass the root password?
    I am thinking of something like:
    docker run –name mybox -v $PWD/mypassword:/root/mypassword -d mysql/mysql-server
    and entrypoint.sh would start with
    if [ -f /root/mypassword ] ; then export MYSQL_ROOT_PASSWORD=$(cat /root/mypassword) ; fi

    This would allow the creation of many servers without exposing the root password on the command line.

    1. All mysql/mysql-server images should support this functionality now:
      If you pass a valid file path to -e MYSQL_ROOT_PASSWORD, it will use the contents of the file as the password, i.e.:
      docker run -v $PWD/mypassword:/root/mypassword -e MYSQL_ROOT_PASSWORD=/root/mypassword -d mysql/mysql-server

  3. Thanks for this priceless tip! – any options given at the end of the docker run command line will be passed to the mysqld process running inside the container.

Leave a Reply

Your email address will not be published. Required fields are marked *

Please enter * Time limit is exhausted. Please reload the CAPTCHA.