如何在Mysql的Docker容器啟動時初始化資料庫

2021-02-21 碼農小胖哥
1. 前言

Docker在開發中使用的越來越多了,最近搞了一個Spring Boot應用,為了方便部署將Mysql也放在Docker中運行。那麼怎麼初始化 SQL腳本以及數據呢?

我這裡有兩個傳統方案。第一種方案是在容器啟動後手動導入,太 low 了不行。第二種在Spring Boot客戶端連接Mysql容器時初始化資料庫,你可以參考使用 flyway 進行資料庫版本控制一文,但是這依賴客戶端的能力。能不能做到Mysql容器啟動時就自己初始化資料庫呢?當然可以!今天就來演示一下。全部代碼見文末

2.原理

Mysql容器首次啟動時,會在 /docker-entrypoint-initdb.d目錄下掃描 .sh,.sql,.sql.gz類型的文件。如果這些類型的文件存在,將執行它們來初始化一個資料庫。這些文件會按照字母的順序執行。默認情況下它們會初始化在啟動容器時聲明的 MYSQL_DATABASE變量中的資料庫中,例如下面的命令會初始化一個REGION_DB 資料庫:

$ docker run --name some-mysql -e MYSQL_DATABASE=REGION_DB -d mysql:tag

如果你的啟動命令沒有指定資料庫那麼就必須在資料庫 DDL 腳本中聲明並指定使用該資料庫。否則就會實現下面的異常:

ERROR 1046 (3D000) at line 7: No database selected

那麼接下來我們將利用這一機制來實現Docker容器啟動時初始化資料庫。

3.自定義 Dockerfile

我們編寫自己的Dockerfile來實現我們的需求,這裡以 Mysql:5.7 為例。不同的版本可能有一定的出入,需要詳細去閱讀官方文檔。腳本如下:

FROM mysql:5.7
LABEL OG=felord.cn
COPY utf8mb4.cnf /etc/mysql/conf.d/utf8mb4.cnf
COPY ./sql  /tmp/sql
RUN mv /tmp/sql/*.sql /docker-entrypoint-initdb.d
RUN rm -rf /tmp/sql

第一步,引入官方 Mysql:5.7 Docker 鏡像。第三步,很重要!本來我沒有配置第三行,結果運行容器後發現初始化數據的中文全部亂碼了。所以需要在初始化資料庫前修改Mysql的編碼等配置,這裡我順便把時區也改為了+8:00。第四步,複製包含資料庫腳本的 ./sql文件夾到鏡像的/tmp/sql下。第五步,使用 mv 命令把第四步拷貝的文件夾下的所有.sql文件複製到 /docker-entrypoint-initdb.d下,這樣才能利用2.章節的機制進行初始化資料庫。

然後你可以通過構建鏡像命令構建自定義的 Mysql 鏡像:

# 一定不要忘記最後的一個 . 點
docker build -t mysql:5.7c .

通過mysql:5.7c鏡像啟動一個名稱為mysql-service的容器,root密碼為123456,並持久化數據到宿主機 D:/mysql/data下:

docker run --name mysql-service -v d:/mysql/data:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7c

小貼士:你可以通過 SHOW VARIABLES LIKE 'character%' 查看字符集是否更改為utf8mb4,也可以通過SHOW VARIABLES LIKE '%time_zone%' 查看時區是否是東八區。

4. 總結

今天我們自定義一個可以執行初始化資料庫的Mysql鏡像,方便我們進行部署。你也可以參考這個思路來定製其它一些自己需要的Docker鏡像。本文的完整Demo可以通過關注公眾號:Felordcn 回復 mysqldocker 獲取。

往期推薦:



相關焦點

  • Win10下安裝Docker集成Mysql(一)
    查看完版本信息後,下面需要執行命令來運行mysql資料庫##########mysql資料庫安裝##########(2)--restart=always:能夠使我們在重啟docker時,自動啟動相關容器。(3)--privileged=true:docker應用容器獲取宿主機root權限。(4)--name:運行啟動後的容器名稱。(5)-e MYSQL_ROOT_PASSWORD:mysql密碼。(6)-d:後臺運行容器,並返回容器ID。
  • 基於docker的mysql部署
    資料庫mysql,相信對於研發人員來說都不陌生,特別是後臺應用,mysql更是基石,因此本文將為大家簡單介紹mysql的容器化安裝。   創建容器,啟動mysqldocker run  創建完成之後我們通過以下命令來查看容器狀態,可以看到容器已經啟動。
  • Docker精髓講解(容器數據卷、Dockerfile、Docker網絡)
    測試1、你可以先將容器停止2、修改虛擬機上的掛載目錄3、使用docker ps -a查看剛停止的容器4、啟動容器docker start  容器id5.2、我們在把mysql容器個刪除了,看數據是否還能夠保存。
  • docker容器操作命令:目錄掛載與安裝MySQL容器詳解
    docker容器操作命令:目錄掛載(卷Volume)docker容器操作命令:目錄掛載(卷Volume)目標掌握目錄掛載命令,其實就是==目錄映射==share/nginx/html nginx查看IP和相關的安裝信息和目錄docker inspect [容器名|容器ID]> docker inspect tomcat> docker inspect nginx
  • 白話Docker——docker run及docker-compose
    白話Docker—docker run及docker-compose        前面介紹了用Dockerfile來製作鏡像,本篇將用最直白的文字來介紹,如何運行鏡像。        用docker運行鏡像時,會根據鏡像來創建一個容器。
  • docker4dotnet #3 在macOS上使用VSC和Docker開發asp.net core+mysql應用
    創建mysql容器作為開發資料庫資料庫的開發一般會要求我們先安裝一個資料庫引擎在自己的機器上,現在使用docker,我們可以在容器中運行一個資料庫引擎。首先通過以下命令將docker命令重定向到這臺主機中eval $(docker-machine env {machine-name})運行以下命令啟動一臺mysql資料庫容器,創建一個叫做
  • 【mycat系列一】基於 Docker 搭建 MySQL 主從複製的詳細教程
    1、安裝dockeryum install docker2、安裝成功啟動Docker後,查看版本docker version4、使用此鏡像啟動容器,這裡需要分別啟動一主兩從3個容器一主兩從:分別執行以下3條指令docker run -p 3307:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD
  • Docker MySQL 使用
    容器是完全使用沙箱機制,相互之間不會有任何接口(類似 iPhone 的 app),更重要的是容器性能開銷極低。不管是在Linux還是windows上面都可以使用docker,windows用戶可以下載 Docker Desktop[2],像軟體一樣開啟docker服務。
  • Docker+Flask+Gunicorn上線項目
    因為我的項目不是國際化項目,所以我的解決方法很簡單,直接在啟動容器時指定時區則可,具體命令如下。問題2:如何在docker容器中看見列印數據因為一開始沒有意識到時區問題,所以我需要一些信息來幫助我判斷為何程序構建成docker容器後,某些接口的功能就報錯了。
  • Docker容器和K8s添加Health Check
    lib官方health check示例K8s中的健康檢查Container ExecHTTP Health CheckTCP Socketreadiness 檢查實例參考docker容器啟動後,怎麼確認容器運行正常,怎麼確認可以對外提供服務了,這就需要health check功能了。
  • Docker系列文章--操作容器
    ps -q001bf3cf82d62、創建啟動容器    2.1、啟動容器的兩種方式        2.1.1、新建容器並啟動這種啟動方式為基於鏡像新建一個容器並啟動,所需要的命令主要為docker run,相當於先執行docker
  • Docker下MySQL的安裝
    概述本文講述了如何利用Docker去安裝MySQL,以及MySQL自定義配置文件的相關設置。其中mysql-latest是執行運行命令時創建的別名,同時使用mysql測試連接:mysql -u root -p輸入環境變量傳遞的root密碼後就可以連接上MySQL了:
  • 基於 Docker 搭建 MySQL 主從複製
    搭建環境Centos 7.2 64位MySQL 5.7.13Docker 1.13.1接下來,我們將會在一臺伺服器上安裝docker,並使用docker運行三個MySQL容器,分別為一主兩從。安裝docker執行命令
  • Docker進階專題-架構及啟動原理
    GraphDB圖資料庫。用於記錄Docker Daemon中維護的所有容器(對應圖資料庫中的節點)以及容器間的Link關係(對應圖資料庫中的邊)。 DriverDocker Daemon將用戶請求轉化為系統調用後,用系統調用來創建進程,從而創建和管理容器。將這些系統調用抽象成統一接口,就成了Driver。
  • 一文精通雲服務安裝JDK11/Mysql/Nginx/Docker/Compose/Node/Git/Rocketmq容器編排
    docker info啟動使用Dockersystemctl start docker #運行Docker守護進程systemctl stop docker #停止Docker守護進程systemctl restart docker #重啟Docker守護進程一個命令部署Nginxdocker run --rm --name nginx-xdclass
  • ​Docker容器化Jenkins+碼雲+Docker+華為鏡像容器實現CI/CD
    不知道是不是自己下的鏡像版本的問題,jenkins容器起起來以後沒有jdk運行環境。使用docker 掛載數據卷的方式蹭宿主機的jdk來用,見下面的一長串啟動命令配置。個人不是很熟悉 docker-compose,所以本篇基本都是docker 原生命令。
  • docker學習6-docker-compose容器集群編排
    前言實際工作中我們部署一個應用,一般不僅僅只有一個容器,可能會涉及到多個,比如用到資料庫,中間件MQ,web前端和後端服務,等多個容器。
  • 使用Docker構建安全的虛擬空間
    而資料庫則可以單獨構建一個 mysql 容器,為每個用戶分配一個 user&database,讓用戶和空間容器來遠程連接。配置資料庫:1. 網絡:要讓虛擬空間的容器能夠遠程連接資料庫,首先要使容器之間在一個網段,那麼我們就需要設置一個橋接模式的 docker network,我這裡使用 172.22.0.0/16 這個網段。
  • 如何用Docker實現PHP命令行程序的CI/CD
    為了確保應用程式容器和資料庫容器已啟動,可以看到codeship-steps.yml文件調用了一個尚未創建的shell腳本。若資料庫遷移,說明測試通過。把腳本放在./docker/codeship-run.sh,內容如下:#!
  • 自己動手創建 Docker 鏡像並分享到鏡像倉庫,容器引擎的用途越來越廣泛!
    對於Docker安裝普通鏡像來說:就是Docker本身是分層下載鏡像,所以可以提取出公共層鏡像,進行復用Docker鏡像的特點Docker鏡像都是只讀的,當容器啟動時,一個新的可寫層加載到鏡像的頂部這一層就是我們通常說的容器層,容器之下的都叫鏡像層Commit鏡像# 提交本地鏡像  # -a:作者信息