複数のRailsプロジェクトとDjangoプロジェクトを同時運用すると、必ず直面する問題があります。それが「ポート競合」と「DB接続事故」です。私自身、試作αから試作η(いーた)まで複数の開発機を運用する中で、新しい環境の構築作業が既存環境の停止を引き起こすというトラブルを経験しました。
原因は単純なプログラムミスではありません。DockerコンテナとPython仮想環境という異なる運用方式を混在させたことによる設計上の問題でした。
本記事では、RailsにおけるDocker運用とDjangoにおける仮想環境運用の違いを整理しながら、PostgreSQL・Redis・ポートマッピング・Windows/Linux混在環境の実際を解説します。
単なる技術解説ではなく、試作αから試作η(いーた)までの試行錯誤を通して見えてきた「事故らない開発環境設計」の考え方をまとめます。
第1章 試作α〜η(いーた)の全体構成を整理する
今回のトラブルを理解するためには、まず試作αから試作η(いーた)までの全体構成を整理する必要があります。
ソフトウェア開発では、問題が発生するとアプリケーションコードに原因を求めがちです。しかし実際には、複数システムを同時運用している場合、障害の原因はインフラ設計やネットワーク構成に潜んでいることが少なくありません。
特に今回はRailsとDjangoという異なるフレームワークだけでなく、DockerコンテナとPython仮想環境という異なる運用方式が混在していました。そのため、単純に「どのアプリがどのデータベースへ接続しているのか」が見えにくくなっていたのです。
まずは全体像から整理していきましょう。
試作α・試作β・試作η(いーた)はなぜDockerを採用したのか
試作α、試作β、試作η(いーた)はいずれもRailsプロジェクトとして開発されました。
これらのプロジェクトではDockerコンテナを採用しています。
Rails開発を続けていると、Rubyのバージョン差異やGemの依存関係によるトラブルに遭遇することがあります。同じソースコードであっても、開発環境が違えば正常に動作しないケースは珍しくありません。
Dockerはこうした問題を解決するために導入されました。
Dockerの本質は「アプリケーションを動かす箱」ではなく、「独立した実行環境を複数作る仕組み」です。
例えばRailsアプリを構築すると、実際には以下のような構成になります。
Rails App
↓
PostgreSQL
さらに本格運用になるとRedisが追加されます。
Rails App
↓
PostgreSQL
Rails App
↓
Redis
Dockerではこれらを個別のコンテナとして管理できます。
app_alpha
db_alpha
redis_alpha
試作βなら、
app_beta
db_beta
redis_beta
試作η(いーた)なら、
app_eta
db_eta
redis_eta
という形になります。
重要なのは、それぞれが独立した世界として存在することです。
仮に試作η(いーた)のデータベース設定を変更しても、試作αや試作βへ直接影響することは基本的にありません。
この高い独立性がDocker採用の最大の理由でした。
試作γ・試作δ・試作ε(いぷしろん)・試作ζ(ぜーた)が仮想環境だった理由
一方でDjango側は異なる考え方で構築されています。
こちらではPython仮想環境(venv)を利用しています。
仮想環境はDockerほど大掛かりではありません。
Pythonライブラリだけを分離する軽量な仕組みです。
例えば、
python -m venv venv
を実行するだけで、独立したPython実行環境を構築できます。
学習用途や小規模プロジェクトでは非常に便利です。
しかしDockerとの決定的な違いがあります。
それはOSを共有することです。
Linux
├ Django γ
├ Django δ
└ PostgreSQL
Windows
├ Django ε
└ PostgreSQL
Linux
├ Django ζ
└ PostgreSQL
つまり複数のアプリケーションが同じOS資源を利用しています。
その結果、ポート番号の管理が極めて重要になります。
例えば全てのDjangoアプリが8000番ポートを利用しようとすると競合が発生します。
そこで、
試作γ → 8003
試作δ → 8004
試作ε → 8005
試作ζ → 8006
のような運用が必要になります。
Djangoプロジェクトが増えるほど、この管理負荷は大きくなります。
WindowsとLinuxが混在した環境の実態
今回の環境をさらに複雑にしていた要因が、WindowsとLinuxの混在です。
| 試作機 | フレームワーク | 運用方式 | OS |
|---|---|---|---|
| 試作α | Rails | Docker | Windows |
| 試作β | Rails | Docker | Windows |
| 試作γ | Django | venv | Linux |
| 試作δ | Django | venv | Linux |
| 試作ε(いぷしろん) | Django | venv | Windows |
| 試作ζ(ぜーた) | Django | venv | Linux |
| 試作η(いーた) | Rails | Docker | Windows |
技術書では単一OS環境が前提となることが多いですが、実際の開発環境はもっと複雑です。
WindowsではDocker Desktopが中心となり、Linuxではsystemdやネイティブ実行が中心になります。
その結果、
- どのPostgreSQLが起動しているのか
- どのポートが利用されているのか
- どのアプリがどのDBへ接続しているのか
が見えにくくなります。
そして後に発生するDB接続事故は、この複雑な構成が背景となっていました。
第2章 Railsコンテナ運用とDjango仮想環境運用の本質的な違い
今回の経験を通じて痛感したのは、RailsとDjangoの違いはプログラミング言語の違いではないということでした。
本当に重要なのは運用モデルの違いです。
Rails側はDockerコンテナによる環境分離を前提に設計されています。一方、Django側はOS共有型の仮想環境を前提に運用されています。
同じPostgreSQLを利用していても、接続方法や障害発生ポイントは大きく異なります。
まずはDockerの考え方から見ていきましょう。
Dockerは小さなサーバーを増やす考え方
Dockerを理解するうえで重要なのは、「コンテナ=小さなサーバー」と考えることです。
試作η(いーた)の構成を例にすると、
app
db
redis
という3つのコンテナが存在します。
物理的には1台のPC上で動いていますが、論理的には3台のサーバーが存在しているのと同じです。
そのためRailsアプリは、
host: db
port: 5432
という設定になります。
ここで重要なのはlocalhostを使わないことです。
Docker内部ではコンテナ名そのものが接続先になります。
つまりRailsアプリは「dbコンテナへ接続する」という考え方で動いています。
この設計によって高い分離性が実現されます。
Python仮想環境は同じOSを共有する考え方
一方、Djangoの仮想環境は発想が異なります。
仮想環境はライブラリを分離する仕組みであり、OSを分離する仕組みではありません。
そのため、
Django γ
Django δ
Django ε
Django ζ
はすべて同じOS上で動作しています。
接続先は通常、
host = localhost
です。
つまり全員が同じマンションに住み、同じ設備を共有している状態に近いのです。
だからこそポート管理が重要になります。
Dockerではネットワーク分離が先にあります。
しかしDjangoではポート分離が先にあります。
この違いが後のトラブルを引き起こすことになります。
PostgreSQL接続の思想が根本的に違う
最も大きな違いはデータベース接続です。
Docker環境では、
host: db
port: 5432
となります。
一方、仮想環境では、
host: localhost
port: 5434
のようになります。
Dockerはネットワークを分離してからポートを考えます。
Djangoは同じOSを共有するため、最初にポート管理を考えます。
つまりRails側では「どのコンテナに接続するか」が重要であり、Django側では「どのポートへ接続するか」が重要なのです。
この違いを理解せずに環境を増設していくと、思わぬDB接続事故やポート競合が発生します。
次章では、実際に発生した試作β停止事故を題材に、localhostの落とし穴とDB名競合の問題を詳しく見ていきます。
第3章 試作β停止事故はなぜ起きたのか
ここまで見てきたように、RailsのDocker運用とDjangoの仮想環境運用では設計思想が異なります。
しかし実際の障害は、こうした理論だけでは発生しません。
今回発生した停止事故は、「少しずつ積み重なった設計上の曖昧さ」が表面化した結果でした。
特定の設定ミスがあったというよりも、
- localhostへの過信
- ポート番号管理の曖昧さ
- データベース命名規則の不足
- 複数環境の一覧管理不足
が重なり合ったことで発生したと考える方が実態に近いでしょう。
ここでは、その原因を順番に振り返っていきます。
localhostが引き起こした誤認
開発を始めたばかりの頃、多くの人はlocalhostを「自分専用の安全な環境」と考えます。
私自身もそうでした。
しかし実際にはlocalhostは単なる接続先の表現に過ぎません。
localhostとは、
127.0.0.1
すなわち「今使っているコンピュータ自身」を意味します。
問題は、そのコンピュータの中で複数のPostgreSQLや複数のアプリケーションが動いている場合です。
例えば次のような設定が存在するとします。
host: localhost
port: 5437
この設定だけを見ると安全そうに見えます。
しかし実際には、
- どのPostgreSQLなのか
- どのデータベースなのか
- どのコンテナなのか
までは表現されていません。
つまりlocalhostという表現は、
「接続先を明確に指定しているようで実は曖昧」
という性質を持っています。
Docker環境であれば、
host: db
と書いた方が接続先が明確になります。
コンテナ名そのものが接続先だからです。
今回の事故を振り返ると、localhostを利用していることで「今どのDBへ接続しているのか」が見えにくくなっていた可能性があります。
ポート競合とDB名競合
次に問題となるのがポート番号です。
PostgreSQLの標準ポートは5432です。
しかし複数環境を運用する場合、
全てが5432を使うことはできません。
そこで一般的には次のような運用になります。
試作α DB → 5432
試作β DB → 5433
試作γ DB → 5434
試作δ DB → 5435
試作ε DB → 5436
試作η DB → 5437
ここで重要なのは、
ポートが違ってもデータベース名が同じであれば混乱が起きることです。
例えば、
pj_rails_development
という名前を複数環境で使い回していた場合、
管理者が見たときに識別しづらくなります。
バックアップや接続確認を行う際にもミスが発生しやすくなります。
今回の経験から学んだのは、
ポート番号とデータベース名の両方を分離しなければならないということでした。
例えば、
pj_rails_alpha
pj_rails_beta
pj_rails_eta
のように機体ごとに命名するだけでも管理性は大きく向上します。
試作η(いーた)構築時の設計ミスを振り返る
試作η(いーた)構築時には、
app、db、redisの三層構成を採用していました。
構成自体は現在でも正しい選択だったと考えています。
しかし問題は周辺管理でした。
環境を増設することに意識が向きすぎて、
既存環境との関係を一覧化していなかったのです。
例えば、
- どの機体がどのポートを使うのか
- どの機体がどのDB名を使うのか
- どのRedisがどのアプリに対応するのか
といった情報が設計資料として十分整理されていませんでした。
開発初期には問題になりません。
しかし試作機が増えるにつれて、
人間の記憶だけでは管理できなくなります。
今回の停止事故は、
むしろ「システムが成長した証拠」だったとも言えます。
小規模運用では見えなかった課題が、
複数環境運用によって顕在化したのです。
第4章 試作η(いーた)完成までの設計
停止事故を経験したことで、
単にアプリケーションを動かすだけでは不十分であることが分かりました。
重要なのは、
将来の増設にも耐えられる運用ルールを作ることです。
今回最終的に到達した考え方は、
- コンテナ名を統一する
- ポート番号を規則化する
- DB名を規則化する
- Redisも含めて管理する
というものでした。
この考え方は今後のAIエージェント開発にも活かせると考えています。
app+db+redis構成の完成形
Railsアプリケーションを本格運用する場合、
最終的には次の三層構成に落ち着きました。
app
↓
db
app
↓
redis
appはユーザーからのリクエストを処理します。
dbは永続データを保存します。
redisはキャッシュやジョブ管理を担当します。
この役割分担によって、
システム全体の責務が明確になります。
また、障害が発生した際も切り分けが容易になります。
PostgreSQL運用ルールを決める
今回もっとも効果があった改善策は、
ポート番号とDB名の命名規則を定めたことでした。
例えば次のようなルールです。
試作α → DB 5432
試作β → DB 5433
試作γ → DB 5434
試作δ → DB 5435
試作ε → DB 5436
試作ζ → DB 5437
試作η → DB 5438
さらにデータベース名も統一します。
pj_alpha
pj_beta
pj_gamma
pj_delta
pj_epsilon
pj_zeta
pj_eta
これだけでも接続事故の可能性は大きく下がります。
特に将来の自分が見たとき、
瞬時に理解できることが重要です。
将来のAIエージェント基盤へつなげる
今回の経験は単なるRails運用の話ではありません。
今後AIエージェントを複数運用する場合にも同じ問題が発生します。
例えば、
- 音声認識エージェント
- 文章生成エージェント
- Webスクレイピングエージェント
- RAG検索エージェント
- ローカルLLM管理エージェント
といったサービスを増やしていくと、
それぞれがDBやRedisを必要とします。
その際に場当たり的な構築を続けると、
今回と同じ問題が再発します。
だからこそ、
開発初期から命名規則とポート設計を決めておくことが重要なのです。
Q&A
Q1 Dockerと仮想環境はどちらが安全ですか
環境分離という観点ではDockerの方が安全です。
ただし学習コストは高くなります。小規模開発なら仮想環境でも十分ですが、複数システムを運用するならDockerのメリットが大きくなります。
Q2 PostgreSQLポート番号はどう決めるべきですか
規則を決めて固定することが重要です。例えば機体番号に合わせて5432、5433、5434という形で管理すると把握しやすくなります。
Q3 Redisは必須ですか
小規模なRailsアプリでは必須ではありません。しかしAction Cableやバックグラウンドジョブを利用する場合は非常に有効です。
Q4 localhost運用の注意点は
localhostは安全な専用領域ではありません。同じOS内で複数サービスが動いている場合は、接続先の識別を慎重に行う必要があります。
Q5 WindowsとLinux混在で気を付けることは
サービス管理方法が異なる点です。Docker DesktopとLinuxネイティブ環境では挙動が異なるため、運用ルールを統一した方が管理しやすくなります。
Q6 複数Railsを同時運用できますか
可能です。Dockerコンテナごとにapp、db、redisを分離すれば、複数のRailsプロジェクトを同一PC上で運用できます。
Q7 DjangoでもDocker化した方が良いですか
将来的に複数環境を運用する予定があるなら有効です。環境差異が減り、再現性が高くなります。
Q8 AIエージェント運用ではどんな構成になるのですか
将来的には、エージェントごとにDockerコンテナを分離し、PostgreSQLとRedisを共通基盤として管理する構成が主流になると考えられます。
おわりに
今回の経験から学んだ最大の教訓は、「障害はコードよりも設計から生まれる」ということでした。
試作αから試作η(いーた)まで開発を続ける中で、アプリケーションそのものよりも、ポート番号、データベース名、コンテナ構成といった周辺設計の重要性を強く実感しました。
開発初期は多少雑な運用でも動きます。しかし環境が増え、サービスが増え、AIエージェントのような常駐システムが増えるほど、設計の差がそのまま運用コストの差になります。
今回の停止事故は決して無駄ではありませんでした。むしろ将来の拡張に耐えるインフラ設計を学ぶための貴重な経験だったと言えるでしょう。
〆最後に〆
以上、間違い・ご意見は
以下アドレスまでお願いします。
全て返信できていませんが 見ています。
適時、改定をします。
nowkouji226@gmail.com

