2023年GWなのでラズパイ買ってきてWebサーバーとして公開した件

# GWなのでラズパイ買ってきてWebサーバーとして公開した件

インストーラーのアップデートなどで過去の記事の内容が古くなっていたので一応最新っぽいものを乗せます。
全世界公開しているので自分でセキュリティの知識を得てから使ってください。責任は持てません。
やばそうなところあったら編集リクエストくださると・・・

## ラズパイ購入する

* メルカリで購入しました
* https://jp.mercari.com/search?keyword=ラズパイ

## ラズパイをインストールする

2023年にはRaspberry Pi Imagerというインストーラーを使うやり方が主流みたいです。

* [公式](https://www.raspberrypi.com/software/)からダウンロードしましょう。
* ここが参考になりました https://nw-electric.way-nifty.com/blog/2022/05/post-2cdd01.html

初期ユーザー `user＝pi、password＝raspberry` は2022年からデフォルトで存在しないので、設定から作りましょう。以下参考

<details>
<summary>ラズパイへのアクセスはSSH/CUIのみの方向け</summary>

![スクリーンショット 2023-05-07 23.14.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/2a5b68d2-95bb-730a-1108-33edd61d9990.png)


* OSはPI OS Lite （ダウンロード早いです）
* 画面右下の設定マークからSSH設定を作れます

一応以下設定乗せます。mac側から `ssh pi` でログインできるようにしてます。

```terminal
$ vim ~/.ssh/config

Host pi
  HostName raspberrypi.local # http://192.168.0.23/, `$ ip addr`
  User ykhirao
  IdentityFile /Users/ykhirao/.ssh/id_rsa_pi

$ ssh pi
$ ykhirao@raspberrypi:~ $
```

</details>


## サーバーを用意する

nginx でも Apacheでも適当なミドルウエアとphpでもnodejsでも何でもいいのでアプリケーションサーバー選ぶ。
何いっているのという方は[適当な記事](https://www.rworks.jp/system/system-column/sys-entry/14865/)を読む。

今回は `nginx x nodejs` にしますが、ApacheのC10K問題とかまでアクセスされる予定ないので（ラズパイのメモリ性能とかが先に限界迎えるはず・・・）自分の好きな環境とか身近な記事を参考にするとよいと思います。


上記記事と同様に設定すると、以下のコマンドを入力してサーバーを立ち上げ

```terminal
$ node index.js
```

同じネットワーク内から `http://raspberrypi.local/`　か http://192.168.0.23/ (人によってIP違う可能性あり) にアクセスしたとき `nginx` のミドルウエアが動き `nodejsサーバー` にアクセスします。うまく設定できてたら `Hello World` が表示させましょう。


<details>
<summary>コマンドまとめと参考記事</summary>

```terminal
# パッケージを最新版へ
$ sudo apt-get update
$ sudo apt-get upgrade

# ミドルウエア
$ sudo apt install nginx -y

# nodejsのインストール（nが使いたいのでもろもろやってます）
$ sudo apt install nodejs npm
$ sudo npm install n -g
$ sudo n lts
$ sudo apt purge nodejs npm

# アプリケーションサーバーの作成
$ sudo mkdir -p ~/workspace/piapp
$ sudo vi ~/workspace/piapp/index.js
# 下記ファイルを参考に修正する
$ sudo vi /etc/nginx/sites-enabled
# 下記ファイルを参考に修正する

# アプリケーションサーバーの立ち上げ
$ sudo npm install nodemon -g
$ nodemon ~/workspace/piapp/index.js

# nodejsプロセスが死んでも自動で再起動させるため nodemon を利用してます。
# 必要なければ node ~/workspace/piapp/index.js でよいです。
```

```~/workspace/piapp/index.js
const http = require("http"); 
const server = http.createServer(function (req, res) {
    res.statusCode = 200;
    res.setHeader("Content-Type", "text/plain");
    res.end("Hello World");
});
server.listen(3000);
```

```/etc/nginx/sites-enabled
	location / {
		try_files $uri $uri/ =404;
		proxy_pass http://localhost:3000;
	}
```


参考記事

* [UbuntuサーバーにnginxとNode.jsを入れてWebサーバーを建てる](https://hondakenya.work/ubuntu-nginx-node-js/)を参考にしました。
* [Ubuntu で Node の最新版/推奨版を使う (n コマンド編)](https://qiita.com/cointoss1973/items/c000c4f84ae4b0c166b5)

</details>

## 自宅のルーターにポート転送設定して全世界公開します

http://raspberrypi.local/ は同じネットワーク内のPC・スマホ等からしかアクセスできませんが、noipで作った http://example.hopto.org/ みたいなアドレスにアクセスすると `Hello World` と表示できたらOKです。 全世界に公開できました。

参考にした記事
* [安全にラズパイWebサーバーを世界に公開するための手順](https://ichiken-usa.blogspot.com/2022/01/raspi-web-server.html)

ポートフォワーディングを使って安全に公開しましょう。

### ファイヤーウォール設定

<details>
<summary> Ubuntuのデフォルトのufwで設定 </summary>

ラズパイに上で以下コマンド

```terminal
$ sudo apt install ufw
$ sudo ufw allow http
$ sudo ufw allow https
$ sudo ufw allow ssh
# sshでアクセスするので必要。失敗したらsshできず終わる。

$ sudo ufw enable

# ラズパイの再起動
$ sudo reboot
```

</details>


### DDNS作成

自宅のIPアドレスは定期的に変更されます。以下のようなサイトで確認できます。

* [アクセス情報【使用中のIPアドレス確認】](https://www.cman.jp/network/support/go_access.cgi )
* [JCOMでグローバルIPアドレスを変更しようとした話](https://tarufu.info/jcom-global-ip/)

自宅のIPがころころ変わったら、ラズパイにアクセスできないのでもろもろいろいろやってくれるサイトにアカウント作るって話です。詳しくは調べてください。

<details>
<summary>NOIPというサイトを使います</summary>

noipのパスワードは後でJCOMルーター上の設定で必要となるので、共通で使っているもの以外がいいと思います。chromeに覚えさせましょう。

参考記事
* [No-ip のアカウント及びDDNSサーバーアドレスの取得方法](https://www.try-e.co.jp/manual/getnoip.pdf)

</details>

### ルーターのDDNS設定

<details>
<summary> 筆者はJCOMなのでその設定 </summary>

http://192.168.0.1/ か http://192.168.100.1/ でアクセスできる。

初期ID/PASSは以下ですが変更しましょう。

```terminal
ID: admin
Password: password
```

設定項目は以下スクショを参考に、先程作ったnoipの情報を使ってください。

![スクリーンショット 2023-05-08 0.03.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/660c98fb-5d38-ab87-efd2-0e845d91c284.png)


参考にした記事
* [HUMAX HG100R-02JG の ポート開放設定](https://homemadegarbage.com/humax-port)

</details>

### ポートフォワーディング設定

ここまでできたらグローバル

<details>
<summary> 筆者はJCOMなのでその設定 </summary>

![スクリーンショット 2023-05-08 0.12.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/a043418e-2e00-5e3f-f888-83fe85bbd1a9.png)


</details>

## https/ssl化

最近のcertbotは [公式サイト](https://certbot.eff.org/instructions?ws=nginx&os=ubuntubionic) で自分のOS等を設定してそのコマンド通りにやるみたいです。過去記事は基本真似しないように。

```terminal
$ sudo apt -y install snapd
$ sudo snap install core; sudo snap refresh core
$ sudo apt-get remove certbot
$ sudo snap install --classic certbot
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
$ sudo certbot --nginx
```

自動処理のためcronの編集。毎月1日、朝4時に更新。 `--force-renewal` で残り30日を待たずに毎月更新、nginxの再起動付き。 作りたてなので本当に動くかわからない。

```terminal
$ sudo crontab -u root -e
00 04 01 * * sudo certbot renew --force-renewal && sudo systemctl restart nginx
```

１時間に5回失敗するとしばらく使えないのでドライランで実行結果だけ見る。

```terminal
$ sudo certbot renew --dry-run
```

nginxのサーバー設定に追記する。pemの位置は `sudo certbot --nginx` で設定したものを書いてください。


```
        server {
          listen 443 ssl;
          ssl_certificate     /etc/letsencrypt/live/example.hopto.org/fullchain.pem;
          ssl_certificate_key /etc/letsencrypt/live/example.hopto.org/privkey.pem;
        }
```


ラズパイ上のalias設定

```terminal
ykhirao@raspberrypi:~ $ cat ~/.bashrc
alias fix_nginx="sudo vim /etc/nginx/sites-available/default"
alias start="sudo systemctl start nginx && nodemon ~/workspace/piapp/index.js"
alias stop="sudo systemctl stop nginx"
```

httpsでアクセスして、こんな感じに `保護されていない通信` とでなくなったらOK

![スクリーンショット 2023-05-08 0.59.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/e1d6db9f-c932-56e1-e39a-b8f9cc0f1174.png)



<details>
<summary> ここまでのnginx設定 </summary>

```terminal
ykhirao@raspberrypi:~ $ cat /etc/nginx/sites-available/default

server {
	listen 80 default_server;
	listen [::]:80 default_server;

	ssl_certificate     /etc/letsencrypt/live/example.hopto.org/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.hopto.org/privkey.pem;
	listen 443 ssl;

	root /var/www/html;

	index index.html index.htm index.nginx-debian.html index.js;

	server_name example.hopto.org;

	location ~ /.well-known {
		allow all;
	}

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
		proxy_pass http://localhost:3000; # ★追加
	}
}
```
</details>

## forever使ってnodejsをバックグラウンドで実行する

```terminal
$ npm install -g forever
$ forever index.js
```

## VSCodeでRemote開発をしよう

[Remote DevelopmentPreview](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)


<details>
<summary>設定のスクリーンショット</summary>

* `CMD + SHIFT + P` もしくは `CMD + P` でメニューを出して `>` を入力
* `SSH` と打つと出てくる　`Remote SSH: connect to host` を選択

![スクリーンショット 2023-05-08 14.38.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/a8d3bc43-fc46-a5c8-57f8-42e8c3b344d4.png)

ssh configを設定してたら出てくるのでpiを選択する。一応再掲する。

```terminal
$ vim ~/.ssh/config

Host pi
  HostName raspberrypi.local # http://192.168.0.23/, `$ ip addr`
  User ykhirao
  IdentityFile /Users/ykhirao/.ssh/id_rsa_pi
```

![スクリーンショット 2023-05-08 14.38.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/a49d2c1b-73d0-f4d0-4eb4-3227d63ecf16.png)

VSCodeでRemote開発できるようになりました。

![スクリーンショット 2023-05-08 14.38.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/9ca558a3-ea66-a933-b135-43541e9b9679.png)


</details>