ラズパイとDjangoで始める格安サーバー構築

作成: 2019年09月15日

更新: 2021年03月29日

やりたいこと

  1. ラズベリーパイをWebサーバーとして起動
  2. Djangoで作ったWebアプリをラズベリーパイで起動
  3. ドメインをどこかで取得し、外部からも閲覧できるようにする

DjangoでHello, WorldでDjangoアプリを作ったはいいがこれでは自分のパソコンでしか見れないのでラズベリーパイをサーバー代わりにして外から見れるようにしたい。

ラズベリーパイの初期設定

ラズベリーパイはModel3B+を使用します。まずRasbianをOSとしてインストールして初期設定を行います。以下のサイトを参考に行いました。実はラズパイ購入時についてきたmicrosdにOSがインストール済みだったんですが、試行錯誤していく中で環境がしっちゃかめっちゃかになってしまったので結局OSを再インストールしました。
Raspberry Pi 3(RASPBIAN JESSIE)OSインストールから初期設定【セットアップ前編 】 - 環境構築メモ
公式サイトからNOOBSのzipをインストールして解凍し、フォーマットしたmicrosdにコピーするだけです。
再インストールしたときは日本語入力がデフォルトでできましたが最初に入っていたOSでは日本語入力ができませんでした。そういうときは以下のサイトなどを参考に日本語入力をインストールする。
ラズベリーパイの初期設定①日本語を使えるようにする – AIに負けない!キッズ・プログラミング教室
神器†VSCODE†をインストールする(入れなくてもいいです)
VSCodeをラズベリーパイで使う方法 | ボッチが1からゲームを作る話

nginxとuwsgi

nginxはサーバー構築のためのプログラム。uwsgiはPythonとnginxをつなげてくれるプログラムです。
ここを参考にしました。
Django + uWSGI + nginx (uWSGIチュートリアルの和訳)
公式チュートリアルの
Setting up Django and your web server with uWSGI and nginx
をわかりやすく和訳してくれています。
注意点としてapacheが入っているとなぜかうまく動きません。筆者は結局OSを再インストールしました。あとDjangoの設定ファイルsettings.pyを以下のようにしましょう。

settings.pyALLOWED_HOSTS = ["*"] #外部からのアクセスを許可する。セキュリティ上はドメインなどを指定したほうがいい
DEBUG = FALSE #仮にバグってもエラー情報が表示されないようになる

これでラズベリーパイはサーバーとして動きますが、これではラズパイと同じネットワーク内でしかアクセスできません。

ルーターとファイアウォールの設定

一般的なhttpアクセスの80番ポートとuwsgiが使う8000番ポートをつなげるためにルーターの設定をします。ルーターの設定方法は契約会社やルーターの機種によって異なるので調べるしかないです。NTTの場合はhttp://ntt.setup にアクセスすると設定できます。ユーザー名は大体userかadmin、パスワードは設定していなければ契約時の書類に書いているはずです。設定画面から静的IPマスカレード設定を行います。宛先IPアドレスをラズベリーパイのプライベートIPアドレスに変換対象IPアドレスを自分のWAN側IPアドレスに変換対象ポートを80(wwwとなる場合もあり)に変換対象プロトコルをTCPとUDP両方(よくわからない)にします。
プライベートIPアドレスはipというコマンドで見ることができます。以下を参考にしました。
【初心者向け】Linux PCのIPアドレスを確認する方法まとめ | Linux Fan
つぎにラズベリーパイのファイアウォールを設定し、ポートを解放します。以下を参考にしました。
ufwを使って簡単にファイアウォールを設定する
ufwをapt-getなどでインストールし、以下のコマンドで80番、8000番ポートを解放します。

$ sudo ufw allow 80
$ sudo ufw allow 8000

この状態でuwsgiを起動し、グローバルipアドレスに外部からアクセスすると作成したDjangoアプリを閲覧できます。しかし、これでは見てもらうにはグローバルipアドレスを教える必要があり、セキュリティ上不安です。

ドメイン取得

今回のように自宅でサーバーを構築するためにダイナミックDNSというサービスがあります。これはドメインを取得し、そのドメインへのアクセスを自分のグローバルipアドレスへのアクセスに変換してくれるサービスです。自分は無料ダイナミックDNS(DDNS)サービス - ieServer.Netを用いました。他にもいろいろなサイトがありますが条件が厳しかったりするのでここが一番楽だと思います。アカウントを登録し、ログインしてドメインを更新するだけでそのドメインが自身のグローバルipアドレスに結び付けられます。

自動起動

これまでで大体目標は達成しているが、いちいちuwsgiをコマンドで起動するのが面倒なので自動起動を設定した。以下のサイトを参考にした。
Raspberry Piでプログラムを自動起動する5種類の方法を比較・解説
この中のsystemdにより自動化した。

$ sudo nano /etc/systemd/system/sample.service

このコマンドでsample.service(名前は自由)というファイルを作成する。そして以下のようにする。

[Unit]
Description=Sample
After=syslog.target

[Service]
Type=simple
WorkingDirectory=iniファイルを置いた場所
ExecStart=/usr/local/bin/uwsgi --ini iniファイル
TimeoutStopSec=5
StandardOutput=null

[Install]
WantedBy = multi-user.target

注意すべきはuwsgiをフルパスで指定しなければいけないところ。
この状態で以下のコマンドで起動、停止を確認する。

$ sudo systemctl start sample
$ sudo systemctl stop sample

確認出来たら以下のコマンドで自動起動をオンにする。

$ sudo systemctl enable sample

また以下のコマンドで自動起動をオフにできる。

$ sudo systemctl disable sample

まとめ

自分で作ったDjangoアプリに外部からアクセスできるようになった。
しかし自宅サーバーはどうやってもセキュリティ上不安なのでお金があればレンタルサーバーを用いたほうがいいかもしれない。