Setting up and Running a MySQL Container – 设置和运行一个MySQL容器

最后修改: 2022年 8月 9日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Containers are the hottest topic of discussion in the IT Industry because of their many advantages. Organizations are adopting container-based solutions for their business at a remarkable rate. According to 451 Research, the application container market will grow four times larger in the coming years.

容器因其众多优势而成为IT行业最热门的讨论话题。各组织正在以惊人的速度为其业务采用基于容器的解决方案。根据451 Research的数据,应用容器市场在未来几年将增长四倍。

Today, we even have databases like MySQL, MongoDB, PostgreSQL, and many more in containerized form. However, this article will explore options for setting and running MySQL containers. To start, we’ll take the backup of our existing MySQL database. Next, we’ll build a container configuration in YAML form and run it using docker-compose, an open-source toolkit for bringing up a stack of application containers together.

今天,我们甚至拥有像MySQL、MongoDBPostgreSQL等数据库的容器化形式。然而,本文将探讨用于设置和运行MySQL容器的选项。首先,我们将对我们现有的MySQL数据库进行备份。接下来,我们将以YAML形式建立一个容器配置,并使用docker-compose来运行它,这是一个开源的工具包,用于将应用程序容器堆叠在一起。

Without any further ado, let’s get into the nitty-gritty details of it.

不多说了,让我们来了解一下其中的细节。

2. Building a MySQL Container Configuration

2.构建一个MySQL容器配置

In this section, we’ll build the MySQL container using the docker-compose tool. However, the YAML also uses the image from the Dockerfile as the base configuration in the current path.

在本节中,我们将使用docker-compose工具构建MySQL容器。然而,YAML也使用Dockerfile中的镜像作为当前路径中的基本配置。

2.1. Docker Compose

2.1.Docker Compose

First, let’s create the YAML file with version and services tags. We define the file format version under the version tag of the YAML file. The MySQL services use the image information from Dockerfile, which we define in the context.

首先,让我们创建带有versionservices标签的YAML文件。我们在YAML文件的version标签下定义文件格式版本。MySQL服务使用来自Dockerfile的图像信息,我们在上下文中定义该信息。

Further, we also instruct the tool to use the default arguments defined as an environmental variable in the .env file. Last, the ports tag will bind the container and host machine port 3306. Let’s see the contents of the docker-compose YAML file we’re using to bring up the MySQL services:

此外,我们还指示工具使用在.env文件中作为环境变量定义的默认参数。最后,ports标签将绑定容器和主机的3306端口。让我们看看docker-composeYAML文件的内容,我们要用它来调出MySQL服务。

# cat docker-compose.yml
version: '3.3'
services:
### MySQL Container
  mysql:
    build:
      context: /home/tools/bael/dung/B015
      args:
        - MYSQL_DATABASE=${MYSQL_DATABASE}
        - MYSQL_USER=${MYSQL_USER}
        - MYSQL_PASSWORD=${MYSQL_PASSWORD}
        - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    ports:
      - "${MYSQL_PORT}:3306"

2.2. Dockerfile Creation

2.2.创建Docker文件

Internally, docker-compose uses the Dockerfile in the specified path to build the image and set the environment for MySQL. Our Dockerfile downloads the image from DockerHub and spins up the container with the defined variables:

在内部,docker-compose使用指定路径中的Dockerfile来构建镜像并为MySQL设置环境。我们的Dockerfile从DockerHub下载镜像,并使用定义的变量启动容器。

# cat Dockerfile
FROM mysql:latest

MAINTAINER baeldung.com

RUN chown -R mysql:root /var/lib/mysql/

ARG MYSQL_DATABASE
ARG MYSQL_USER
ARG MYSQL_PASSWORD
ARG MYSQL_ROOT_PASSWORD

ENV MYSQL_DATABASE=$MYSQL_DATABASE
ENV MYSQL_USER=$MYSQL_USER
ENV MYSQL_PASSWORD=$MYSQL_PASSWORD
ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD

ADD data.sql /etc/mysql/data.sql

RUN sed -i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql
RUN cp /etc/mysql/data.sql /docker-entrypoint-initdb.d

EXPOSE 3306

Now, let’s have a glimpse of all the instructions given in the below Dockerfile snippet:

现在,让我们来看看下面Dockerfile片段中的所有说明。

  • FROM – A valid Dockerfile begins with the FROM statement, which describes the image name and version tag. In our case, we use the mysql image with the latest tag.
  • MAINTAINER – Set the author information as the container’s metadata that is visible through the docker inspect.
  • RUN – Execute the command on top of the mysql image, which subsequently forms a new layer. The resultant- image is committed and used for the next steps defined in the Dockerfile.
  • ARG – Pass variables during build time. Here, we are passing four user variables as build arguments.
  • ENV – We use the $ symbol to represent the environment variables in Dockerfile. In the above snippet, we use four variables.
  • ADD – During build time, it will add the file into the container for future use.
  • EXPOSE – Make the services available outside the Docker Container.

2.3. Setting the Environment

2.3.设置环境

Additionally, we can create an environment variable file as .env in the current path. This file contains all the variables involved in the compose file:

此外,我们可以在当前路径下创建一个环境变量文件,即.env。这个文件包含了编译文件中涉及的所有变量。

# cat .env
MYSQL_DATABASE=my_db_name
MYSQL_USER=baeldung
MYSQL_PASSWORD=pass
MYSQL_ROOT_PASSWORD=pass
MYSQL_PORT=3306

2.4. MySQL Backup File

2.4 MySQL备份文件

For the sake of demonstration, let’s take the backup from the existing database table. Here, we import the same Customers table into our MySQL container automatically through the data.sql file.

为了演示,让我们从现有的数据库表进行备份。在这里,我们通过data.sql文件将同样的Customers表自动导入我们的MySQL容器。

Below, we’ve showcased the table data using the SELECT query, which fetches data from the requested table:

下面,我们使用SELECT查询展示了表的数据,它从请求的表中获取数据。

mysql> select * from Customers;
+--------------+-----------------+---------------+-----------+------------+---------+
| CustomerName | ContactName     | Address       | City      | PostalCode | Country |
+--------------+-----------------+---------------+-----------+------------+---------+
| Cardinal     | Tom B. Erichsen | Skagen 21     | Stavanger | 4006       | Norway  |
| Wilman Kala  | Matti Karttunen | Keskuskatu 45 | Helsinki  | 21240      | Finland |
+--------------+-----------------+---------------+-----------+------------+---------+
2 rows in set (0.00 sec)

As part of the MySQL RDBMS package, the mysqldump utility is used to backup all data in a database into a text file. Using a simple command with inline arguments, we can quickly take the backup of the MySQL tables:

作为MySQL RDBMS软件包的一部分,mysqldump工具被用来将数据库中的所有数据备份到一个文本文件。使用一个带有内联参数的简单命令,我们可以快速地对MySQL表进行备份。

  • -u: MySQL username
  • -p: MySQL password
# mysqldump -u [user name] –p [password] [database_name] > [dumpfilename.sql]

# mysqldump -u root -p my_db_name > data.sql
Enter password:

At a high level, the backup file will drop any table named Customers in the chosen database and insert all backed-up data into it:

在高水平上,备份文件将放弃所选数据库中任何名为Customers的表,并将所有备份的数据插入其中。

# cat data.sql
-- MySQL dump 10.13  Distrib 8.0.26, for Linux (x86_64)
...
... output truncated ...
...
DROP TABLE IF EXISTS `Customers`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `Customers` (
  `CustomerName` varchar(255) DEFAULT NULL,
...
... output truncated ...
...
INSERT INTO `Customers` VALUES ('Cardinal','Tom B. Erichsen','Skagen 21','Stavanger','4006','Norway'),('Wilman Kala','Matti Karttunen','Keskuskatu 45','Helsinki','21240','Finland');
/*!40000 ALTER TABLE `Customers` ENABLE KEYS */;
UNLOCK TABLES;
...
... output truncated ...
...
-- Dump completed on 2022-07-28  1:56:09

However, the database creation or removal isn’t managed in the created dump file. We’ll add the below snippet in the data.sql file, which creates the databases if they do not exist. It makes the circle complete by managing both databases and tables. Finally, it also uses the created database with the USE command:

然而,在创建的转储文件中并没有管理数据库的创建或删除。我们将在data.sql文件中添加下面的片段,如果数据库不存在,它将创建数据库。它通过管理数据库和表使这个圈子变得完整。最后,它还用USE命令使用创建的数据库。

--
-- Create a database using `MYSQL_DATABASE` placeholder
--
CREATE DATABASE IF NOT EXISTS `MYSQL_DATABASE`;
USE `MYSQL_DATABASE`;

Currently, the directory structure looks like this:

目前,目录结构看起来像这样。

# tree -a
.
├── data.sql
├── docker-compose.yml
├── Dockerfile
└── .env

3. Spinning up a MySQL Server Container

3.启动一个MySQL服务器容器

Now, we’re all set to spin up a container through docker-compose. To bring up the MySQL container, we need to execute docker-compose up.

现在,我们已经准备好通过docker-compose来启动一个容器了。为了启动MySQL容器,我们需要执行docker-compose up

When we skim through the output lines, we can see that they form the new layers in each step on top of the MySQL image.

当我们略过输出行时,我们可以看到它们在MySQL图像之上的每一步都形成了新的层

Subsequently, it also creates the databases and loads the data specified in the data.sql file:

随后,它还创建数据库并加载data.sql文件中指定的数据。

# docker-compose up
Building mysql
Sending build context to Docker daemon  7.168kB
Step 1/15 : FROM mysql:latest
 ---> c60d96bd2b77
Step 2/15 : MAINTAINER baeldung.com
 ---> Running in a647bd02b91f
Removing intermediate container a647bd02b91f
 ---> fafa500c0fac
Step 3/15 : RUN chown -R mysql:root /var/lib/mysql/
 ---> Running in b37e1d5ba079

...
... output truncated ...
...

Step 14/15 : RUN cp /etc/mysql/data.sql /docker-entrypoint-initdb.d
 ---> Running in 34f1d9807bad
Removing intermediate container 34f1d9807bad
 ---> 927b68a43976
Step 15/15 : EXPOSE 3306
 ---> Running in defb868f4207
Removing intermediate container defb868f4207
 ---> 6c6f435f52a9
Successfully built 6c6f435f52a9
Successfully tagged b015_mysql:latest
Creating b015_mysql_1 ... done
Attaching to b015_mysql_1
mysql_1  | 2022-07-28 00:49:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.26-1debian10 started.

...
... output truncated ...
...

mysql_1  | 2022-07-28 00:49:16+00:00 [Note] [Entrypoint]: Creating database my_db_name
mysql_1  | 2022-07-28 00:49:16+00:00 [Note] [Entrypoint]: Creating user baeldung
mysql_1  | 2022-07-28 00:49:16+00:00 [Note] [Entrypoint]: Giving user baeldung access to schema my_db_name
mysql_1  |
mysql_1  | 2022-07-28 00:49:16+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/data.sql
...
... output truncated ...
...

We can use the -d option to run containers in detached mode:

我们可以使用-d选项,以分离模式运行容器

# docker-compose up -d
Building mysql
Sending build context to Docker daemon  7.168kB
Step 1/15 : FROM mysql:latest
 ---> c60d96bd2b77
...
... output truncated ...
...
Step 15/15 : EXPOSE 3306
 ---> Running in 958e1d4af340
Removing intermediate container 958e1d4af340
 ---> c3516657c4c8
Successfully built c3516657c4c8
Successfully tagged b015_mysql:latest
Creating b015_mysql_1 ... done
#

4. MySQL Client Readiness

4.MySQL客户端的准备情况

It’s mandatory to install a client to get easy access to the MySQL server. Depending on our need, we can install the client on either the host machine or any other machine or container that has IP reachability with the server container:

必须安装一个客户端,以方便访问MySQL服务器。根据我们的需要,我们可以将客户端安装在主机或任何其他与服务器容器有IP联系的机器或容器上。

$ sudo apt install mysql-client -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
mysql-client is already the newest version (5.7.37-0ubuntu0.18.04.1).
...
... output truncated ...
...

Now, let’s extract the installation path and version of the MySQL client:

现在,让我们提取MySQL客户端的安装路径和版本。

$ which mysql
/usr/bin/mysql
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.37, for Linux (x86_64) using  EditLine wrapper

5. Server Client Communication

5.服务器客户通信

We can access the deployed MySQL server using the client application. In this section, we’ll see how to access the MySQL server through the client.

我们可以使用客户端应用程序访问已部署的MySQL服务器。在本节中,我们将看到如何通过客户端访问MySQL服务器。

Let’s look at the created container id and status using the docker ps command:

让我们用docker ps命令来看看创建的容器ID和状态。

# docker ps | grep b015_mysql
9ce4da8eb682   b015_mysql                "docker-entrypoint.s…"   21 minutes ago   Up 21 minutes         0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp                                                                    b015_mysql_1

Next, let’s get the container IP address to access the database using the installed client service. If we issue the docker inspect command, we’ll see the detailed information about the container in JSON format. We can also pick any field from the resultant JSON. Here, we are taking the IP address from range.NetworkSettings.Networks -> IPAddress:

接下来,让我们获取容器的IP地址,以使用已安装的客户端服务访问数据库。如果我们发出docker inspect命令,我们将看到JSON格式的容器的详细信息。我们还可以从结果的JSON中挑选任何字段。在这里,我们从range.NetworkSettings.Networks -> IPAddress中获取IP地址。

# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 9ce4da8eb682
172.19.0.2

We can then use the client to log in to MySQL Server using the configured host and port information:

然后我们可以使用客户端使用配置的主机和端口信息登录到MySQL服务器。

# mysql -h 172.17.0.2 -P 3306 --protocol=tcp -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
...
... output truncated ...
...
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| my_db_name         |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
mysql> use my_db_name
...
... output truncated ...
...

Database changed

Here, we can see that the data is restored automatically from the data.sql file:

在这里,我们可以看到,数据被自动从data.sql文件中恢复。

mysql> select * from Customers;
+--------------+-----------------+---------------+-----------+------------+---------+
| CustomerName | ContactName     | Address       | City      | PostalCode | Country |
+--------------+-----------------+---------------+-----------+------------+---------+
| Cardinal     | Tom B. Erichsen | Skagen 21     | Stavanger | 4006       | Norway  |
| Wilman Kala  | Matti Karttunen | Keskuskatu 45 | Helsinki  | 21240      | Finland |
+--------------+-----------------+---------------+-----------+------------+---------+
2 rows in set (0.00 sec)

Now, let’s try to add a few more rows to the existing database tables. We’ll use an INSERT query to add data to the table:

现在,让我们试着在现有的数据库表中增加几条记录。我们将使用一个INSERT查询来向表添加数据。

mysql> INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country) VALUES ('White Clover Markets', 'Karl Jablonski', '305 - 14th Ave. S. Suite 3B', 'Seattle', '98128', 'USA');
Query OK, 1 row affected (0.00 sec)

We have successfully inserted a new row in the restored table also. Congrats! Let’s see the result:

我们也成功地在恢复的表中插入了一条新行。祝贺你!让我们看看结果。

mysql> select * from Customers;
+----------------------+-----------------+-----------------------------+-----------+------------+---------+
| CustomerName         | ContactName     | Address                     | City      | PostalCode | Country |
+----------------------+-----------------+-----------------------------+-----------+------------+---------+
| Cardinal             | Tom B. Erichsen | Skagen 21                   | Stavanger | 4006       | Norway  |
| Wilman Kala          | Matti Karttunen | Keskuskatu 45               | Helsinki  | 21240      | Finland |
| White Clover Markets | Karl Jablonski  | 305 - 14th Ave. S. Suite 3B | Seattle   | 98128      | USA     |
+----------------------+-----------------+-----------------------------+-----------+------------+---------+
3 rows in set (0.00 sec)

Alternatively, the MySQL server container comes with the MySQL client installation. However, it can be used only within the container for any testing purposes. Now, let’s login to the Docker container and try to access the MySQL server using the default MySQL client.

另外,MySQL服务器容器与MySQL客户端安装一起。然而,它只能在容器内用于任何测试目的。现在,让我们登录到Docker容器并尝试使用默认的MySQL客户端访问MySQL服务器。

The docker exec command helps to login to the running container using the container id. The option -i keeps the STDIN open, and -t will allocate the pseudo-TTY, and finally, the /bin/bash at the end lands us in the BASH prompt:

docker exec命令有助于使用容器ID登录到运行中的容器。选项-i使STDIN保持开放,-t将分配伪TTY,最后,最后的/bin/bash使我们进入BASH提示。

# docker exec -it 9ce4da8eb682 /bin/bash
root@9ce4da8eb682:/# mysql -h localhost -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
...
... output truncated ...
...
mysql>

6. Conclusion

6.结论

In summary, we discussed the steps to bring up a MySQL server container using docker-compose. It also automatically restored the database and tables from the backup files. Further, we also accessed the restored data and performed some CRUD operations.

综上所述,我们讨论了使用docker-compose提起MySQL服务器容器的步骤。它还自动从备份文件中恢复了数据库和表。此外,我们还访问了恢复的数据并进行了一些CRUD操作。