概要
賃貸のスマートホーム化をしたい!!!
と思い、「まずは家に入るところから」とスマートロックの購入を検討したところ、安くても10000円以上・・・
僕はこう感じた
あんな鍵回すだけの機械になんで10000円も払わなあかんねん!!!!
こんなんなら自分で作ったるわ!!!
元からラズパイを触りたかったということもあって、勢いでRaspberrypiZeroWHを購入。
せっかくラズパイを使うなら、なにかサーバーを立てて操作したいと思った。
過去にLINEbotを作ったという経験もあり、LINEbotで操作できるスマートロックを作ることとした。
今回の記事はLINEで動くスマートロック制作のためのサーバー構築編1。
ラズパイのセットアップからラズパイ本体にWebサーバーを構築、https通信でHelloWorldするところまで書いていく。
ただのメモなので再現性はないかも。参考程度に。
筆者のスキル
- 研究でnumpyやpandasを使ったデータ解析をしていた
- サーバー関係はEC2を使ってApacheでWebサーバーを構築できるレベル(ほぼ初心者)
- Herokuを使ってLINEbotを作ったことがある
- ラズパイ経験はなし
- 電気回路系は何もわからない
今回使うスキル
- Linuxの基本操作
- Flask
- uwsgi
- nginx
- Docker、Docker-compose
- line-bot-sdk
必要なもの
- RaspberrypiZeroWH
- ラズパイの電源ケーブル
- サーボモーター(SG92R)
- ジャンパワイヤー3本
開発環境
- Windows10
OSのインストール・SSH通信
宅配ボックスにRaspberrypiが、届き、ワクワクしながら箱を開ける。
最初からSDカードにOSが入ってるとのことなので、早速起動して、いざセットアップ・・・!!
・・・ん・・・?
あ!!!!!!有線のキーボードがない!!!!!!!!!!!!!!なにも操作できないじゃんか!!!!!!!!!
どうしよう、さっそく調べる。
どうやらSDカードであらかじめWifiのセッティングファイルをぶち込んでラズパイを起動することで、何も操作せずともラズパイにSSH通信を許可することが出来るらしい。
というわけで、OSのインストール方法とSSH通信の方法を書いていく。
OSのインストール
RaspberryPiImagerを使うと便利。
こちらを参照
SSH通信でしか操作しないならGUIもいらないので、
RaspberryPiOS(other) → RaspberryPiOSLiteでOK
GUIが入ってない分かなり軽量。
SSH
こちらを参照
要約すると、OSの入っているSDカード直下に以下のファイルを作ればOK
(何も書かない)
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="WifiのSSID"
psk="WifiのPW"
}
sshに「(何も書かない)」って書いちゃだめだよ!!
ファイルを生成し終えたら、RaspberrypiにSDカードをいれて早速起動!
5分くらい待ってから、自分のPCのコマンドプロンプトから以下のコマンドを実行
初期パスワードはraspberrypi
$ ssh pi@raspberrypi
pi@raspberrypi's password:(入力しても何も表示されないが、ちゃんと入力されてる)
色々表示されて、以下のような待ち受けになったら成功
pi@raspberrypi:~ $
Docker、Docker-composeをインストール
今まで使ったことなかったが、勉強のためにDockerを用いてサーバー構築することにした。
実際、使う必要もなかった気がするが・・・
ただ、また同じ環境を作りたくなった際、環境構築が楽になるかもしれない。
Dockerインストール
pi@raspberrypi:~ $ curl -sSL https://get.docker.com | sh
// グループの追加
pi@raspberrypi:~ $ sudo usermod -aG docker pi
// OS再起動(グループ追加を反映)
pi@raspberrypi:~ $ sudo shutdown -r now
// dockerサービスの有効化
pi@raspberrypi:~ $ sudo systemctl enable docker
// バージョン確認
pi@raspberrypi:~ $ docker --version
Docker version 20.10.5, build 55c4c88
Docker-composeインストール
githubにソースコードが落ちてるらしいので、そっちでインストールしたほうがいいと思うが、
pipでもインストールが可能らしく、個人的に使い慣れてるのでこちらを用いた。
ラズパイにvenv環境が最初から入っていたか覚えていないので、入っていなかったら各自インストールするように!
//venv環境の作成
pi@raspberrypi:~ $ python -m venv venv
//venv環境の中に入る
pi@raspberrypi:~ $ source venv/bin/activate
//pipのアップデート
(venv)pi@raspberrypi:~ $ pip install --upgrade pip
// docker-composeのインストール
(venv)pi@raspberrypi:~ $ pip install docker-compose
nginx+flaskでHTTP通信でHelloWorld!
docker-composeを用いてnginxサーバーとflaskサーバーをuwsgiを用いて繋げる
こちらを参照。
基本この記事のディレクトリ構成をパクればうまくいくはず。
あ、ただ、docker-composeは環境変数が設定されてないのでコマンド実行時は~/venv/bin/docker-composeと絶対パスor相対パスを指定しなければならないので注意。めんどくさい人は環境変数を設定してくれ!
ルーターのポートを開放してhttpリクエストを送信!
この記事の通りのディレクトリ構成にした後、自身のルーターのポート番号80番を開けて早速アクセス!
ルーターのポートの開け方は多分自身のルーターの説明書に書いてあるので、各自確認。
グローバルIPを確認したらブラウザに入力
http://グローバルIP
因みにグローバルIPアドレスはこのサイトで見れる。
https://www.cman.jp/network/support/go_access.cgi
成功!
ドメイン、DDNS取得
こちらの記事を参照
お名前.comでドメインを取得し、グローバルIPと関連付ける。
.workドメインであれば年間1円で取得できるから実質タダ。
グローバルIPは時々刻々で変化してていくので、DDNSサービスを用いる必要がある。
DDNSサービスを用いれば変化するグローバルIPとドメインを関連付けることが出来る。
DDNSサービスにはmydnsを用いた。
お名前.comでドメイン取得し、mydnsで動的IPとドメインを関連付けたら早速アクセス
http://www.自分の登録したドメイン
先ほどと同様HelloWorld!が表示されたら成功!
https通信
主な流れは以下の通り
- SSL証明書発行前の準備(main.pyを少し改造)
- Let's encryptで証明書発行
- nginxの設定ファイルを編集してポート443番解放、.pemを関連付ける
- ymlファイルの.pemの位置をマウントしdocker-compose実行
- ルーターのポート443を開放し、ブラウザでhttpsアクセス
SSL証明書発行前の準備
main.pyに以下の項目を追加。
これを追加しなきゃ正しく証明書を発行できない。
from flask import Flask, render_template, request, abort
app = Flask(__name__)
@app.route("/")
def hello_world():
return "hello world!"
############ ここを追加!! ###############################################
@app.route("/.well-known/acme-challenge/<filename>")
def well_known(filename):
return render_template('.well-known/acme-challenge/'+ filename)
########################################################################
if __name__ == "__main__":
app.run()
main.pyのファイルが入っているところにtemplate/.well-known/acme-challengeを作る
(venv)pi@raspberrypi:mkdir -p ~/app/template/.well-known/acme-challenge
(venv)pi@raspberrypi:touch ~/app/template/.well-known/acme-challenge/test.html
Let's encryptで証明書発行
(venv)pi@raspberrypi:sudo yum install certbot-apache
(venv)pi@raspberrypi:sudo certbot certonly
対話形式で指示に従って入力していく
How would you like to authenticate with the ACME CA?の質問に対してはwebrootの方を選択
あとはメアドとかドメインとか適当に。
/etc/letsencrypt/live/ドメイン名/ にpemファイル等が作成されてたら成功!
これをnginxディレクトリにコピー
(venv)pi@raspberrypi:mkdir ~/nginx/ssl
(venv)pi@raspberrypi:sudo cp /etc/letsencrypt/live/ドメイン名/fullchain.pem ~/nginx/ssl
(venv)pi@raspberrypi:sudo cp /etc/letsencrypt/live/ドメイン名/privkey.pem ~/nginx/ssl
nginxの設定ファイルを編集してポート443番解放、.pemを関連付ける
nginxの設定ファイルに以下の項目を追加
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
upstream uwsgi {
server uwsgi:3031;
}
server {
listen 80;
charset utf-8;
location / {
include uwsgi_params;
uwsgi_pass uwsgi;
}
}
##############ここを追加######################################
server {
listen 443 ssl;
charset utf-8;
location / {
include uwsgi_params;
uwsgi_pass uwsgi;
}
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
}
#############################################################
}
ymlファイルの.pemの位置をマウントしdocker-compose実行
ymlファイルに以下の項目を追加
version: "3"
services:
uwsgi:
# ビルドするDockerfileのでディレクトリ相対パス
build: ./app
# 指定したパスをコンテナにマウントする。"ホストのパス:コンテナのパス"となる
volumes:
- ./app:/var/www/
# 解放するポートを指定。"ホスト:コンテナ"のマッピング となる
ports:
- "3031:3031"
# コンテナ内の環境変数を指定する
environment:
TZ: "Asia/Tokyo"
nginx:
build: ./nginx
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
# nginxのログをホストOSの /tmp/nginx_log に出力する
- /tmp/nginx_log:/var/log/nginx
############ここを追加####################
- ./nginx/ssl:/etc/nginx/ssl/
#########################################
links:
- uwsgi
ports:
- "80:80"
################ここを追加################
- "443:443"
#########################################
environment:
TZ: "Asia/Tokyo"
ymlファイルの設定が完了したら、docker-composeを実行
//docker-composeを実行
(venv)pi@raspberrypi:~/venv/bin/docker-compose build && ~/venv/bin/docker-compose up -d
// 正しく実行されているか確認
(venv)pi@raspberrypi:~/venv/bin/docker-compose ps
ルーターのポート443を開放し、ブラウザでhttpsアクセス
自身のルーターの443ポートを開放。ルーターの説明書を参考に。
ブラウザでhttpsアクセスを試す
https://www.ドメイン名
HelloWorldが出力されたら成功!!!
疲れたので、今回はここまで!
次回はLINEとWebhookしてLINEbot作るよ!