0
1

VPSをAPIサーバにして、Flutterアプリを作った話

Posted at

概要

以前からVPSを契約していて活用していなかったので、今回は、VPSをAPIサーバとして、Flutterアプリを作りました。(アプリの内容は、chatgptで作成したナンバーズ3の当選番号予測プログラムであり、正確性が保証されていないためメインでは触れません。)
システム全体の構成から、触れたいところのみ詳細に書こうと思います。

システム全体の構成

  • クライアント:Flutter
  • APIサーバ:ubuntu
  • DB:Neon(Postgresql)
  • API:Python3(FastAPI)
    一応全体の構成図も載せておきます。
    システム構成図

DBについて

APIサーバについては契約していましたが、DBをどうしようと無料のものを探していたところ、Neonを見つけました。最初はHerokuにしようと思っていたのですが、2022年11月28日に無料枠が廃止されたようです。

Neonとは

サーバーレスなデータベース(Postgresql)を提供しているサービスです。
無料のプランは以下のようになってます。(公式サイトより抜粋)今回は、このサービスを使用して、APIサーバからアクセスしています。
Neonの無料プラン
このプランでいうところの0.25CUというのは、0.25 vCPU,1GB RAMだそうです。
なので、2CU = 2 vCPU,8GB RAMまでAutoScaleします。
ストレージが500MBで少し物足りないですが、今回作るアプリでは十分な容量です。

Neonのセットアップについては、ここでは割愛します。

APIサーバについて

以前からVPSサーバをWebARENA Indigoを契約していて使ってなかったので、今回APIサーバとして使用することにしました。VPSを契約した時に書いた記事がこちら(個人ブログの記事です)。
そして、同時期にドメインを取得したので、このVPSに割り当てています。

APIサーバでやること

今回APIサーバの役割は、以下の二つです。

  1. ナンバーズ3の過去の当選番号をスクレイピングして、予測した番号をNeonにinsertする(日次)
  2. FlutterアプリからのAPI呼び出しにより、Neonから予測した番号をselectしアプリ画面に表示する

どちらもPython3のプログラムですが、1.はcronによる日次バッチ、2.はFastAPIを用いたREST APIとなっています。ここで、FastAPIの環境構築とデーモンプロセス化までの手順を書いておきます。

FastAPI環境構築、およびデーモンプロセス化手順

まずは、以下のコマンドにより、fastapiとuvicornをインストールします。

pip install fastapi[all]
pip install uvicorn

次に、VPSサーバが万一再起動された場合を考慮して、デーモンプロセス化して自動起動するようにします。
(サービス名をfastapiとした場合)

cd /etc/systemd/system
touch fastapi.service
vi fastapi.service

記述内容は以下です。

[Unit]
Description=Your FastAPI Application
After=network.target

[Service]
User=username #実際のユーザー名を記述
Group=www-data
WorkingDirectory=/home/fastapi #fastapiのワーキングディレクトリを記述
ExecStart=/usr/local/bin/uvicorn main:app --host 127.0.0.1 --port 8000 #ポート番号は実際のものを記述

[Install]
WantedBy=multi-user.target

続いて、上記で指定したワーキングディレクトリにパーミッションを付与します。

chown -R username:www-data /home/fastapi
chmod -R 755 /home/fastapi

デーモンプロセスのリロードを行い、作成したサービスを起動し、自動起動を有効にします。

systemctl daemon-reload
systemctl start fastapi
systemctl enable fastapi

Nginxを介してFastAPIにアクセスする

FlutterからのAPI呼び出しをNginxで受けつつ、FastAPIにリバースプロキシ設定します。(NginxはFastAPIと同一サーバに環境構築します)
ここの手順は割愛します。

API呼び出しをHTTPS化する

HTTPSでのアクセスは必須です。
SSL証明書の発行となると費用が発生するため、どうにか無料でHTTPS化できないかと探していたら、Let's Encryptというフリーの認証局(CA)を見つけました。
有効期限が90日であるため、月初に自動更新するように設定をしましたが、有効期限が30日以上ある場合は、自動更新されないようです。

以下の手順で、Let's Encryptをインストールします。

# Let's Encryptのインストール
apt-get install letsencrypt

# 一旦nginxは停止
systemctl stop nginx

# SSL証明書取得
letsencrypt certonly --standalone -d [実際のドメイン名を記述]
# 途中でメールアドレスを入力します

# nginxを再開
systemctl start nginx

証明書が取得されているかを確認します。
以下コマンドを実行し、Found the following certs:以下にドメイン名に関する情報が出力されれば、取得できています。VALID:に残り何日有効か記載されています。

certbot certificates


Found the following certs:
  Certificate Name: ドメイン名
    Serial Number: XXXXXXXXXXXXXXXXX
    Key Type: RSA
    Domains: ドメイン名
    Expiry Date: 2024-MM-DD 00:00:00+00:00 (VALID: XX days)
    Certificate Path: /xxx/fullchain.pem
    Private Key Path: /xxx/privkey.pem

【参考】実際のアプリ画面

参考までに実際のアプリの画面です。
特に画面での操作はなく、起動するとAPIでデータを取得し表示するのみです。
今はまだスクレイピングのプログラムが日次で動いていないので、8/26更新で止まってます。
あと、App Storeに一応審査を出していますがはたして通るのでしょうか?
アプリのスクリーンショット

まとめ

今までは、個人のブログで記事を書いていたのですが、今回初めてQiitaで記事を書いてみました。
情報の粒度感とかわからないですが、今後も個人開発で得た知見などを書いていく予定です。

0
1
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
1