When preparing or changing a MySQL environment, it is essential to test many aspects of the build prior to rolling it out to a production system. For this, I use a Docker-based test environment which I spin up to perform the relevant testing.
In this example, I will prepare a MySQL instance, with its own persistent data directory which will survive a full Docker image re-build. This then becomes the foundation of future articles and examples.
Assuming you already have Docker installed on your machine (install docker if you have not yet done this), create the following folder structure as shown below.
$ tree -d test
test
└── data
└── mysql
All the files we create for this test environment will go inside the test
folder, and all the MySQL data files for the test instance will be stored within the data/mysql
folder.
Create a file in the test
folder called docker-compose.yml
containing the following content. This file defines a Docker container based on the MySQL image (mysql:5.7
). The container will mount the MySQL data folder located in the data
folder into the default data file location for MySQL on the container when it is created. The default password for the root
user is provided within the config file, which is then used by the MySQL setup scripts. Ports 33060
is mapped to 3306
to allow access from the host machine.
version: '2'
services:
# --------------------------------------------------------------
mysql:
image: mysql:5.7
container_name: mysql_test
volumes:
- ./data/mysql:/var/lib/mysql
environment:
- "MYSQL_ROOT_PASSWORD=secret"
ports:
- "3306:3306"
From within the test
folder you can now fire up this environment by downloading the MySQL 5.7 Docker image (if required) and starting up the container in background ‘daemon’ mode.
$ docker-compose up -d
Creating network "single_test_default" with the default driver
Pulling mysql (mysql:5.7)...
5.7: Pulling from library/mysql
d599a449871e: Pull complete
f287049d3170: Pull complete
08947732a1b0: Pull complete
96f3056887f2: Pull complete
871f7f65f017: Pull complete
1dd50c4b99cb: Pull complete
5bcbdf508448: Pull complete
02a97db830bd: Pull complete
c09912a99bce: Pull complete
08a981fc6a89: Pull complete
818a84239152: Pull complete
Digest: sha256:5779c71a4730da36f013a23a437b5831198e68e634575f487d37a0639470e3a8
Status: Downloaded newer image for mysql:5.7
Creating mysql_test ... done
This will automatically start the MySQL instance, which will, in turn, create all the necessary folders and files required in the data folder to allow the instance to run.
$ tree -d data
data
└── mysql
├── mysql
├── performance_schema
└── sys
You can also confirm the running MySQL container with the following command, showing the base image used and what port is mapped to the container.
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
18fc7741b5ee mysql:5.7 "docker-entrypoint.s…" 58 seconds ago Up 57 seconds 33060/tcp, 0.0.0.0:33060->3306/tcp mysql_test
You can see that the container has the port 33060/tcp
open, and an additional port has been opened on each container that is mapped to the regular MySQL port 3306. This allows us to use MySQL Shell (mysqlsh
) to connect to the MySQL instance using the address localhost:33060
.
$ mysqlsh --sql -h localhost -P 33060 -u root -psecret
mysqlsh: [Warning] Using a password on the command line interface can be insecure.
Creating a session to 'root@localhost:33060'
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 7
Server version: 5.7.28 MySQL Community Server (GPL)
No default schema selected; type \use <schema> to set one.
MySQL Shell 8.0.12
Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type '\help' or '\?' for help; '\quit' to exit.
MySQL localhost:33060 ssl SQL > show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.0174 sec)
I wouldn’t normally supply the password on the command line using -p{password}
as it would be stored in the shell history and visible on the system process list, but as this is just a test environment, I’m happy to do so.
When you are happy that everything is working as expected, stop the Docker container by running the following command. This helps to free up resources on your host machine – many times I’ve realised I’ve still got a number of Docker containers still running that I’d forgotten about 🙂
$ docker-compose down
Stopping mysql_test ... done
Removing mysql_test ... done
Removing network single_test_default
To extend this to multiple instances to test replication, take a look at my article Docker-based Multiple MySQL. In this and future articles, I will be expanding this environment with additional replica hosts, management and monitoring tools.