― コンテナ内ログローテーション時の権限トラブル完全整理 ―
はじめに
Docker コンテナでアプリを運用していると、ログはホストに bind mount したいケースがほとんどだと思います。
その際に避けて通れないのが uid / gid とファイル権限の問題です。
今回は以下の構成で発生したトラブルを題材に、
- logrotate は正常に動いているのに
- ローテート後にアプリが起動不能になる
- create 0644 root root が原因に見えるが、それだけではない
という問題を 原因分析 → 正しい設計 → 再発防止策 の順で整理します。
構成概要
前提構成
- ホスト Linux(debian系 Ubuntu等)
- Docker + docker-compose
- Django + Gunicorn
- ログは ホストの ./log を /app/log に bind mount
- コンテナ内アプリは 非 root ユーザーで実行
- logrotate は ホスト側で実行
発生した現象
logrotate 設定
ローテート後の状態
問題点
新しく生成された access.log / error.log
- owner: root
- permission: 0644
コンテナ内のアプリユーザーが 書き込み不可
結果として:
- Gunicorn / Django 起動時にログファイルを open できず
- コンテナが起動しない
表面的な原因
一見すると原因はこれです。
確かに、
- root:root
- 書き込みは owner のみ
なので、非 root ユーザーで動くアプリは書けない。
しかし本質的な原因は別にある
問題の本質
ホストとコンテナで uid / gid の整合性が取れていない
これに尽きます。
uid / gid は固定値か?
結論
- 数値(uid/gid)は固定値
- 意図的な操作をしない限り勝手に変わらない
ただし…
「いつのまにかズレる」ケース
以下はよくある罠です。
- Dockerfile で useradd / groupadd をミスる
⬇ エラー
原因:
- groupadd と useradd を 1行で連結
- -m は useradd のオプション
正しくは:
- ホスト側の log ディレクトリが root 所有のまま
bind mount は 権限を変換しない。
ホスト root:root (0644)
↓
コンテナでも root:root (0644)
Docker が気を利かせてくれることはない。
「create 0755 にすればいい?」問題
結論
推奨しない
これをすると:
- root 所有のまま
- world-writable に近い状態
- セキュリティ的に雑
- 問題の根本(uid/gid不一致)は未解決
正しい解決アプローチ(推奨)
方針
ホストとコンテナで uid / gid を揃える
手順① ホスト側の uid/gid を確認
手順② Dockerfile で同じ uid/gid を作る
手順③ docker-compose.yml で build args を指定
手順④ ホスト側 log ディレクトリの所有者を変更
手順⑤ logrotate の create を修正
なぜこれで解決するのか
- logrotate は ホスト側で root として動作
- しかし 所有者を appuser に指定
- bind mount 経由でコンテナ内 appuser(uid=1001) がそのまま書き込み可能
つまり:
Host uid=1001
↓ bind mount
Container uid=1001
が成立する。
よくある勘違いまとめ
| 勘違い | 実際 |
|---|---|
| `Docker` が `uid` を変換してくれる | ❌ しない |
| `create` のパーミッションだけで解決 | ❌ 一時しのぎ |
| `uid/gid` は勝手に変わる | ❌ 意図しない限り固定 |
| `root` で作れば安全 | ❌ むしろ事故る |
再発防止チェックリスト
- bind mount するディレクトリの uid/gid を把握している
- Dockerfile の useradd / groupadd を分けて書いている
- logrotate の create で owner/group を明示している
- world-writable(777/775)で逃げていない
おわりに
Docker + logrotate + bind mount は
「動いているように見えて、ある日突然死ぬ」構成になりがちです。
今回のポイントはただ一つ。
uid/gid を数値で揃えろ。権限は後から考えろ。
この原則を守れば、同様のトラブルにはほぼ遭遇しません。
将来また詰まった時は、まずここを疑う。
それだけでデバッグ時間は大幅に減ります。





