Help us understand the problem. What is going on with this article?

自宅サーバ用ラズパイでPythonでLINE bot(HTTPS化)をつくる(heroku, ngrok使わない) Apache(+wsgi)+Flask(Djangoでも同じ?)

はじめに

何もかも初心者なので設定に9割の時間を使いました...
設定は具体的には、

  • PythonでWeb公開する
  • それをSSL化

の2つです。
こちらはブラウザでhttps://<domainname>/testFlaskで、pythonで書いた"Hello Flask!"が見れるようにすることです。
これさえできればLINE APIのWebhook URLにはっつければLINE botはできます。
後はherokuなりngrok使った他の記事を参考にしていただければと思います。

スキーム

schematic_view.png

上図のように、PHPで書こうとするとApacheだけでいいんですが、Pythonで書きたかったのでwsgiというモジュールを使いました。
https://qiita.com/lamplus/items/9877849d3108e2c6d0df

使ったモジュール、サービス

  • Apache2
  • LINE API
  • wsgi
  • Flask(Pythonのモジュール)
  • Let's encrypt(SSL証明書発行の無料サービス)

ディレクトリ構成

/etc/
 |---apache2/
 |       |---ports.conf
 |       |---sites-available/
 |                |---flask.conf(新規作成)
 |
 |---letsencrypt
 |       |-...
 |       ...
 |
 |
/home/
 |---t13m082h/
         |---ExampleFlask
                |---my_flask_app.py (my_flask_app.wsgiでこれをimportする)
                |---my_flask_app.wsgi (flask.confでこれを読み込ませる)

 各モジュール、サービスのインストールは他記事参考に

Apache

# apt-get
$ sudo apt-get install apache2

wsgi + Flask

$ sudo apt-get install libapache2-mod-wsgi-py3 python-dev
$ pip install flask
$ pip install mod_wsgi

Let's encrypt
https://piguide.dev/2019/03/13/raspberry-pi-ssl-certificates-using-lets-encrypt.html

Flaskで書いたページをWeb公開

エラーのlogは常に

$ sudo cat /var/log/apache2/access.log
$ sudo cat /var/log/apache2/error.log

で確認。(設定は後述)

ポート設定

HTTPリクエストを受け付けるのはApacheだが、特定のListenしているポートにきたリクエストをwsgiで処理している。
まず、Listenしているポートを設定。
ポートの設定ファイルは /etc/apache2/ports.confにまとめられている。

/etc/apache2/ports.conf
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 80
Listen 8000

<IfModule ssl_module>
    Listen 443
    Listen 4443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 443
    Listen 4443
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

wsgi用に新しく4443番ポートを使用(ルータ設定のポートフォワーディングの設定も忘れずに)
これで4443番ポートに来たHTTPリクエストを受け付けることができるようになった。
ちなみに、ポート番号を変更したい時は

  • /etc/apache2/ports.conf
  • /etc/apache2/sites-available/flask.conf
  • ルータのポートフォワーディング

の3箇所の変更が必要。

wsgi設定

設定ファイルは/etc/apache2/sites-availableディレクトリのconfファイル。
全部の設定後のファイルの中身は以下。(SSL証明書の設定も入っているので一部読み飛ばしてください)
confファイル書き方
https://pawelzny.com/server/django/2018/02/26/the-most-complete-apache2-config-for-wsgi-django-and-drf/

/etc/apache2/sites-available/flask.conf
(t13m082h は username)
<IfModule mod_ssl.c>
<VirtualHost *:4443>
     # Add machine's IP address (use ifconfig command)
     #ServerName <domain name>
     # Give an alias to to start your website url with
     WSGIScriptAlias /testFlask /home/t13m082h/ExampleFlask/my_flask_app.wsgi
     <Directory /home/t13m082h/ExampleFlask>
            # set permissions as per apache2.conf file
            Options FollowSymLinks
            AllowOverride None
            Require all granted
     </Directory>

     ErrorLog ${APACHE_LOG_DIR}/error.log
     LogLevel warn
     CustomLog ${APACHE_LOG_DIR}/access.log combined

     SSLEngine on
     Include /etc/letsencrypt/options-ssl-apache.conf
     SSLCertificateFile /etc/letsencrypt/live/<domain name>/fullchain.pem
     SSLCertificateKeyFile /etc/letsencrypt/live/<domain name>/privkey.pem
</VirtualHost>
</IfModule>

設定見る限り、ここの

WSGIScriptAlias /testFlask /home/t13m082h/ExampleFlask/my_flask_app.wsgi

でAapacheからwsgiへ受け流しています。
https:///testFlaskでアクセスできます。

.pyファイル

my_flask_app.wsgi
# /home/bin/python

import logging
import sys

logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, '/home/t13m082h/ExampleFlask/')

from my_flask_app import app as application

my_flask_app.py
# coding: utf-8
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello, Flask!"

if __name__=="__main__":
    app.run()

そして先程の、エラーログの設定はこちらです。

     ErrorLog ${APACHE_LOG_DIR}/error.log
     LogLevel warn
     CustomLog ${APACHE_LOG_DIR}/access.log combined

HTTPS化

SSL署名書の発行はこちらで終わっている前提とします。
つまり、/etc/letsencrypt/live/<domain name>/ディレクトリに証明書が置いてあること。
前述しましたが既にLet's encryptで443番ポートをSSL化していたので、4443番ポートで待機し、https://<domain name>/testFlask/home/t13m082h/ExampleFlaskへリダイレクトしている。
先程のflask.confファイルのこちらにて設定。

     SSLEngine on
     Include /etc/letsencrypt/options-ssl-apache.conf
     SSLCertificateFile /etc/letsencrypt/live/<domain name>/fullchain.pem
     SSLCertificateKeyFile /etc/letsencrypt/live/<domain name>/privkey.pem

Document root 変える場所

  • /etc/apache2/sites-availableWSGIScriptAlias<Directory>
  • my_flask_app.wsgisys.path.insert()

他のモジュール、サービスのメモ

ngrok(エヌジーロック) ⇔ Let'script + 独自ドメイン + wsgi(ウィスギー)

ngrok使うと8時間で切れてしまう
8時間毎に起動し直すスクリプト書いてもいいが、毎回URLが変わってしまうのでLINE APIの設定のWebhook URLも毎回直さなければいけないのがだるい。

heroku(ヘロク) ⇔ 自宅サーバ(Raspberry Pi) + wsgi(ウィスギー)

無料では月に1000時間しかサーバ稼働させられないので、稼働させたいWebアプリケーション増えた時に課金しなければいけない。

nginx(エンジンエックス) ⇔ apache

Apacheを元々使っていたのと、自分用のサーバなのでたくさんアクセスもないのでApacheで十分。

Django(ジャンゴ) ⇔ Flask

Flaskの方が軽いらしいので。

参考URL

https://qiita.com/okoppe8/items/0f67753706cdc11ff1cd
https://qiita.com/lamplus/items/9877849d3108e2c6d0df
https://www.codementor.io/abhishake/minimal-apache-configuration-for-deploying-a-flask-app-ubuntu-18-04-phu50a7ft
https://teratail.com/questions/78671
https://blue-black.ink/?p=4601

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした