設置和運行 MySQL 容器
一、概述
容器因其諸多優勢而成為 IT 行業最熱門的話題。組織正在以驚人的速度為其業務採用基於容器的解決方案。 據 451 Research稱,未來幾年應用容器市場將增長四倍。
今天,我們甚至擁有諸如 MySQL、MongoDB、PostgreSQL 等容器化形式的數據庫。但是,本文將探討設置和運行 MySQL 容器的選項。首先,我們將備份現有的 MySQL 數據庫。接下來,我們將以 YAML 形式構建一個容器配置,並使用docker-compose
運行它,這是一個開源工具包,用於將一堆應用程序容器組合在一起。
事不宜遲,讓我們深入了解它的細節。
2. 構建 MySQL 容器配置
在本節中,我們將使用docker-compose
工具構建 MySQL 容器。但是,YAML 也使用 Dockerfile 中的圖像作為當前路徑中的基本配置。
2.1。碼頭工人撰寫
首先,讓我們創建帶有version
和services
標籤的 YAML 文件。我們在 YAML 文件的version
標籤下定義文件格式版本。 MySQL 服務使用我們在上下文中定義的 Dockerfile 中的圖像信息。
此外,我們還指示該工具使用在.env
文件中定義為環境變量的默認參數。最後, ports
標籤將綁定容器和主機端口 3306。讓我們看看我們用來啟動 MySQL 服務的docker-compose
YAML 文件的內容:
# 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 創建
在內部,docker 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
現在,讓我們看一下以下 Dockerfile 片段中給出的所有指令:
-
FROM
– 一個有效的 Dockerfile 以FROM
語句開頭,它描述了鏡像名稱和version
標籤。在我們的例子中,我們使用帶有latest
標籤的mysql
鏡像。 -
MAINTAINER
– 將作者信息設置為通過docker inspect
可見的容器元數據。 -
RUN
– 在mysql
映像之上執行命令,隨後形成一個新層。生成的鏡像被提交並用於 Dockerfile 中定義的後續步驟。 -
ARG
– 在構建期間傳遞變量。在這裡,我們傳遞了四個用戶變量作為構建參數。 -
ENV
我們使用$
符號來表示 Dockerfile 中的環境變量。在上面的代碼片段中,我們使用了四個變量。 -
ADD
- 在構建期間,它將文件添加到容器中以供將來使用。 -
EXPOSE
– 使服務在 Docker 容器之外可用。
2.3.設置環境
此外,我們可以在當前路徑中創建一個環境變量文件為.env
。此文件包含撰寫文件中涉及的所有變量:
# cat .env
MYSQL_DATABASE=my_db_name
MYSQL_USER=baeldung
MYSQL_PASSWORD=pass
MYSQL_ROOT_PASSWORD=pass
MYSQL_PORT=3306
2.4. MySQL 備份文件
為了演示,讓我們從現有的數據庫表中進行備份。在這裡,我們通過data.sql
文件自動將相同的Customers
表導入到我們的 MySQL 容器中。
下面,我們使用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)
作為 MySQL RDBMS 包的一部分, mysqldump
實用程序用於將數據庫中的所有數據備份到文本文件中。使用帶有內聯參數的簡單命令,我們可以快速備份 MySQL 表:
- -u:MySQL用戶名
- -p:MySQL 密碼
# mysqldump -u [user name] –p [password] [database_name] > [dumpfilename.sql]
# mysqldump -u root -p my_db_name > data.sql
Enter password:
在較高級別上,備份文件將刪除所選數據庫中名為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
但是,數據庫的創建或刪除不在創建的轉儲文件中進行管理。我們將在data.sql
文件中添加以下代碼段,如果數據庫不存在,它將創建數據庫。它通過管理數據庫和表來完成循環。最後,它還通過USE
命令使用創建的數據庫:
--
-- Create a database using `MYSQL_DATABASE` placeholder
--
CREATE DATABASE IF NOT EXISTS `MYSQL_DATABASE`;
USE `MYSQL_DATABASE`;
目前,目錄結構如下:
# tree -a
.
├── data.sql
├── docker-compose.yml
├── Dockerfile
└── .env
3. 啟動 MySQL 服務器容器
現在,我們都準備好通過docker-compose
啟動一個容器了。要啟動 MySQL 容器,我們需要執行docker-compose up
。
當我們瀏覽輸出行時,我們可以看到它們在 MySQL 映像之上的每個步驟中形成了新層。
隨後,它還會創建數據庫並加載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 ...
...
我們可以使用-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 客戶端準備
必須安裝客戶端才能輕鬆訪問 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 ...
...
現在,讓我們提取MySQL客戶端的安裝路徑和版本:
$ which mysql
/usr/bin/mysql
$ mysql --version
mysql Ver 14.14 Distrib 5.7.37, for Linux (x86_64) using EditLine wrapper
5.服務器客戶端通信
我們可以使用客戶端應用程序訪問已部署的 MySQL 服務器。在本節中,我們將看到如何通過客戶端訪問 MySQL 服務器。
讓我們使用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
接下來,讓我們使用已安裝的客戶端服務獲取容器 IP 地址以訪問數據庫。如果我們發出docker inspect
命令,我們將以 JSON 格式看到有關容器的詳細信息。我們還可以從生成的 JSON 中選擇任何字段。在這裡,我們從range.NetworkSettings.Networks -> IPAddress
獲取 IP 地址:
# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 9ce4da8eb682
172.19.0.2
然後我們可以使用客戶端使用配置的主機和端口信息登錄到 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
在這裡,我們可以看到數據是從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)
現在,讓我們嘗試在現有數據庫表中添加更多行。我們將使用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)
我們也成功地在恢復的表中插入了一個新行。恭喜!讓我們看看結果:
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)
或者,MySQL 服務器容器隨 MySQL 客戶端安裝一起提供。但是,它只能在容器內用於任何測試目的。現在,讓我們登錄到 Docker 容器並嘗試使用默認的 MySQL 客戶端訪問 MySQL 服務器。
docker exec
命令有助於使用容器 id 登錄到正在運行的容器。選項-i
使 STDIN 保持打開狀態,而-t
將分配偽 TTY,最後,最後的/bin/bash
使我們進入 BASH 提示符:
# docker exec -it 9ce4da8eb682 /bin/bash
[email protected]:/# mysql -h localhost -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
...
... output truncated ...
...
mysql>
六,結論
總之,我們討論了使用docker-compose
啟動 MySQL 服務器容器的步驟。它還自動從備份文件中恢復數據庫和表。此外,我們還訪問了恢復的數據並執行了一些 CRUD 操作。