0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MongoDBAtlasを使ったサービスを動かしたい(初心者向け)

Last updated at Posted at 2025-08-26

課題)こじんまりとした無料サービスをデプロイしたいときに課題となるデータベース問題

私は個人の趣味で簡単なサービスを一人で作っちゃ喜んでいますが、静的なサイトであればjsonファイルをマスタとして参照し、処理はHTML+javascrpt+cssでコードを書き、それをGithub pagesで公開するという超絶カンタンな方法が定番でした。実際のコードはほぼ生成AIに書いてもらうので、デザインの修正と細かい処理の追加程度でそれなりのモノ(あくまで素人として)ができます。が、データベースを扱いたいとなるとこれが厄介。昔はherokuやrenderなどが無料のデータベースサービスを提供していたけれど、今は有料です。そんななかpythonanywhereは無料のデータベース環境を提供してくれていますが、それもいつまで続くかわかりません。

ならばどうするか?

ガンガン追加、更新、削除を繰り返すような処理は、やはりリレーショナル型データベースで実績のあるPostgreSQLとかMySQLとかの有名どころを使うのが常套手段なんでしょうが、そうなるとお金がかかる。たとえばGoogle Cloudではアクセスがなくてもディスクを確保するだけで課金される(無料対象外)ので、たいして使わないサービス用に環境を持っておくのは金銭的に厳しい(最低規模で一ヶ月2000円くらいですが)。Dockerのコンテナにデータベースのデータを置いておくととりあえず動きますが、利用が途絶えたスリープ後の再起動時にはせっかく登録したデータが初期化されてしまうからそれじゃ扱えない。エンジンだけコンテナに置いといて、データはGoogle storageを使うのが可能ならばできるような気もするけど、IAM設定とか色々めんどくさそうでやる気が出ない。

で、みつけたのがインターネットでデータベースが無料で使えるMongoDB Atlasです。

サービス環境

サービスを動かすのはpythonで、今回はプルダウンのリストから都道府県を選択して登録してもらうだけのカンタンな内容だから、これくらいの処理ならばフレームワークは扱いが簡単なflaskとしました。
(Djangoは高機能だけどそのぶん扱いがめんどい)

python = 3.13
flask = 3.1.1
pymongo = 4.14.0
python-dotenv = 1.1.1
gunicorn = 23.0.0
  • gunicornは本番環境でWSGIサーバーとして利用します

サービスはRenderとCloud Run上で稼働中です。

MongoDBに関するflaskからアクセスするための記述

# MongoDB Atlas 接続
load_dotenv() 
uri = os.getenv('MONGODB_URI')

if os.path.exists('/etc/secrets/mongo-client-pem'): # 本番環境用(render,cloud runの証明書ファイルがあるパス)
    cert_path = '/etc/secrets/mongo-client-pem'
elif os.path.exists('mongo-client-pem'): # ローカル実行用(ローカルテスト時は証明書ファイルをルートに置いておく)
    cert_path = 'mongo-client-pem'
else:
    cert_path = None # 環境変数が存在しない場合の処理

client = MongoClient(uri,
                    tls=True,
                     tlsCertificateKeyFile=cert_path,
                    server_api=ServerApi('1')
                     )
                     
db = client["local_data"]
votes = db["votes"]

MongoDBへ接続するためのURI(MONGODB-URI)はそれぞれ環境の外部変数として登録しています(ローカルでは.env)。また接続用証明書ファイルの置き場については、ローカル環境のパス設定がよくわからず置き場所をルートにしてる関係で、同一コードでローカルのテスト環境とインターネット環境で動くようにするため、ファイル置き場の指定はif文で切り分けています。

なお本番環境の外部変数やセキュリティファイルに関する設定については別に投稿する予定です

"mongo-client-pem"はMongoDB.comに自分の環境を設定すると発行できる証明書ファイルです。

これをflaskに書いとけばインターネットに接続されていればどこからでもアクセスオーケーです。

まとめ

MongoDBはいわゆるNoSQLと呼ばれるデータベースエンジンで事前にスキーマの定義が不要であり、かつ同じコレクション(RDBでいうテーブル)にレイアウトが違うドキュメント(RDBでいうレコード)が混在していても問題なしというフリーダムな設計で気軽に利用できるのがよいです。今回のようなとりあえず登録されるデータを単純に溜め込んでおくようなサービスでは何も考えなくてよいのでオススメじゃないかと思います。

データ自体はJSONと同様なkeyとvalueの組み合わせで、公式サイトからGUIで参照してもわかりやすいし、同じく公式サイトではデータを集計する機能なども提供されているっぽいので今後使ってみたいと思います。

なお詳しくはMongoDBで検索するか生成AIに聞いてもらえば、Atlas利用開始の手順など有用な情報が入手できるはずですので、そちらでよろしく(と丸投げしてみる)

最後に

ふとした思いつきで始めた状態でMongoDBの知識は皆無でしたが、生成AIに基本のコードを書いてもらい、それを読みつつ改良していくうちになんとなくわかった気になりました。とりあえず習うより慣れろ。無料だし、夏休みの自由研究としてやってみるのアリだとおもいますよ。

おまけ

わたしの夏休み自由研究

某有名アイドルグループが毎年明治神宮野球場で開催するライブツアー最終公演には1公演あたり平均3.5万人が全国から集結しますが、そんなファンたちはどこから来たのかを調べたいなと思い立ち、生成AIに頼りっぱなしですが5日でぼちぼち作ったサービスです。

サービス画面

単純に都道府県を選択して登録するだけで都道府県名と投票日時を登録している以外の情報は保存していません。
このサービスは香川県で行われたライブ開催時に地元特産品ショップのSNSの投稿にあった、来場したファンに対してどこからやってきたかを地図上にシールで貼り付けてもらってたのをみて思いつきで作ったものです。

サービス画面

※画像引用元 https://x.com/shikokushop88/status/1957233439708700947

なので正確な情報を取ろうとすれば本来はcookieなどを使った一人一回のみの投票制限や、実際現場周辺でのみ投票可能とするスマホのGIS情報を取得するなどの仕組みを入れるべきなんでしょうが、個人情報の取扱云々の管理は対応しきれないし、そこまでやる責任は負えないし、そういった情報を取得するとなると利用に関する心理的な忌避感もあるだろうってことで、登録制限なしのデータ正確性はフル無視仕様です。
ということで現在稼働中のサービス(上のリンク)からアクセスして触ってもらい、怖がらずにお気軽に投稿してみてください、というお願いでした。

今年のライブ開催は2025年9月4,5,6,7日の4日間ですので、14万件以上のデータが登録される可能性もあるわけです。「きゃー、サーバが落ちたらどうしよう」などと心配してみても無駄なことはよくわかっていますが、1,000件くらいの登録があればデータをグラフ化したり日本地図上にヒートマップで表示させたりしても面白いかなって思ってます。

現在サービスはRenderとCloud Runで同じコードの同じDBを参照したサービスを同時に動かしています(上のリンクはCloud Run環境)。それら環境へのデプロイ方法についてはまた別に投稿する予定です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?