
OpenClawをDocker Compose上で運用する際、セキュリティをどこまで考慮すべきか悩んだことはありませんか?
私自身、Telegram/Discordの複数チャネルに対応し、外部AI API(GLM、Gemini、OpenAI)を利用するBotを構築した際に、認証情報の管理やネットワークの露出範囲について意外と考えることが多いと感じました。
この記事では、実際にDocker Compose環境でセキュリティを意識した構成を組んだ経験をもとに、非rootユーザー実行・localhostポート限定・entrypoint自動硬化の「3層セキュリティ」と、2段階の認証情報管理について紹介します。
こんな人におすすめ
- Docker ComposeでBotやAPIサーバーを運用している方
- コンテナのセキュリティ設定をどこまでやるべきか迷っている方
- 複数のAI APIキー・トークンを安全に管理したい方
- entrypoint.shを活用したセキュリティ自動化に興味がある方
目次
背景
OpenClawをDocker Compose上で運用するにあたり、セキュリティを考慮した環境構築を行いました。
Telegram/Discordの複数チャネルに対応し、外部AI API(GLM、Gemini、OpenAI)を利用する構成のため、認証情報の管理やネットワークの露出範囲を意識する必要がありました。
正直なところ、最初は「Dockerだからある程度安全だろう」と思っていましたが、実際に構築してみると考慮すべき点が予想以上に多かったです。
要件
- 非rootユーザーでの実行
- APIキー・トークンの安全な管理(
.envファイル分離) - ポートの公開範囲をlocalhostに限定
- Gateway認証とDiscordチャンネルのアクセス制御
- コンテナ起動時のセキュリティ設定自動適用
実装方針
今回採用したセキュリティ設計は、以下の3層構造です。
graph TD
subgraph Layer1["Layer 1: Dockerコンテナ"]
A[非rootユーザー実行<br/>UID 1001]
end
subgraph Layer2["Layer 2: ネットワーク"]
B[ポート公開を<br/>127.0.0.1に限定]
end
subgraph Layer3["Layer 3: 起動時自動硬化"]
C[entrypoint.shで<br/>セキュリティポリシー適用]
end
Layer1 --> Layer2 --> Layer3
style Layer1 fill:#e8f5e9
style Layer2 fill:#e3f2fd
style Layer3 fill:#fff3e0
1. Docker構成のセキュリティ対策
非rootユーザー実行:
- Dockerfile内でアプリ専用ユーザー(UID 1001)を作成しています
- アプリケーション実行はすべて非rootです
ポート公開の限定:
ports:
- "127.0.0.1:51121:51122" # OAuth: localhost only
- "127.0.0.1:18789:18790" # Gateway: localhost only
外部からのアクセスを遮断し、localhostのみに制限しています。
認証情報の分離:
.envファイルに機密情報を集約しています.gitignoreで.envを除外していますdocker-compose.ymlのenv_fileで読み込みます
2. entrypoint.shによる自動セキュリティ硬化
コンテナ起動時に entrypoint.sh が以下を自動適用します:
- 設定ディレクトリのパーミッション(700)
- Discord groupPolicy を allowlist に強制
- 信頼プロキシの設定
- socat ブリッジによる内部ポートフォワード
3. アプリ固有の認証管理
このBotは独自の2層構造の認証管理を持っています:
flowchart LR
A[".env<br/>環境変数"] --> B["bot-config.json<br/>auth.profiles"]
B --> C["auth-profiles.json<br/>実際のAPIキー"]
style A fill:#ffecb3
style B fill:#bbdefb
style C fill:#c8e6c9
bot-config.jsonのauth.profilesがプロファイルを参照しますauth-profiles.jsonに実際のAPIキー・OAuthトークンが格納されています
環境変数だけでは不十分で、Bot内部のauthプロファイルにも登録が必要です。
ここは実際にハマったポイントで、.env に設定しただけでは動かず、原因の特定に時間がかかりました。
4. AIモデルの動的切り替え
BOT_AI_MODEL環境変数は設定ファイルを自動で上書きしませんentrypoint.shで起動時にbot models setを呼び出して適用します- Makefileに
make model-glm/make model-geminiを用意し、再起動なしで即時切り替え可能です
良かった点
個人的に最も良かったのは、entrypoint.shによる自動硬化です。
設定ファイルが外部から書き換えられても、コンテナを再起動すればセキュリティポリシーが自動的に再適用されます。
「壊れても再起動すれば安全な状態に戻る」という安心感は、運用上とても大きいと感じています。
また、localhostバインドは設定が簡単なわりに効果が高く、Docker Composeの ports に 127.0.0.1: プレフィックスを付けるだけで外部公開を防止できます。
つまづいた点
実際に構築する中でいくつかハマったポイントがありました。
2層構造の認証管理: 環境変数(.env)に設定しただけでは不十分で、Bot固有の設定ファイルにも登録が必要でした。
この「環境変数 → アプリ設定のブリッジ処理」に気づくまでに、正直なところ2時間ほど費やしました。
セッションロック問題: コンテナ再起動後に .lock ファイルが残り、Botが起動できなくなる問題に遭遇しました。
entrypoint.shにロックファイル削除処理を追加することで解決しましたが、初回は原因がわからず困りました。
得られた効果
この3層セキュリティ + 2段階認証管理の構成を導入した結果:
- セキュリティ設定の手動確認が不要に: entrypoint.shが起動時に自動チェックするため、人為的なミスを防止できます
- 環境の再現性が向上:
docker-compose upだけでセキュアな環境が再現できます - トラブルシューティングの効率化: ロックファイル対策やモデル切り替えをMakefileに集約し、運用ナレッジをコードに落とし込めました
まとめ
Docker ComposeでOpenClawを運用する際のセキュリティ設計として、以下の3点が効果的でした。
- 非rootユーザー + localhostポート限定 + entrypoint自動硬化の3層構造
- 複数のAPI認証情報を扱うため、
.env+ アプリ固有のauth管理の2段構えが必要です - 運用ナレッジ(モデル切り替え、トラブルシューティング)をMakefileやCLAUDE.mdに集約することで、次回のセッションで即座にコンテキストを復元できます
セキュリティ設計は「やりすぎかな」と思うくらいがちょうどよいと個人的には感じています。
特にAPIキーを複数扱うBotでは、最初にしっかり設計しておくことで、後々の運用が格段に楽になります。


