1つのVMインスタンスに複数のアプリを置くような構成を考える

VPSなどの環境で、1つのVMインスタンスにたくさんDjangoアプリをホストしたいなー、という場合の構成を考えたりしてました。

自分で運用しやすい形にまとまったので、メモを残しておきます。

要件

  • 1台のVMで複数種類のDjangoアプリを動かす
  • VMのメモリは2~4GBぐらい(月2000~4000円以下ぐらいのVPS
  • OSはUbuntu
  • DBはMySQL
  • WebサーバーはNginx
  • HTTPSはLet's Encryptを使う
  • MySQLはWorkbenchとかですぐ見れるようにはしておきたい
  • メール送信はSendgridを使う(なのでローカルにSMTPサーバーは不要)

要するにサーバー費用を抑えつつ、アプリをいくつも動かしたい。

負荷が上がった場合は、ミドルウェアを別のものに変えなくても、他のインフラに容易に移設できるような感じにしておきたい。

構成

f:id:nullpobug:20200630224433p:plain
構成図

結局これで一旦落ち着きました。

  • Nginx
    • Docker化するとCertbotが面倒な感じだったので、ホスト側Ubuntuにインストールして利用
    • アプリとの通信はTCP使わずにUnixドメインソケット
  • MySQL
    • アプリごとにDocker化するとメモリ食い過ぎる
    • 運用時にすぐmysqlコマンドやmysqldumpを使いたかったのと、Workbenchでの接続も簡単にしたかったので、ホスト側Ubuntuにインストール
  • アプリ
    • Pythonの環境は分離したかったので、Dockerで動かす
    • アプリごとにdocker-compose.ymlを作って自動起動するように設定してる
    • gunicornはワーカープロセスを1にしてメモリ使用量減らす、代わりにワーカースレッド数を増やす
    • NginxからはUnixドメインソケットで接続するので、Gunicornはソケットファイルにバインド
    • MySQLへの接続はUnixドメインソケット経由
  • cron
    • 定期実行は docker-compose exec でアプリのmanage.pyのコマンドを起動する

以上。小さいDjangoアプリなら1台に10個ぐらいホストしても大丈夫だとおもう。