Spring Boot＋MySQLで作成したWebサイトをさくらのVPSにデプロイする手順

# はじめに
SpringBoot＋MySQLで作成したWebサイトをさくらのVPS上にデプロイするまでの手順を備忘録としてまとめます。

# 1.ドメインを用意する
好きな所で取得してください。
私は[Xserverドメイン](https://www.xdomain.ne.jp/)で取得しました。

# 2.さくらのVPSを契約する
システムにあったサーバープランを選びます。
どれを選択してよいか迷ったのでChatGPTに確認しました。

| プラン名 | CPU | メモリ | SSD | 用途 |
| ---- | ---- | ---- | ---- | ---- |
| 1Gプラン | 仮想2コア | 1GB | 50GB | 個人ブログ、小規模サイト |
| 2Gプラン | 仮想3コア | 2GB | 100GB | 一般的なWEBサイト、Spring Bootの標準環境 |
| 3Gプラン | 仮想4コア | 4GB | 200GB | 企業用、アクセスの多いサイト |

私の場合は2Gプランがよさそうだったので、Ubuntu24.04の2Gプランを選択しました。
契約完了後、以下の情報を控えておいてください。
* IPアドレス
* SSHユーザ名
* 初期パスワード

# 3.VPSへのSSH接続と初期設定
契約したVPSにSSH接続します。
```:ローカルPCのコマンドプロンプト等
ssh ユーザー名@IPアドレス
```

```:VPS上のターミナル
sudo apt update
sudo apt upgrade -y
```

# 4.Java ＆ MySQLのインストール
VPS上でJavaとMySQLをインストールします。

### Javaのインストール
開発環境と同じバージョンを選択してください。
```:bash
sudo apt install openjdk-21-jdk -y
```

### MySQLのインストールと設定
インストール
```:bash
sudo apt install mysql-server -y
```

セキュリティ設定
```:bash
sudo mysql_secure_installation
```

データベース作成（例）
```:bash
sudo mysql -u root -p
```
```SQL:DB作成.sql
CREATE DATABASE DB名;
CREATE USER 'ユーザ名'@'localhost' IDENTIFIED BY 'パスワード';
GRANT ALL PRIVILEGES ON DB名.* TO 'ユーザ名'@'localhost';
FLUSH PRIVILEGES;
EXIT;
```

DBの作成が完了したら必要なデータを投入してください。

# 5.Spring Bootアプリの準備
jarファイルをビルドしてVPS上に配置します。

### プロジェクトのインポート
1. Eclipse上のメニューから「ファイル」→「インポート」を選択する
2. 「既存のMavenプロジェクト」を選択し、「次へ」をクリックする
3. プロジェクトのルートディレクトリを指定し、「完了」をクリックしてプロジェクトをインポートする

### Mavenビルドでjarファイルを作成
1. プロジェクトを右クリックする
1. 「実行/デバッグ」→「Maven ビルド...」を選択する
1. 「目標（Goals）」欄に「clean package」と入力する
1. 「実行」をクリックすると、EclipseがMavenビルドを開始し、ビルドが成功するとプロジェクト内の「target」フォルダにjarファイルが生成される

### jarファイルの起動
作成されたjarファイルをさくらのVPSに転送します。
私はWinSCPで転送しましたが、以下コマンドでも行けると思います。
```:bash
scp target/webapp.jar ユーザー名@VPSのIPアドレス:/home/ubuntu/
```



VPS上で以下のコマンドを実行し、アプリを起動します。
```:bash
java -jar webapp.jar
```

# 6.Spring Bootをsystemdで常駐化する
/etc/systemd/system配下にserviceファイルを作成し、以下を記述します。
構成は以下の通りです。
* [Unit]：サービスの説明と依存関係を指定
    * Description：サービスの概要説明
    * After：起動順序（例：ネットワーク起動後に開始）
* [Service]：実際に実行されるサービス内容を指定
    * User：サービスを実行するユーザー
    * ExecStart：実行するコマンド。今回場合はJavaコマンドでjarを実行
    * WorkingDirectory：実行時の作業ディレクトリ
    * SuccessExitStatus：Javaの正常終了時のコード
    * Restart：サービスが異常終了した際に再起動する設定
    * RestartSec：再起動までの待機秒数
* [Install]：systemctlでサービスを有効化する際の設定
    * WantedBy：起動時に自動実行する設定


参考：[systemdの*.serviceファイルの書き方](https://qiita.com/masami256/items/ef0f23125cf8255e4857)

```Service:webapp.service
[Unit]
Description=webapp
After=network.target

[Service]
User=ubuntu
ExecStart=/usr/bin/java -jar /home/ubuntu/web/jar/webapp.jar
WorkingDirectory=/home/ubuntu/web/jar
SuccessExitStatus=143
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

上記を保存したら以下のコマンドを実行してください。

```:bash
sudo systemctl daemon-reload
sudo systemctl enable webapp.service
sudo systemctl start webapp.service
```

# 7.Nginxをリバースプロキシとして導入する
必須ではないのですが、SSL対応、セキュリティ強化のために行います。

### Nginxインストール
```:bash
sudo apt install nginx -y
```

### 設定ファイル編集
以下の設定を/etc/nginx/sites-available/defaultに記載します。

```Nginx:nginx
server {
    listen 80;
    server_name webapp.com www.webapp;

    location / {
        proxy_pass http://localhost:8080;
        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;
    }
}
```

### Nginxを再起動する

```:bash
sudo systemctl restart nginx
```

# 8.ドメインのDNS設定
XServerドメインのDNSレコード設定画面で、以下の設定を追加します。

* ホスト名：「空欄」と「www」の2種類
* 種別：A
* 内容：VPSのIPアドレス

# 9.SSL設定

### Certbotのインストール

```:bash
sudo apt install certbot python3-certbot-nginx
```

### 証明書の発行

```:bash
sudo certbot --nginx -d webapp.com -d www.webapp.com
```

成功すると、自動でNginx設定にSSLが組み込まれます。
証明書発行に失敗する場合はさくらのVPSのパケットフィルターで、80番・443番ポートを許可しているか確認してください。

# おまけ（jarファイル更新手順）
Webアプリを更新した場合は以下手順で更新可能です。

### 1.最新のjarファイルをVPS上に配置

### 2.systemdサービスの確認と停止

```:bash
sudo systemctl stop webapp.service
```

### 3.新しいjarに入れ替える

### 4.Spring Bootサービス再始動

systemdで再度アプリを起動

```:bash
sudo systemctl start webapp.service
```

起動状態を確認

```:bash
sudo systemctl status webapp.service
```

### 5.更新をブラウザで確認
実際にブラウザからアクセスし、変更が反映されているか確認する。

### 6.再起動がうまくいかない場合

以下コマンドでログを確認する。

```:bash
sudo journalctl -u webapp.service -f
```

### 7.古いプロセスが残ってしまった場合

以下コマンドで再起動する。

```:bash
sudo systemctl restart webapp.service
```