2024-03-24

[Windows] docker desktop 4.26.0 開始會遇到 container 在啟動後維持了一定時間(大概30分鐘)時,外部host就無法對該容器進行操作

先說明,這有可能只是在下自己遇到的情況…

就是,某天在下 Windows 11 當時使用的 docker desktop 是在 4.25.0 然後更新到 4.26.0 時發生了一些奇怪的問題…

先說明在未更新前的環境

os: win11

cpu: amd ryzen 2700x

ram: 2 * 16G

app: docker desktop 4.25.0

containers: ubuntu 20.04 lts(內裝了 apache, php, mysql, phpmyadmin)

因為我大部份進行開發都是在公司上班時用工作機(筆電),當時工作機的 docker desktop 是更新到 4.25.2,家裡的桌機主要是為了在家工作時可以拿來開發,所以平時 docker desktop 我是不太會去更新

然後就有天看到有提醒有新版本 4.26.0 可以更新,我也沒想太多,就進行動作,然後更新完就把 docker desktop 關掉了,也沒去留意。

直到有天是公司 pm 告知客戶有反應前次更新有一些狀況,問我能不能先在家更新,更新完再來上班,我想說也行,就在30分鐘內完成了修正然後 hotfix 到客戶端去,正準備結束時就不知道為啥就按到了系統頁面的重新整理,結果發現一直在 loading…

2024-03-23

docker-compose 在 windows 環境該如何在 volumns 中設定掛載外部路徑

在 docker run 建立 container 的指令中,可以用 "-v {host-path}:{container-host-path}" 的方式來掛載主機路徑(host-path)至容器路徑(container-host-path)。

而主機路徑可以直接用絕對路徑的寫法,像 "-v D:\abc:/var/www/html"...

但,這方式在 docker-compose.yml 的 volumns 中這樣寫雖然不會報錯,但容器路徑 /var/www/html 卻會是空的,我假設 docker-compose.yml 中是這樣寫的(容器路徑我是假設的)
volumns:
  - "D:\abc:/var/www/html"
  - "./def:/var/www/html2"

"./def" 是以 docker-compose.yml 這個檔案的路徑開始中的 def 資料匣

我假定在 D:\abc 和 def 中都放了一個 index.html,在 container 啟動後,實際到 /var/www/html 路徑下查看,會發現是空的…而到 /var/www/html2 中查看則會有看到 index.html

在下試過很多寫法,但好像都無法掛載不是跟 docker-compose.yml 同路徑的其他路徑…但後來在 google 搜尋之後,發現了狀況,要掛載非 docker-compose.yml 同路徑的其他路徑,除了要寫絕對路徑的寫法外,寫法要改成

//{Disk drive}/path

例如: D:\abc 的掛載就要寫成

- "//d/abc:/var/www/html"

如此就能正常掛載到想要的外部路徑

註: 我自己後來把 docker desktop 在「用/不用 WSL」切換來切換去,有發現似乎「//d/abc」的這個方式是在「用 WSL」的情境下才有支援,「不用 WSL」的情境下還是要使用「D:\abc」的寫法,供大家參考

MySQL: ERROR...Aborted connection...to db: unconnected user:... host:... (init_connect command failed)... MySQL server has gone away!!

呃,沒錯,mysql 又遇坑了

不過遇上的前因是…我在把 apache, mysql, php-fpm, phpmyadmin 利用 docker 來運行在各自專屬的 container 上時,在 phpmyadmin 登入後所出現的訊息

因為這作法我沒有特別在 mysql 的 container 中去指定我自己優化的 mysql.cnf,而是改用 command 的命令加載去啟動的,所以我在 docker-compose.yml 中,mysql 的 command 的部份我有用到

command: [

...,

'--init_connect="SET NAMES utf8mb4"',

'--init_connect="SET collation_connection = utf8mb4_unicode_ci"'

]

然後 docker-compose up 的過程是沒什麼問題,當用 phpmyadmin 登入時就會看到頁面直接出現跟本篇標題差不多的文字,然後資料庫選單沒出現,重整網頁後也只是跳回登入,再次登比也是一樣。

這時我就直接進入 mysql container 內,直接用指令的方式登入

mysql -u {username} -p

剛登入是沒什麼異狀,但要求展示資料庫列表( show databases; )時就出現跟 phpmyadmin 登入時看到的異常訊息是一樣的( 註: 如果直接以高權限的帳戶登入,像 root 反而一切都很正常,沒有異常訊息 )

因為訊息中有提到 "init_connect command failed",所以先把 init_connect 的資料列出來看看

SHOW VARIABLES LIKE '%init_connect';

其結果為

| Variable_name |         Value       |
|-------------------------------------|
| init_connect  | 'SET NAMES utf8mb4' |

因為我有其他的 mysql 也有用到同樣的 init_connect 的命令,但是該命令是寫在 mysql.cnf 中,不是跟本次發生狀況的 mysql 一樣是用 docker 帶參數命令去生成的,所以我進到正常的 mysql 中看了一下,發現列出來的 init_connect 的值是不該帶有單引號的。

所以,我將 docker-compose.yml 中的 mysql 的 command 中有關於 init_connect 的命令改寫成

command: [

...,

'--init_connect=SET NAMES utf8mb4;SET collation_connection = utf8mb4_unicode_ci'

]
這樣 phpmyadmin 或 mysql 的登入就沒有再出現那個異常訊息了