在Docker container中執行sudo時,環境變數沒有生效

這是一篇備忘,其實標題就是關鍵了
這不只是docker中會遇到的問題,但由於docker標準做法是用環境變數做設定,這導致特別容易踩中地雷

我遭遇的問題

我在執行nextcloud升級後遇到了提示說資料表缺欄位,要我執行 occ db:add-missing-indices
我的nextcloud是部署在docker中,我習慣是先 docker exec -it <container_name> bash 打開裡面的bash來做事

好死不死這個command需要以 www-data 這個身份組來操作,我又收到如下提示

Console has to be executed with the user that owns the file config/config.php
Current user id: 0
Owner id of config.php: 33
Try adding 'sudo -u #33' to the beginning of the command (without the single quotes)
If running with 'docker exec' try adding the option '-u 33' to the docker command (without the single quotes)

這最後一行其實就是正確的指示,但我當時沒有注意到
我使用了個錯誤的做法,也是我寫下這篇備忘的原因

我在container中安裝了sudo,並在裡面執行sudo -u

sudo安裝完後我在container中下了這個command

sudo -u www-data ./occ db:add-missing-indices

結果是得到了這個回應

Fatal error: Allowed memory size of 2097152 bytes exhausted (tried to allocate 446464 bytes) in /var/www/html/3rdparty/composer/autoload_real.php on line 37

釐清問題

把這段錯誤丟Google後我找到這篇討論,其中有一個人提到了這個issue,在issue下的這篇回答完整回覆了問題

It seems the omission of the -p flag for su causes this problem. This flag ensures the environment of the user running the su command (usually root in this case) is preserved. So the behavior described as problematic is actually as expected.

So docker exec nextcloud su -p www-data -s /bin/bash -c '/var/www/html/occ' should run just fine. Or any other command for that matter, such as the cron.php script in the issue description.

Same for docker exec -u www-data nextcloud /var/www/html/occ.

These work because the image already has the correct environment variables set (these are set in the Dockerfile). These can be overwritten using -e, but that will only happen for that shell, and they will need to be preserved using -p if using su in a subsequent command.

If -p isn't set, it will revert to the default which apparently isn't enough. Not sure what that is though, as it complains it has exhausted the 2M limit, but the default limit of PHP 8 is 128M.

一言以蔽之,執行sudo時現有的環境變數不會生效。
nextcloud image使用環境變數來設定php memory_limit,缺少這個設定使得指令失敗

解決問題

事實上在 docker exec 有個 -u 參數,能以指定的身份組執行指令,且它會正確的載入我們在docker層面設定的環境變數

nextcloud這問題正確的做法如下,在host執行

docker exec -u www-data <container_name> /var/www/html/occ db:add-missing-indices

結語

  • su時若要使環境變數生效(保留至su),使用su -p
  • 千萬不要在container中sudo -u,改用docker exec -u <username>

沒有留言:

張貼留言

目錄