使用Docker啟動MySQL數據庫
在本文中,將來學習如何使用Docker CLI和Docker compose啟動MySQL容器。

如果你正在開發需要數據存儲的應用程序,則MySQL是一種流行的SQL數據庫。以前從未使用過MySQL或數據庫都沒關系-本教程將學習并熟悉啟動Docker容器的過程。這些概念可以應用于應用程序所需的任何依賴項。
1、在Docker Hub上找到合適的MySQL映像
訪問Docker Hub,然后在搜索框中輸入以找到包含官方圖像的頁面: MySQL

Docker存儲庫提供一個或多個受支持的標簽,它們是映像的變體。通常,如果發行版使用語義版本控制,則標記將與應用程序的MAJOR.MINOR.PATCH編號匹配。
對于MySQL,可以從各種版本的5.6、5.7或8.0中進行選擇:
如果你選擇了一個精確的版本,比如8.0.22,MySQL的那個版本將永遠被安裝。
選擇主版本和副版本,比如8.0,將安裝副版本的最新版本。現在可能是8.0.22,明天變成8.0.23。
只選擇主版本,例如8,將安裝最新的主版本。現在可能是8.0.22,但下周可能變成8.1.0。
選擇latest(或不指定標簽)將安裝最新的版本,而不管版本是什么。現在可能是8.0.22,但下個月可能是9.0.0或更高版本。
對于本例,latest是一個很好的選擇,但是應該嘗試匹配生產服務器上的版本,或者選擇一個精確的版本,以便每個開發人員都使用相同的依賴項。Docker使得在任何時候測試數據庫升級都很容易。
2、啟動MySQL容器
通過在終端中輸入以下命令來啟動MySQL容器(Windows用戶:請刪除反斜杠和換行符):
docker run
-it --rm --name mysql
-p 3306:3306
--mount "src=mysqldata,target=/var/lib/mysql"
-e MYSQL_ROOT_PASSWORD=websecret
mysql
所有的Docker CLI命令都以Docker和一個指令開始,比如run后面跟著選項。docker run從一個指定的映像(mysql)創建一個容器并啟動它。如果該映像在主機上不可用,則下載該映像。
下載映像、啟動容器并在第一次運行時初始化MySQL可能需要幾分鐘的時間。隨后的運行幾乎是即時的。當看到以下內容時,即可使用該數據庫了:
[System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections.
docker run 提供了許多選項(請參閱附錄A),但是將使用的主要選項是:
-d:運行一個容器作為后臺進程(在應用程序結束時退出)-it:保持容器在前臺運行(即使在應用程序結束后),并顯示活動日志--rm :停止后取出容器--name:命名容器(否則使用隨機GUID)-p:將主機端口映射到容器端口--mount:創建一個持久的docker管理卷來保存數據。字符串指定一個src卷名和一個target,在容器的文件系統中裝入卷名-v:使用符號掛載主機文件夾:-e:定義環境變量--env-file:從文件中讀取環境變量,其中每行定義一個VAR=value--net:連接到特定的Docker網絡--entrypoint :覆蓋默認的啟動應用程序
如果不指定--rm,則容器即使停止后仍將保持可用。盡管重啟它是可能的,但幾乎沒有任何好處,因為再次執行docker run命令會更簡單。
MySQL的憑證
創建一個MySQL用戶是一個很好的做法,它被授予特定數據庫的有限權限,即它可以訪問數據,但不能改變表結構或檢查其他數據庫。這可以通過設置環境變量來實現(請參閱MySQL映像文檔)。
生產環境可以啟動自己的MySQL容器,因此使用具有所有權限的根用戶似乎不那么危險。然而,容器不是沙箱應用程序。被鎖定的用戶總是更安全。
為了簡潔起見,下面的示例使用
root,但是在開發和部署期間建議使用更安全的憑證。
3、使用MySQL客戶端連接到數據庫
一旦數據庫容器啟動,就可以使用安裝在主機上的任何MySQL客戶端應用程序以用戶ID root 和密碼websecret 連接到 localhost:3306。
如果你手頭沒有MySQL客戶端,Admineris是一個輕量級的基于php的選項。它也可以作為 Docker image ,在另一個終端中運行以下命令:
docker run
-it --rm --name adminer
-p 8080:8080
adminer
啟動后,在瀏覽器中打開 http://localhost:8080 并輸入MySQL登錄憑據:

注意,你不能使用localhost作為服務器名,因為Adminer將解析到它自己的容器!相反,可以:
-
輸入
host.docker.internal。Docker Desktop 將此域路由到你的PC的網絡IP地址,但它可能不是在所有系統上都可用。
-
使用實際的網絡IP地址。
這可以通過
macOS和Linux上的ifconfig命令或Windows上的ipconfig命令獲得。 -
或者使用Docker分配的容器的IP地址。
Docker創建了自己的虛擬網絡。docker inspect mysql返回JSON格式的容器信息。你可以找到IPAddress值使用-f格式選項:
docker inspect
-f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
mysql
4、連接到容器外殼
每個Docker容器都運行一個隔離的Linux環境。可以連接到其外殼以運行命令,檢查日志或執行任何其他活動。
記住容器是無狀態的!只要重新啟動容器,所做的任何更改都會丟失。
假設MySQL容器仍在運行,請打開另一個終端并輸入:
docker exec -it mysql bash
一些使用Alpine Linux的輕量級映像不提供bash shell。如果此命令失敗,嘗試使用docker exec -it mysql sh代替。
例如,可以訪問MySQL命令行并列出數據庫:
> mysql -u root -pwebsecret
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 9
Server version: 8.0.19 MySQL Community Server - GPL
Copyright (c) 2000, 2020, 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 'h' for help.
Type 'c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
mysql>
輸入 exit 退出
5、查看、停止、重啟容器
容器運行在交互模式(開始與-it開關)通常可以停止按 Ctrl | Cmd + C。
輸入以下內容可以查看正在運行的容器的列表:
docker container ls
docker container ls -a
或更短的:
docker ps
顯示活動容器的列表。這可能很寬-此處顯示了截短的版本:
CONTAINER ID IMAGE STATUS PORTS NAMES
ef3bab04fc8f adminer Up 16 mins 8080->8080/tcp adminer
793003e459e6 mysql Up 17 mins 3306->3306/tcp mysql
每個容器都被分配了一個十六進制ID,可以在Docker命令中用作引用。但是,指定容器--name可以大大簡化管理。
可以通過提供一個或多個名稱列表來重啟容器 docker container restart 。如果要刪除瀏覽器會話或臨時數據,這可能很有用:
docker container restart adminer mysql
你也可以 pause 和 unpause 例如,如果要測試應用程序對數據庫故障的反應,請運行容器:
docker container pause mysql
docker container unpause mysql
同樣,容器可以通過 docker container stop :
docker container stop adminer mysql
這些容器使用-rm選項啟動,因此在停止時將刪除它們。如果你不使用該選項(或遇到Docker問題),列出所有的容器:docker ps -a 停止的容器刪除可以使用:docker container prune
6、定義Docker網絡
使用IP地址在容器之間進行通信可能很困難。啟動容器后,會在默認的Docker網絡上為其分配IP地址,但是在以后的啟動中可以更改。
docker run有--ip和--ip6選項,所以你可以定義一個固定的ip,但通常使用 --name 引用另一個容器更容易。這可以通過創建自己的Docker網絡來實現。
停止所有正在運行的容器,然后創建一個新的網絡,例如在這里命名為mysqlnet:
docker network create --driver bridge mysqlnet
啟動時,任何容器都可以使用--net選項連接到該網絡。 MySQL示例:
docker run
-d --rm --name mysql
-p 3306:3306
--mount "src=mysqldata,target=/var/lib/mysql"
-e MYSQL_ROOT_PASSWORD=websecret
--net mysqlnet
mysql
Adminer:
docker run
-d --rm --name adminer
-p 8080:8080
--net mysqlnet
adminer
現在,每個容器的名稱都在Docker mysqlnet 網絡上解析。因此,可以在Adminer登錄屏幕上輸入mysql作為服務器名稱。
7、清理
Docker會占用大量磁盤空間!可通過輸入以下信息獲得可怕的使用情況統計信息
docker system df
要查看所有正在運行和已停止的容器,請輸入:
docker container ls -a
請注意,容器通常很小,因為它們是無狀態的并且從特定映像啟動。
要查看所有活動圖像和懸空映像(與容器無關的映像),請輸入:
docker image ls -a
要查看所有Docker管理的磁盤卷,請輸入:
docker volume ls
要查看所有Docker網絡,請輸入:
docker network ls
僅使用MySQL和Adminer,將使用近1GB的空間。隨著開始使用其他依賴項并創建自己的映像,這一點將進一步提高。
通過將容器名稱添加到命令來停止容器: stop
docker container stop adminer mysql
可以使用以下方法刪除所有停止的容器,未使用的網絡和懸掛的映像:
docker system prune
這是安全的,并且經常運行可能是一個好主意。
以下命令將執行相同的操作,并擦除與運行中的容器無關的任何映像:
docker system prune -a
7.1 刪除磁盤卷
刪除Docker卷將永久擦除其數據!就沒有回頭路了。
如果要開發數據庫驅動的應用程序,通常可以保留一個或多個數據轉儲,這些數據轉儲可用于在各種狀態下重新創建數據庫。大多數MySQL客戶端工具都提供轉儲或導出功能,例如Adminer中的Export鏈接。
另外,隨MySQL提供的mysqldump實用程序可以通過附加到容器shell或使用docker exec命令來運行。
使用root將名為mydb的數據庫備份到名為backup.sql文件。
Linux或macOS上的MySQL憑證,請使用:
docker exec mysql /usr/bin/mysqldump -u root -pwebsecret mydb
> backup.sql
Windows PowerShell:
docker exec mysql /usr/bin/mysqldump -u root -pwebsecret -r mydb |
Set-Content backup.sql
假設愿意繼續,可以使用以下方法查看Docker卷:
docker volume ls
然后按ID或名稱刪除任何內容:
docker volume rm
可以使用以下方法刪除未使用的Docker卷-當前未連接到正在運行的容器的那些卷:
docker volume prune
7.2 完全干凈的啟動
可以使用以下方法擦除每個未使用的容器,圖像,卷和網絡:
docker system prune -a --volumes
如果您想在沒有確認提示的情況下強制擦除,請添加-f。
8、使用Docker Compose啟動多個容器
單獨啟動Docker容器并不有趣——尤其是當命令很長且難以記憶時。幸運的是,Docker Compose提供了一種從名為docker-compose.yml單個配置文件構建和啟動容器、網絡和卷的方法。
YAML不是標記語言:是一種常用的、緊湊的數據格式,通常用于配置目的。它使用了新的行和制表符,而不是JSON喜歡的引號和括號。
Docker Compose提供了許多配置選項([參見附錄C](https://docs.docker.com/compose/compose-file/),但一個示例是說明常見設置的最佳方式。下面是一個示例:docker-compose.yml
version: '3'
services:
mysql:
image: mysql
container_name: mysql
environment:
- MYSQL_ROOT_PASSWORD=websecret
volumes:
- mysqldata:/var/lib/mysql
ports:
- "3306:3306"
networks:
- mysqlnet
restart: on-failure
adminer:
image: adminer
container_name: adminer
depends_on:
- mysql
ports:
- "8080:8080"
networks:
- mysqlnet
restart: on-failure
volumes:
mysqldata:
networks:
mysqlnet:
這將創建與上面使用的docker run命令相同的容器,并在底部列出volumes和networks。它還定義了兩個新設置:
-
depends_on啟動依賴項:adminer 將在MySQL啟動后啟動 -
restarton-failure:容器以退出代碼停止時會自動重新啟動。
如果尚未停止現有容器,請立即執行以下操作:
docker container stop adminer mysql
docker system prune
在使用以下命令從與docker-compose.yml文件相同的目錄中啟動Docker Compose:
docker-compose up
如有必要,將下載mysql和adminer映像并啟動兩個容器。默認情況下,docker-compose作為前臺任務運行,并顯示所有容器活動的日志。當您看到以下內容時,即可使用MySQL:
mysql | ... [Server] X Plugin ready for connections.
現在可以在http://localhost:8080/上啟動Adminer并使用用戶ID root和密碼 websecret連接到MySQL服務器。
指定單個端口值僅會暴露網絡中的端口,例如
ports:
- "3306"
在這種情況下,盡管Adminer仍可以與內部網絡上的mysql:3306通信,但主機無法訪問MySQL。
可以像以前一樣使用服務并連接到它們的外殼。容器將繼續運行,直到您在啟動docker-compose的終端中按Ctrl | Cmd + C為止。
從現在開始,將盡可能使用docker-compose。很少需要輸入單獨的docker命令,但是知道它們可用是很有用的,尤其是因為Docker Compose可能并非在每個系統上都可用。