モヒカンメモ

髪色が定期的に変わることに定評のある(比較的)若者Webエンジニアの備忘録

dockerコンテナ内から /dev/stdout へ書き込もうとすると "Permission denied" になる

PHP Laravel 5.5系のアプリをdockerコンテナにして、所定のログファイルpathから /dev/stdout へのsymlinkを貼って動かしたところ Permission denied エラーが出た。原因を調べたところそれなりにめんどくさかったので調べたことをまとめておく。

症状

  • dockerコンテナ内のアプリから /dev/stdout へログを吐こうとしたときに Permission denied エラーになる
  • コンテナに入ってディレクトリとパーミンションを確認すると、パット見問題無さそう

原因

/dev/stdout の最終的な向き先が自分のpts (仮想端末) ではないことがあり (バグ?)、自分のものでないptsには当然書き込めないのでエラーとなる。

▼ ptsってなんやねん的な人向け

takuya-1st.hatenablog.jp

▼ 神記事

qiita.com

どうすればいいか

アプリから /dev/stdout へ直接ログを吐かず、プログラミング言語が用意している標準出力用streamへ向けてログを吐くようにする (phpでいうと php://stdout ってやつ)。

そうするといい感じに実行ユーザのptsを解決して、自分のptsへ向けて標準出力を吐いてくれる。


Laravelの場合、 bootstrap/app.php に下記のような設定を加えればOK。

$app->configureMonologUsing(function ($monolog) {
    $monolog->pushHandler(
        new \Monolog\Handler\StreamHandler(
            'php://stdout',
            \Monolog\Logger::WARNING // TODO: 適切なログレベルを設定
        )
    );
});

▼ configureMonologUsingってなんやねん的な人向け

laravel.com

memo

▼ 同じような事象を相談していた stack overflow。この人はSymfonyだけど同じ原因。

stackoverflow.com