LAN内でもURLを使いたい

## やりたいこと

* 自宅でいくつかのwebアプリサーバーを立ち上げていますが、そろろそ`IPアドレス:ポート番号`とサービスを紐づけるのが大変になってきました
* nginxを立ち上げてリバースプロキシ設定を行い、`IPアドレス:ポート番号`と`URL`の紐付けを行わせたいと思います
* 例として`jupyter.home`というドメインと`192.168.1.3:8888`の紐付けを起こっていきます

## やらないこと

* DNS設定
家ではNuro光を利用しています。割り当てられたルーター(ONU)はHG8045Qでした。`192.168.1.1`にアクセスしたところDNSサーバーの役割もしてくれることがわかったので、そこで登録して名前解決させています。
:::note warn
ドメイン名と紐づけるのはnginxを立ち上げたサーバーであることを注意してください。
:::


## インストール
nginxのインストールを行います。

### 参考

nginxのインストールは以下を参考にしました。
* [Ubuntu22.04 nginx最新の安定版をインストールする](https://qiita.com/lustm5/items/aabd365aaeb873e7b17a)
### 準備
```bash
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
```

### nginxの公開鍵でダウンロード先の正当性確認
```bash
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
    
gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list
```

### インストール

```bash
sudo apt update
sudo apt install nginx
```

### 起動

```bash
sudo systemctl start nginx
sudo systemctl status nginx
nginx -v #バージョンを表示させて起動確認
```

### 設定

リバースプロキシの設定をしていきます
* サーバー上の全ての設定ファイルを`/etc/nginx/sites-available`ディレクトリに置き、有効な設定ファイルを`/etc/nginx/sites-enabled`に置いてで分けるのがベストプラクティスらしいです

#### ディレクト作成
```bash
sudo mkdir /etc/nginx/{sites-available,sites-enabled}
```

#### `nginx.conf`の設定
site-enabledを読み込む設定を`/etc/nginx/nginx.conf`に加えます
```diff_nginx:nginx.conf
 
 user  nginx;
 worker_processes  auto;
 
 error_log  /var/log/nginx/error.log notice;
 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;
 
     include /etc/nginx/conf.d/*.conf;
+    include /etc/nginx/sites-enabled/*;
 }

```

#### ドメイン名とIPアドレス:ポート番号の紐付け

```nginx:/etc/nginx/sites-available/home
# サーバーブロック
server {
    listen 80 ;
    listen [::]:80; 
    server_name jupyter.home;

    # リクエスト処理
    location / {
        proxy_pass http://192.168.1.3:8888;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

}
```
* `sites-enabled`配下を読み込む設定しかしていないので、シンボリックを張る
```bash
sudo ln -s /etc/nginx/sites-available/home /etc/nginx/sites-enabled/
```

* テストと有効化
```bssh
sudo nginx -t
sudo systemctl reload nginx
```
### おまけ

* サーバー名が重複していないか確認して、設定を追加するスクリプト
* シンボリックを張ったりはしないので、2回目以降に使ってください
* 使う場合は`chmod +x /update_nginx.sh`で実行権限を渡して、`sudo ./update_nginx.sh`で実行する。
```bash:update_nginx.sh
#!/bin/bash

# 引数からサーバー名とIPアドレス:ポート番号を取得
SERVER_NAME=$1
IP_PORT=$2

# 設定ファイルのパス
CONFIG_FILE="/etc/nginx/sites-enabled/home"

# サーバー名の重複確認
if grep -q "server_name $SERVER_NAME;" $CONFIG_FILE; then
    echo "Error: Server name $SERVER_NAME is already in use."
    exit 1
fi

# 新しいサーバーブロックを設定ファイルに追加
echo "Adding new server block for $SERVER_NAME to $CONFIG_FILE"
sudo tee -a $CONFIG_FILE > /dev/null <<EOF

server {
    listen 80;
    server_name $SERVER_NAME;

    location / {
        proxy_pass http://$IP_PORT;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
    }
}
EOF

# Nginxの構文チェック
echo "Checking Nginx configuration syntax..."
sudo nginx -t

if [ $? -ne 0 ]; then
    echo "Nginx configuration test failed."
    exit 1
else
    echo "Nginx configuration test passed."
     # DNS設定の更新を促すメッセージを表示
    echo "Please make sure to update your DNS settings to point $SERVER_NAME to the appropriate IP address."

    # Nginxをリロードするコマンドを表示
    echo "To apply the new configuration, run: sudo systemctl reload nginx"
    
    # ここでnginxをリロードする場合は、以下のコメントを解除
    # sudo systemctl reload nginx
    # echo "Nginx reloaded successfully."
fi
```

実行
```bash
./update_nginx.sh jupyter.uhome 192.168.1.3:8888
```

## 接続

この時点で`http://jupyter.uhome`へアクセスすると`192.168.1.3:8888`で立ち上げたサーバーにアクセスできます。