Docker Container: MySQL 8

February 16, 2020

On this post we are going to create a container with a MySQL 8 server database.

Dockerfile and additional files

The Dockerfile shown below has been copied from MySQL GitHub repository, specifically from the following folder:
https://github.com/mysql/mysql-docker/tree/mysql-server/8.0


Along with the Dockerfile, there are two additional files: docker-entrypoint.sh, and healthcheck.sh that are required for the creation of the Docker Image. These files that can also be found on the GitHub repository indicated above.

Dockerfile


# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
FROM oraclelinux:7-slim

ARG MYSQL_SERVER_PACKAGE=mysql-community-server-minimal-8.0.19
ARG MYSQL_SHELL_PACKAGE=mysql-shell-8.0.19

# Install server
RUN yum install -y https://repo.mysql.com/mysql-community-minimal-release-el7.rpm \
        https://repo.mysql.com/mysql-community-release-el7.rpm \
    && yum-config-manager --enable mysql80-server-minimal \
    && yum install -y \
        $MYSQL_SERVER_PACKAGE \
        $MYSQL_SHELL_PACKAGE \
        libpwquality \
    && yum clean all \
    && mkdir /docker-entrypoint-initdb.d

VOLUME /var/lib/mysql

COPY docker-entrypoint.sh /entrypoint.sh
COPY healthcheck.sh /healthcheck.sh

RUN chmod +x /entrypoint.sh
RUN chmod +x /healthcheck.sh

ENTRYPOINT ["/entrypoint.sh"]
HEALTHCHECK CMD /healthcheck.sh
EXPOSE 3306 33060
CMD ["mysqld"]

You can download a compressed zip file with this Dockerfile, as well as the docker-entrypoint.sh, and the healthcheck.sh files from here.


Compared to the original Dockerfile the only additions have been the RUN commands that change the permissions of the entrypoint and healthcheck files, which is needed so that they can be run inside the container.


RUN chmod +x /entrypoint.sh
RUN chmod +x /healthcheck.sh

As a first step before creating the Docker Image and Container, unzip the compressed file containing the Dockerfile, the entrypoint and healthcheck files.


Docker-mysql-8/
  ├─ Dockerfile
  ├─ docker-entrypoint.sh
  └─ healthcheck.sh

Create the Docker Image and Container

Now we create the Docker Image.

Open a terminal window, navigate to the folder containing the Dockerfile, and type the following command:.


docker build -t image_mysql8 .


Then we create the Docker Container.

Type the following command on the terminal window:


docker run -d -p 3306:3306 --name=container_mysql8 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_ROOT_HOST=% \
image_mysql8 --default-authentication-plugin=mysql_native_password

  • We use the -p 3306:3306 parameter to specify the port to access the MySQL server. If you have already running another instance of a MySQL server using the same port, you would need to stop it, or use another port for this container. (i.e. -p 4001:3306)

  • With the MYSQL_ROOT_PASSWORD parameter we are indicating the password of our root user. In the command above we are using the password "root". You may want to use a more secure password.

  • With the MYSQL_ROOT_HOST=% parameter we are going to allow connections from any IP address. Without this parameter we wouldn't be able to connect to the MySQL server from the host machine, and you may get an error like this:
    Host '172.17.0.1' is not allowed to connect to this MySQL server

  • MySQL 8 is set by default with a new authentication method using SHA2. And if your are going to use PHP to connect to it, then the connection would fail since PHP doesn't currently support the new method.
    The parameter --default-authentication-plugin=mysql_native_password will change the authentication method so that PHP will be able to access it.
    Without this parameter you may get an error like this:
    Authentication plugin 'caching_sha2_password' cannot be loaded:
    dlopen(/usr/local/mysql/lib/plugin/caching_sha2_password.so, 2): image not found
    Or this:
    The server requested authentication method unknown to the client

Check the status of the Docker Container

Important Note: Once you create the container, it is not immediately available to be used since the MySQL server is running its start up process. To check the status of the server use the docker ps -a command.


docker ps -a

You will see an output similar to this one:

CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                            PORTS                               NAMES
01fd851f848d        image_mysql8            "/entrypoint.sh --de…"   4 seconds ago       Up 3 seconds (health: starting)   0.0.0.0:3306->3306/tcp, 33060/tcp   container_mysql8

Notice that under the STATUS column, it indicates (health: starting)


Wait a few seconds and run the docker ps -a command again. The status will have changed to (healthy)

CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                      PORTS                               NAMES
01fd851f848d        image_mysql8            "/entrypoint.sh --de…"   38 seconds ago      Up 36 seconds (healthy)     0.0.0.0:3306->3306/tcp, 33060/tcp   container_mysql8

The MySQL server is now ready to be used.


Test the Docker Container

If you have telnet installed on your host machine, you can perform a quick test by executing the following:


telnet localhost 3306

You should see an output similar to this one:

Trying ::1...
Connected to localhost.
Escape character is '^]'.
J
8.0.19
v9PA?HI%mI
mysql_native_password


Downloads

Docker-mysql-8.zip



Check the Dockerfile on Github here.

Download the Image from Docker Hub here.