この記事の目的
ホスト(Ubuntu 24.04 LTS)上で Docker + AppArmor を組み合わせ、
- nginx(80 / 443 公開)
- nextjs / django / mariadb(ポート非公開・docker network 内通信)
という構成を 現実的・実用的・安全に 運用するための手順を、
後で見返しても再現できる形で整理する。
前提構成
- OS: Ubuntu 24.04 LTS
- Docker / docker-compose 使用
- fail2ban:ホストに直接インストール済み・稼働中
- SSH: * IP 制限あり * 鍵認証のみ * パスワードログイン無効
コンテナ構成
| コンテナ | 公開ポート | 備考 |
|---|---|---|
| nginx | 80 / 443 | 外部公開・リバースプロキシ |
| nextjs | なし | 表示専用・入力フォームなし |
| django | なし | ブログ記事管理 |
| mariadb | なし | 記事データのみ |
機密性の高い個人情報は扱わない構成。
AppArmor の基本方針(重要)
ポイント
- **AppArmor はホストで管理する**
- docker-compose の `security_opt` は「どのプロファイルを使うか」を指定するだけ
- `complain / enforce / disable` の切り替えは **ホスト側のみ** で行う
1. AppArmor の状態確認
- `apparmor module is loaded.` が出ていれば有効
- `docker-default` は **enforce のままで OK**
2. Docker 用プロファイルを作成
例:nginx 用
読み込み
3. まず complain モードで開始(必須)
同様に:
👉 いきなり enforce しない
4. docker-compose.yml への適用
例:nginx
Django / Next.js / MariaDB 共通で推奨
5. 再起動は必ず down → up
`restart` では **AppArmor 設定が反映されない場合がある**
6. ログ確認(deny が出ていないか)
またはプロファイル単位で:
ALLOWED のみであれば問題なし。
7. 現在の状態確認(重要)
確認ポイント:
- プロファイルが complain にある
- 実プロセスが **docker-xxx プロファイルで動作**している
例:
これが出ていれば 分離成功。
8. nginx トラブル時の典型例
症状
- コンテナが Restarting
- deny ログは出ていない
対処
- `cap_add: NET_BIND_SERVICE` を追加
- `read_only: false` に一時的に戻して切り分け
- entrypoint が使う `/usr/bin/find` 等をプロファイルで許可
9. enforce へ移行するタイミング
- 数日通常運用
- deny が一切出ない
10. よくある誤解
Q. docker-default は disable すべき?
NO
- docker-default は enforce のままで良い
- 個別プロファイルと併用される
Q. コンテナ内で complain / enforce を切り替える?
できない
- AppArmor はホスト管理
- docker-compose では指定のみ
最終まとめ
- AppArmor は **段階導入が必須**
- complain → ログ確認 → enforce
- docker-default は触らない
- down → up を徹底
この構成で 実運用に耐える Docker + AppArmor 環境が完成する。




