在現代軟體架構中,將資料庫等有狀態服務進行容器化管理,已成為提升開發與維運效率的關鍵實踐。透過 Docker 部署 MySQL,不僅能確保開發、測試與生產環境的一致性,更能簡化繁瑣的安裝與設定流程,實現快速部署與彈性擴展。本文將深入探討此過程中的核心技術環節,從基礎的 Docker 環境整備與映像檔獲取開始,逐步引導至容器的啟動與配置。我們將特別聚焦於處理有狀態應用的兩大挑戰:如何利用 Docker 卷(Volume)機制實現數據的持久化,以及如何透過環境變數注入,對 MySQL 伺服器進行初始化設定,包含使用者權限與資料庫建立。此流程不僅是技術操作的展現,更是實現基礎設施即程式碼(IaC)理念的具體應用。
在 Docker 中部署 MySQL:環境準備與映像檔獲取
本節將引導您完成在 Docker 環境中部署 MySQL 數據庫的初始步驟,包括設置必要的軟體、連接到主機、啟動 Docker 服務,以及下載 MySQL 的官方 Docker 映像檔。
必要軟體與主機環境設定
要成功部署 MySQL 數據庫於 Docker 容器中,您需要以下條件:
- Docker Engine:確保您的主機上已安裝並運行 Docker。本範例中使用的 Docker Engine 版本為 1.8,但較新版本通常也能兼容。
- MySQL Docker 映像檔:我們將使用 Docker Hub 上官方提供的
mysql映像檔。 - 主機作業系統:我們將繼續使用 Amazon EC2 上的 Red Hat Enterprise Linux 7 作為 Docker 主機。
連線至 EC2 主機並啟動 Docker 服務
SSH 連線:使用您的私鑰 (
docker.pem) 連線到 Red Hat 7 EC2 實例。請將範例中的 IP 地址52.91.169.69替換為您實際的 EC2 公用 IP。ssh -i "docker.pem" ec2-user@52.91.169.69啟動 Docker 服務:登入後,執行以下命令來啟動 Docker 服務。
sudo service docker start驗證 Docker 服務狀態:確認 Docker 服務已成功啟動並運行。
sudo service docker status您應該會看到類似於「OK」的啟動確認訊息,並且在狀態檢查中,「Active」欄位顯示為「running」。
下載 MySQL Docker 映像檔
Docker Hub 提供了官方維護的 MySQL 映像檔,這是部署 MySQL 的推薦方式。
從 Docker Hub 下載映像檔: 執行以下命令來獲取
mysql映像檔的最新版本。sudo docker pull mysqlDocker 會從 Docker Hub 下載
mysql:latest映像檔。下載過程會顯示各個層級的進度,完成後您將在本地擁有該映像檔。列出本地 Docker 映像檔: 為了確認映像檔已成功下載,可以使用
docker images命令。sudo docker images在列出的映像檔列表中,您應該能看到
mysql映像檔,以及其標籤(通常是latest)和創建時間、大小等資訊。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100
object "使用者" as User
object "SSH Client" as SSHClient
object "EC2 Instance (RHEL 7)" as RHELInstance
object "Docker Service" as DockerService
object "Docker CLI" as DockerCLI
object "Docker Daemon" as DockerDaemon
object "Docker Hub" as DockerHub
object "Docker Image (mysql:latest)" as MySQLImage
partition "MySQL 容器化環境準備" {
User --> SSHClient : 準備私鑰 (docker.pem) 並輸入連線指令
SSHClient --> RHELInstance : 建立 SSH 連線 (ec2-user@<IP>)
RHELInstance --> SSHClient : 顯示終端提示符
User --> RHELInstance : 執行 sudo service docker start
DockerService --> RHELInstance : 啟動 Docker 服務並回傳狀態
User --> RHELInstance : 執行 sudo service docker status
DockerService --> RHELInstance : 回傳服務運行狀態 ("active (running)")
User --> DockerCLI : 執行 docker pull mysql
DockerCLI --> DockerDaemon : 請求下載映像檔
DockerDaemon --> DockerHub : 從 Docker Hub 獲取映像檔
DockerHub --> DockerDaemon : 提供映像檔數據
DockerDaemon --> User : 回傳下載進度與完成訊息
User --> DockerCLI : 執行 docker images
DockerCLI --> DockerDaemon : 請求列出本地映像檔
DockerDaemon --> User : 顯示映像檔列表 (含 mysql:latest)
}
@enduml看圖說話:
此圖示描繪了在 Docker 中部署 MySQL 的初始階段,即環境設置和映像檔的獲取。使用者首先透過 SSH Client 連線到 Amazon EC2 上的 Red Hat Enterprise Linux 7 實例,並確保 Docker 服務正在運行,若未運行則啟動它,然後驗證其狀態。接著,使用者利用 Docker CLI 執行 docker pull mysql 命令,指示 Docker Daemon 從 Docker Hub 下載官方的 MySQL 映像檔。Docker Daemon 負責與 Docker Hub 進行通信,下載映像檔的所有必要組件,並將其儲存到本地。最後,使用者執行 docker images 命令,Docker CLI 會查詢 Docker Daemon,列出本地所有可用的映像檔,使用者可以在列表中確認 mysql:latest 映像檔已成功下載。這個流程為後續啟動 MySQL 容器奠定了基礎。
在 Docker 中啟動 MySQL 伺服器:數據持久化與環境變數配置
本節將指導您如何啟動一個 MySQL 數據庫伺服器,並將其運行在 Docker 容器中。我們將重點關注數據的持久化策略以及如何通過環境變數來配置 MySQL 實例。
數據持久化策略
為了確保 MySQL 數據在容器重啟或刪除後不會丟失,我們需要將數據庫文件存儲在 Docker 卷(Volume)或主機目錄中。本範例將使用主機上的一個目錄來實現數據持久化。
創建數據目錄: 在主機上創建一個用於存儲 MySQL 數據的目錄。這裡我們選擇
/mysql/data。sudo mkdir -p /mysql/data-p選項確保如果父目錄不存在,也會一併創建。設置目錄權限: 為了讓 Docker 容器內的 MySQL 進程能夠讀寫該目錄,我們需要將其權限設置為全局可寫(777)。
sudo chmod -R 777 /mysql/data請注意,在生產環境中,權限設置為 777 可能存在安全風險,建議根據實際需求設置更精確的權限。
MySQL Docker 映像檔的環境變數配置
MySQL 的官方 Docker 映像檔支持通過環境變數來配置數據庫的初始狀態。以下是一些常用的環境變數及其作用:
MYSQL_ROOT_PASSWORD:必需。設置 MySQL 的root用戶的密碼。MYSQL_DATABASE:可選。指定在容器啟動時自動創建的數據庫名稱。MYSQL_USER和MYSQL_PASSWORD:可選。如果設置了其中一個,則必須同時設置另一個。這將創建一個新的數據庫使用者,並授予其在MYSQL_DATABASE指定的數據庫上的超級用戶權限。MYSQL_ALLOW_EMPTY_PASSWORD:可選。設置為yes時,允許root用戶擁有一個空密碼。這在開發和測試環境中可能有用,但強烈不建議在生產環境中使用。
啟動 MySQL 容器的 docker run 命令
我們將結合上述環境變數和數據持久化策略,使用 docker run 命令來啟動 MySQL 容器。
命令參數解析:
-v /mysql/data:/var/lib/mysql:這是數據持久化的關鍵。它將主機上的/mysql/data目錄掛載到容器內的/var/lib/mysql目錄。容器內的 MySQL 數據將被寫入到主機的/mysql/data中。--name mysqldb:為容器指定一個易於識別的名稱,方便後續管理。-d:以分離模式(detached mode)運行容器,即容器會在後台運行,不會阻塞當前終端。-e MYSQL_ROOT_PASSWORD='':設置root用戶的密碼為空。注意:在實際生產環境中,請務必設置一個強密碼!-e MYSQL_DATABASE='mysqldb':自動創建一個名為mysqldb的數據庫。-e MYSQL_USER='mysql':創建一個新用戶,用戶名為mysql。-e MYSQL_PASSWORD='mysql':設置新用戶mysql的密碼為mysql。同樣,生產環境請使用強密碼!-e MYSQL_ALLOW_EMPTY_PASSWORD='yes':允許root用戶密碼為空(與MYSQL_ROOT_PASSWORD=''結合使用)。
執行啟動命令:
sudo docker run -v /mysql/data:/var/lib/mysql --name mysqldb -d \ -e MYSQL_ROOT_PASSWORD='' \ -e MYSQL_DATABASE='mysqldb' \ -e MYSQL_USER='mysql' \ -e MYSQL_PASSWORD='mysql' \ -e MYSQL_ALLOW_EMPTY_PASSWORD='yes' \ mysql:latest執行此命令後,Docker 將會拉取
mysql:latest映像檔(如果本地不存在),然後創建並啟動一個名為mysqldb的 MySQL 容器。容器會在後台運行,並完成數據庫的初始化。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100
object "使用者" as User
object "Docker CLI" as DockerCLI
object "Docker Daemon" as DockerDaemon
object "Host Machine" as HostMachine
object "MySQL Container (mysqldb)" as MySQLContainer
object "MySQL Server" as MySQLServer
object "MySQL Data Directory (on Host)" as HostDataDir
object "MySQL Data Directory (in Container)" as ContainerDataDir
partition "啟動 MySQL 容器與數據持久化" {
User --> DockerCLI : 執行 mkdir -p /mysql/data
DockerCLI --> HostMachine : 創建目錄
User --> DockerCLI : 執行 chmod -R 777 /mysql/data
DockerCLI --> HostMachine : 設置目錄權限
User --> DockerCLI : 執行 docker run ... (包含 -v, --name, -d, -e)
DockerCLI --> DockerDaemon : 請求創建並運行容器
DockerDaemon --> HostMachine : 準備掛載點 /mysql/data
HostMachine --> HostDataDir : 創建並準備 /mysql/data
DockerDaemon --> ContainerDataDir : 創建容器內的 /var/lib/mysql
DockerDaemon --> HostDataDir : 建立主機數據目錄與容器數據目錄的映射 (-v /mysql/data:/var/lib/mysql)
DockerDaemon --> MySQLContainer : 創建名為 mysqldb 的容器
DockerDaemon --> MySQLContainer : 配置環境變數 (MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, etc.)
DockerDaemon --> MySQLContainer : 設定分離模式運行 (-d)
DockerDaemon --> MySQLContainer : 啟動 MySQL 映像檔 (mysql:latest)
MySQLContainer --> MySQLServer : 初始化 MySQL 伺服器
MySQLServer --> ContainerDataDir : 讀寫數據到容器內數據目錄
ContainerDataDir --> HostDataDir : 數據同步到主機上的 /mysql/data
MySQLServer --> User : 數據庫初始化完成
}
@enduml看圖說話:
此圖示詳細說明了如何啟動一個 MySQL Docker 容器,並確保數據的持久化。首先,使用者在主機上創建了一個名為 /mysql/data 的目錄,並將其權限設置為全局可寫(777),以確保容器內進程的訪問能力。接著,使用者透過 Docker CLI 執行 docker run 命令。此命令包含了幾個關鍵參數:-v /mysql/data:/var/lib/mysql 指示 Docker Daemon 將主機上的 /mysql/data 目錄掛載到容器內的 /var/lib/mysql(MySQL 的預設數據存儲路徑),從而實現數據持久化,確保容器刪除後數據不會丟失。--name mysqldb 為容器指定了易於識別的名稱。-d 使容器在後台運行。一系列 -e 選項用於配置 MySQL 伺服器,例如設置 root 密碼、自動創建 mysqldb 數據庫,以及創建一個名為 mysql 的用戶及其密碼。Docker Daemon 接收到這些指令後,創建 MySQL 容器,配置好環境變數,並啟動 MySQL Server 進程。MySQL Server 在運行時會將所有數據操作寫入到容器內的 /var/lib/mysql 目錄,由於該目錄已與主機上的 /mysql/data 目錄進行了映射,因此所有數據都會被同步並持久化到主機上。
縱觀現代應用部署的典範轉移,將 MySQL 這類關鍵的狀態型服務(stateful service)容器化,不僅是技術操作的演進,更反映了對基礎設施敏捷性與可塑性的深層次追求。此流程的核心價值,在於建立了標準化、可預測且與底層環境解耦的部署單元。
本文所展示的流程,從映像檔獲取到透過環境變數進行宣告式配置,再到利用掛載卷實現數據與應用生命週期的分離,完美體現了容器化思維的精髓。相較於傳統虛擬機或實體機部署,此模式顯著降低了環境差異引發的風險,並將部署時間從數小時縮短至數分鐘。然而,其挑戰在於管理者必須建立新的維運心智模型,例如對數據卷權限的精準控制(如文中所提 chmod 777 的權衡)以及對容器網路的深入理解,這些是從傳統 IT 思維轉向 DevOps 文化的關鍵突破點。
此部署單元看似基礎,實則是通往微服務架構、Kubernetes 自動化編排乃至無伺服器(Serverless)數據庫服務的基石。未來,基礎設施的管理將更趨向於「代碼化」與「自動化」,而這種將服務元件化的能力,將決定企業技術棧的演進速度。
玄貓認為,熟練掌握此容器化部署模式,不僅是技術能力的提升,更是管理者在雲原生時代,建構具備高韌性與快速迭代能力的技術團隊所不可或缺的策略視野。