PHP-FPMはデフォルトでは環境変数を渡さない

エラー内容

laravelでpythonを途中使うところがあり、ライブラリインポートのところでこんなエラーに遭遇した。

ShellScript
...
  File "xxx/.pyenv/lib/python3.10/site-packages/pydub/audio_segment.py", line 163, in AudioSegment
    converter = get_encoder_name()  # either ffmpeg or avconv
  File "xxx/.pyenv/lib/python3.10/site-packages/pydub/utils.py", line 164, in get_encoder_name
    if which("avconv"):
  File "xxx/.pyenv/lib/python3.10/site-packages/pydub/utils.py", line 152, in which
    envdir_list = [os.curdir] + os.environ["PATH"].split(os.pathsep)
  File "/usr/lib/python3.10/os.py", line 680, in __getitem__
    raise KeyError(key) from None
KeyError: 'PATH'

しかも、sshでログインして直接スクリプトを叩くときはエラーがでない。

エラーの原因

エラー内容をちゃんと見てみると、os.environ["PATH"]でPATHというキーがないというエラーということだった。

pythonのos.environは、OS の環境変数を反映する(コマンドのprintenvとかで確認できる)ということなので確認してみたところ、コマンド上では数十個登録されていたが、laravelのスクリプトの途中でexec(printenv)を行うと3つしか登録されていなかった。

環境の違い

sshからのログインシェルからスクリプトを叩くときと、リクエストからlaravelの処理を通ってスクリプトを叩くときの差が影響しているということになりそうだ。

リクエストでは、デーモンのnginxからのデーモンのphp-fpmで処理をするので、ここの環境変数の設定がログインシェルの時と違うことになる。

systemctlで設定(解決せず)

まずpythonを実行するのはphp-fpmじゃないかという当たり前のことに気が付く前の話。。
ubuntuのサービスの設定プロパティにEnvironmentFileというのが設定できるのでそれで解決できるのではないかと試していた。(備忘録として書いておく)

ShellScript
systemctl show nginx.service

というのでubuntuのサービスの設定プロパティを見ることができるのだが、独自の設定を以下のコマンドから追加することができるらしい

ShellScript
systemctl edit nginx.service

まずこのファイルの編集に時間をとられてしまったのだが、よく見ると「Lines below this comment will be discarded」と書いてあり、それ以降に何を書いても

Editing "/etc/systemd/system/nginx.service.d/override.conf" canceled: temporary file is empty.

と言われてしまって保存ができないので注意!!!

デフォルトで用意してくれる設定ファイル

Prisma
### Editing /etc/systemd/system/nginx.service.d/override.conf
### Anything between here and the comment below will become the new contents of the file

## ここに何か書かなくてはいけない

### Lines below this comment will be discarded
###これ以降に書いても何も保存できない
###
# [Unit]
...
# [Service]
# Type=forking
# PIDFile=/run/nginx.pid
...

PHP-FPMの設定 clear_env

PHP-FPMの方をなんとかしなくてはいけない、と気づいてから調べたところ、php-fpmの設定でclear_env=noを指定できるという記事を見た。

https://qiita.com/jkr_2255/items/51ef6112a11465ed5e6e

実際設定ファイルを見てみると、clear_env=noはデフォルトでコメントアウトされていた。
このコメントアウトを外すと、環境変数PATHは渡されるようになり(それでもログインシェルの時よりなんか少なかったけれど)、問題は解決された。。

終わりに

エラーはちゃんと根気強くエラー文をよく読んで根幹を直すように考えないと、こうして遠回りすることになってしまう…。(これ、定期的に反省してる気がする)

特にchatgptの使い方はちゃんと考えないとね🙄

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール