Laradock與MySQL Container的操作
Laradock如何利用sql檔建立或更新MySQL資料庫
最近打算把以前寫的Projects從CI(CodeIgniter)移植到Laravel,因此開始學習Laravel,順便研究怎麼在Docker上安裝Laravel 。本篇分享:
1.如何在Laradock下執行需要的SQL file
2.如何將資料庫連線資訊從SQL file中抽離,並由.env統一管理
3.疑難排解與相關參數設定
0.Edit SQL File
編輯SQL File
laradock預設會在MySQL容器建立完成時執行laradock/mysql/docker-entrypoint-initdb.d/l目錄下的createdb.sql,通常我們只要在這裏插入需要的SQL就可以了。
#檔案位置:laradock/mysql/docker-entrypoint-initdb.d/createdb.sql# Copy createdb.sql.example to createdb.sql
# then uncomment then set database name and username to create you need databases#
# example: .env MYSQL_USER=appuser and needed db name is myshop_db
#
# CREATE DATABASE IF NOT EXISTS `myshop_db` ;
# GRANT ALL ON `myshop_db`.* TO 'appuser'@'%' ;...(省略)
不過預設的方法必須在createdb.sql中留下資料庫名稱、使用者名稱,甚至需要建立使用者與密碼,而這些資料已經紀錄在.env的環境參數裡了。
我們其實可以寫一個shell script,直接抓環境參數去做建立資料庫與使用者、操作授權等行為,讓createdb.sql單純做sql import的動作,這樣日後在維護上可以有幾個效益:
- 資料庫連線資訊統一由.env管理,不會分散四處,造成修改的麻煩。
- 日後資料庫更新時,直接將dump出來的sql檔作為createdb.sql即可,不需要額外撰寫sql檔,開發人員在部署時更加便捷。
所以我在docker-entrypoint-initdb.d下,建立一個database-loader.sh:
#檔案位置:/docker-entrypoint-initdb.d/database-loader.sh
while !(mysqladmin -u $MYSQL_USER -p$MYSQL_PASSWORD ping)
do
sleep 3
echo "waiting for mysql ..."
done
echo "starting the main script"#create database
mysql -u root -p$MYSQL_ROOT_PASSWORD -e " CREATE USER $(echo \'$MYSQL_USER\')@'localhost' IDENTIFIED BY $(echo \'$MYSQL_PASSWORD\') ; FLUSH PRIVILEGES ; "#create database user
mysql -u root -p$MYSQL_ROOT_PASSWORD -e "CREATE DATABASE IF NOT EXISTS $(echo '`'$MYSQL_USER'`') CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_bin' ;FLUSH PRIVILEGES ; "#import sql file
mysql $MYSQL_DATABASE -u root -p$MYSQL_ROOT_PASSWORD < /docker-entrypoint-initdb.d/createdb.sql
接著修改Dockerfile,讓mysql container建立時,去執行database-loader.sh:
ARG MYSQL_VERSION=latest
FROM mysql:${MYSQL_VERSION}LABEL maintainer="Mahmoud Zalt <mahmoud@zalt.me>"#####################################
# Set Timezone
#####################################ARG TZ=UTC
ENV TZ ${TZ}
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && chown -R mysql:root /var/lib/mysql/COPY my.cnf /etc/mysql/conf.d/my.cnfCMD ["mysqld"]COPY docker-entrypoint-initdb.d/database-loader.sh /database-loader.sh
RUN nohup /database-loader.sh > /dev/null 2>&1 &EXPOSE 3306
1.Remove Old Databse
移除舊的資料庫
匯入新的SQL,必須先將原本的資料庫檔清空,查詢.env檔中的DATA_PATH_HOST所設定的目錄:
DATA_PATH_HOST=~/.laradock/data
到指定的目錄底下將mysql資料夾刪除(若第一次建立可跳過此步驟):
2.Recreate MySQL Container
重新建立與啟動MySQL容器
執行以下指令:
docker volume rm laradock_mysql && docker-compose up -d --build --force-recreate --renew-anon-volumes mysql
3.Check MySQL Container
檢查MySQL 是否正確啟動
執行以下指令,確定MySQL Service顯示ready for connections:
docker logs $(docker ps -aqf "name=laradock_mysql")
如果沒有正常啟動,可以從log中看到出錯的原因,最容易發生的問題通常是sql語法問題:
有時候,我們得進入到容器裡去查看更詳細的資訊,可使用以下指令:
docker exec -it $(docker ps -aqf "name=laradock_mysql") bash
4.Modify Configuration Files
修改設定檔
如果資料庫中的資料編碼有問題,可能需要設定my.cnf檔
#檔案位置:mysql/my.cnf
# The MySQL Client configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html[mysql]
default-character-set=utf8mb4
[mysqld]
sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8[client]
default-character-set=utf8mb4
或者在createdb.sql中加入字元集設定:
SET CHARACTER_SET_CLIENT=utf8mb4;
SET CHARACTER_SET_RESULTS=utf8mb4;
SET CHARACTER_SET_database= utf8;
SET COLLATION_CONNECTION=utf8_unicode_ci;
結語
本篇分享:
- 如何在Laradock下執行需要的SQL file
- 如何將資料庫連線資訊從SQL file中抽離,並由.env統一管理
- 疑難排解與相關參數設定
我是James,艾菲肯數位科技創辦人/成功大學製造資訊與系統所碩士/13年經驗的軟體工程師對於軟體開發與接案工作充滿熱忱,有閒沒錢時喜歡攝影與閱讀,有錢有閒時喜歡旅遊,截至2019年,已累積13年的經驗在軟體工程領域、7年的接案經驗FB粉絲頁:艾菲肯數位科技——您最佳的技術夥伴
個人刊物 :詹姆士的咖啡時間
艾菲肯數位科技官網:Efacani.com
Instagram:https://www.instagram.com/s870018/