database

Docker – 使用Docker一秒架MySQL

Docker是一個讓我越用越喜歡的東西,以往安裝MySQL要注意的東西很多,諸如使用的平台、平台版本、Port衝突等。

使用docker除了幫我解決上述問題以外,額外帶來的好處還有:

  1. 方便同時建立多個MySQL,利於多個不同專案開發
  2. 十個人用不同電腦建立開發環境,十個人都可以順利執行
  3. 幫助專案部署自動化,全部自動化涉及的觀念比教多,本篇文章專注在介紹建置MySQL的部分

這篇文章就以實務範例教你使用docker一秒架起MySQL,並且用docker-compose完成自動化。

執行

開始介紹docker指令之前,我們需要準備一些項目:

  1. 安裝docker desktop
  2. MySQL的docker image官方文件

按照官方文件的指令即可立即啟用mysql instance:

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

這行指令的意思:

  • 將docker container取名為「some-mysql」
  • 設定MySQL環境變數MYSQL_ROOT_PASSWORD為「my-secret-pw」
  • 指定一個tag作為MySQL版本,tag參照官網

特別要注意的是,不同MySQL版本在每個OS架構的支援度可能不同,例如我想要安裝mysql:5.7,執行以下指令:

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7

結果出現以下回應:

Unable to find image 'mysql:5.7' locally
5.7: Pulling from library/mysql
docker: no matching manifest for linux/arm64/v8 in the manifest list entries.

由於我沒有事先將mysql:5.7的image下載到主機上,docker在執行指令時會自動幫我將image抓下來,此時發生了OS架構不支援的問題(我的電腦是MacBook Air M1),從官網可以看到OS/ARCH為linux/amd64。

加上–platform解決並重新執行指令:

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw --platform linux/amd64 -d mysql:5.7

好了,按照官方提供的指令一秒就可以把MySQL跑起來,但實務上會發生一個問題,當我結束運行docker container之後,MySQL的資料全部都不見了!原因是因為預設都是把資料存在container內部,用以下指令檢查:

docker ps -s

可以發現這個container佔用的空間不斷長大:

CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                 NAMES        SIZE
8cd3159f6ed7   mysql:5.7   "docker-entrypoint.s…"   6 minutes ago   Up 6 minutes   3306/tcp, 33060/tcp   some-mysql   13.2kB (virtual 429MB)

為了解決這個問題,我們可以利用外掛儲存空間把資料存下來:

docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
  • -v代表掛上外部volume
  • MySQL在container內的資料都存在/var/lib/mysql,我們將資料掛載到本機位置/my/own/datadir

Docker Compose

工程師都很懶,一行一行輸入指令是一件很累人的事情,我們將以上流程寫到docker-compose.yml,讓docker-compose自動幫我們做完以上的所有流程:

version: '3.9'

services:
  mysql:
    container_name: softaverse-mysql
    image: mysql:5.7
    platform: linux/amd64
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    ports:
      - 7777:3306
    environment:
      - MYSQL_ROOT_PASSWORD=dockerdb
      - MYSQL_DATABASE=dockerdb
      - MYSQL_USER=dockerdb
      - MYSQL_PASSWORD=dockerdb
    volumes:
        - ./db-data:/var/lib/mysql
  • ./db-data是我本機上儲存資料的相對位置

我在docker-compose.yml加上了實務上我會使用到的設定,如何設定?有哪些設定?所有的內容全部都可以在image的官方文件找到,在這邊只是做個簡單範例提供給各位參考。

volume除了可以指定本機資料夾位置之外,我們還可以讓docker為我們建立volume:

docker volume create vol-name

透過指令可以查詢volume:

docker volume ls

輸出結果為:

DRIVER    VOLUME NAME
local     vol-name

修改docker-compose.yml使用另一種方式掛載外部資料夾到container內:

version: '3.9'

services:
  mysql:
    container_name: softaverse-mysql
    image: mysql:5.7
    platform: linux/amd64
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    ports:
      - 7777:3306
    environment:
      - MYSQL_ROOT_PASSWORD=dockerdb
      - MYSQL_DATABASE=dockerdb
      - MYSQL_USER=dockerdb
      - MYSQL_PASSWORD=dockerdb
    volumes:
        - db-data:/var/lib/mysql
volumes:
    db-data:
        name: softaverse_db-data

結論

這篇文章簡單紀錄了docker MySQL的運行方式,許多客製化的設定都是來自實務上的需求,實務上遇到問題的時候再去查閱官方文件找到相對應的設定方式即可,本篇提到的volume的概念以及docker-compose設定已經可以幫助實務上解決大部分的問題,更多細節設定請參考官方文件docker docs,希望本篇文章對大家有幫助!想看更多內容歡迎前往軟體工程筆記

喜歡運用科技工具提升工作效率、並自主開發實用小工具的長時間使用電腦工作者。對新科技工具深感興趣,樂於分享如何運用科技工具提升生活和工作效率的技巧。

發佈留言