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?

Raspberry PiとAzure VMを使ってAPIを外部公開

Last updated at Posted at 2025-03-01

RaspberryPi 5 上のAPIを、AzureVMを踏み台にして外部公開するまでの内容です。勉強と備忘録も兼ねてまとめてみました。

RaspberryPiOSのインストールやSSH接続といった初期設定は済んでいる前提で話を進めます。初期設定のやり方は他に沢山の記事でわかりやすく説明されているので、そちらを参照ください。

※今回、API常時稼働まではできませんでした。度々Raspberry Pi上でAPIサーバーを起動する必要があります。

アーキテクチャ図

ざっくりとした全体像です。

APIサーバーアーキテクチャ図.png

RaspberryPi 5 上のFastAPIで開発したAPIを、AzureVMのパブリックIPアドレスを使って公開します。インターネット上でAPIが叩かれると、Azure VM上のNginxからRaspberry Piへリクエストを転送するイメージです。

1. Azure VMの構築

Azure VMの設計

  • Azure Portal で 「仮想マシンの作成」
  • Ubuntu 20.04 LTS or 22.04 LTS を選択
  • パブリックIPを有効化(固定IP推奨)
  • ポート 80, 443 を開放
  • SSH を有効化(22番ポート)
    • RSA SSH 形式を選択し、SSHキーをPCに保存

2. Raspberry PiのFastAPIを起動

以下、FastAPIプロジェクトの場合の起動方法

プロジェクトディレクトリに移動

cd src/hot-bubbles-api/

venv仮想環境を起動(未作成であれば作成する)

※下記fishでの実行コマンド

source venv/bin/activate.fish

サーバー起動

uvicorn app.main:app --host 0.0.0.0 --port 8000

3. SSH接続:Raspberry Pi → Azure VM

参考Doc

Linux VM に接続する - Azure Virtual Machines

sshキーの転送

ここでいうSSHキーとは、VM構築時に払い出された.pemファイルのことです。
私は自分のMacでVMを構築したので、Raspberry Piに転送します。
はじめからRaspberry PiでSSHキーを保存した方はこの手順は不要です。
使うのは、scpコマンドです。ssh接続された端末間でのファイルの送受信が可能です。

PCの~/.ssh/hotbubbles-api-dev_key.pemファイルをraspberry@piというRaspberry Piの/.sshディレクトリ配下に転送します。

scp ~/.ssh/hotbubbles-api-dev_key.pem raspberry@pi.local:~/.ssh

Raspberry Pi上での操作

読み取り権限の確認

chmod 400 ~/.ssh/myKey.pem

下記sshコマンドを実行し、Azrue VMに接続確認

ssh -i ~/.ssh/myKey.pem ${VMのuser名}@${VMのパブリックIP}

VMのuser名を忘れてしまった場合、Azure PortalのJSONビューから確認できます。

4. Raspberry Pi から Azure VM に SSH リバーストンネルを設定

Raspberry Piで以下コマンドを実行

ssh -i ~/.ssh/myKey.pem -R 9000:localhost:8000 ${VMのuser名}@${VMのパブリックIP}

これで Azure VM の localhost:9000 にアクセスすると、Raspberry Pi の localhost:8000 に接続可能となります。

Azure VM環境で下記コマンドを実行してみて、FastAPIで実装したAPI値が返って来れば成功です。

curl http://localhost:9000

アクセス失敗時に考えられる原因

ssh: connect to host ${IPアドレス} port 22: No route to host

私の場合はRaspberry Piがインターネットにアクセスできていませんでした。

その他にも以下のような原因が考えられます。

  • Azure VMの起動
  • Azure VMがポート22を開放していない
  • VMのSSHサーバーを起動
  • VMのファイアウォールを設定

5. Azure VM に Nginx をインストールしリバースプロキシを設定

インストール

sudo apt update && sudo apt install nginx -y

設定を変更

sudo nano /etc/nginx/sites-available/api
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://localhost:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

設定を有効化する。

Nginxは/etc/nginx/sites-enabled/ にある設定しか読み込まないので、シンボリックリンクを貼る。
※参考→ Nginxのconf.dとsites-availableとsites-enabledの違い - Qiita

sudo ln -s /etc/nginx/sites-available/api /etc/nginx/sites-enabled/

Nginxを再起動

sudo systemctl restart nginx

6. インターネットから API にアクセス

ドメイン名を設定

今の状態でもVMのパブリックIPにアクセスすれば、インターネット上からAPIが叩けるのですが、せっかくならドメイン名で叩きたいですよね。

Azure Portal上で下記操作をして独自のドメイン名を作りましょう。

今回使っているVMの画面のパブリックIPアドレスをクリックすると、構成画面に遷移すると思います。そこのDNS名ラベルという設定値(はじめは空欄のはず)に任意のドメイン名を設定しましょう。

${設定したドメイン名}.japaneast.cloudapp.azure.comにアクセスすると、インターネット上からAPIにアクセスできるはずです!

失敗した場合

パブリックIPアドレスにアクセスしてもNginxのデフォルト画面が表示される。

/etc/nginx/sites-enabled/default が残っているのが原因かも。

削除

sudo rm /etc/nginx/sites-enabled/default

nginxを再起動する

APIの結果の日本語が文字化け

Azure VMのパブリックIPアドレスにアクセスして、jsonファイルが返ってくることを確認したのですが、日本語部分が文字化けした状態で表示されます。

FastAPIの文字コードの設定をいじると治りました。

詳しいことはまだわかりませんが、ensure_ascii=Falseでユニコードエスケープを抑制するようです。

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?