GitHubActionsのSelf-hosted runnerで、SpringNativeのビルド時間を短縮する


SpringBootで作っているRestAPIアプリケーションを、SpringNativeでNative化しています。
Native化のハードルとして「ビルド時間が長い」ことが結構ストレスだったりします。

ローカルマシンだと、ビルドが30分近くかかったり、メモリ不足でビルド自体がエラーで落ちたりします。
AWSにビルドサーバー作ってビルド時間の短縮とかをしていたんですが、GitにPushしてビルドサーバーの方でPullしてというのがちょっと面倒。
GithubActionsでCIもしているが、どうにもこうにも遅かったり、メモリ不足でエラーになったりする。

その解決策として「Self-hosted runner」を使って強めのインスタンスでビルド時間の短縮を実現しました。


# 欲しい環境
・SpringNativeでNative-Buildできる環境
・Dockerが使える


# AWSで利用したUbuntuのAMI

時期によって更新されていくので日付の部分は探す際には、違う日付になっている場合があります。


```
ubuntu-focal-20.04-amd64-server-20210430
```

# docker-ceインストール
```
#docker-ce install
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y docker-ce
sudo systemctl enable docker
sudo systemctl start docker
```

## docker実行時にsudoしなくていいように
```
sudo gpasswd -a $USER docker
```

    
ここで、設定反映のため一度ログアウトして再ログインする
  
  

## dockerの実行テスト
```
#docker test
docker run hello-world
```

# SpringNativeのビルド環境を作っていく

## 必要なライブラリ
以下のライブラリのインストールが必要でした。
※状況によって適宜必要なライブラリは入れてください。

```
sudo apt-get update && sudo apt-get upgrade
sudo apt install -y zip
sudo apt install -y gcc
sudo apt-get install build-essential
```

## GraalのJava11を入れる

springのドキュメントをもとにセットアップしていきます。

```
#java11 graal
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install java 21.2.0.r11-grl
sdk use java 21.2.0.r11-grl
gu install native-image
```

#### springの参考資料
https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#getting-started-native-build-tools

#### sdkmanについてはこちら
https://sdkman.io/





## 自分は「maven」使っているのでインストール
```
#maven
sudo apt install -y maven
```


## Self-Hosted Runnerの設定
ここまで設定したら、GitHubActionsのSelf-hosted runnerとして使う設定をします。
Githubのリポジトリで「Setting > Actions > Runners」から「Add Runner」する。
「OS」と「Archtecture」は、利用したいインスタンスに合わせて設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27112/f1b98c5f-26e3-6527-7bb2-5aee1c88ee97.png)


### こんな感じで設定画面が出るので適宜設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27112/55e86944-baa1-59ec-6edd-2c2806c7e9dd.png)

### 設定完了したら実行
ターミナルを閉じても実行され続けるように、バックグランドで実行させる。

```
#self hosted runner. for background.
cd ~/actions-runner
nohup ./run.sh &
```

### 実行されているかプロセス確認
実行されていますね。

```
ps -a
   PID TTY          TIME CMD
 18425 pts/0    00:00:00 run.sh
 18429 pts/0    00:00:00 Runner.Listener
 18445 pts/0    00:00:00 ps
```


### 終了させたい場合はkill
```
kill <PID>
```


### ssh接続を切って、githubからSelf-hosted runnerの稼働状況を確認します。
動いてますね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27112/7ee7b873-5126-80f0-5a65-f445a3e8a43e.png)




# 実際にCIを動かしてみます。
GithubActionsの使い方についてはここでは話しませんので、
公式のドキュメントなど見てみてください！
https://docs.github.com/ja/actions



# ビルド時間がどう変わったか

### GitHubの標準のRunnerの場合（ubuntu-20.04）
#### 約19分（18分41秒）
ローカルよりは早いけど、メモリが足りないときはどうしようもないです。
大きなプロジェクトになると、メモリエラーでビルド自体できなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27112/457e1470-0e88-b8fc-d9d8-cc2734fdb919.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27112/ccd69f4d-beb5-ab25-bc66-c9e6b3f07f78.png)


### Self-hosted runnerの場合（ubuntu-20.04 c5n.4xlarge 16vCpu/32GB）
#### 約6分（5分51秒）
結構早くなりました！このくらいなら我慢できる。
もっとハイスペックなマシンを用意してスレッド設定をもっと増やしたら、もっと早くなるかも。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27112/604122e1-cd30-bb63-becc-498e9db1adac.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27112/066050b9-088e-5d52-5ba8-04ba415238d9.png)



# 最後に

今回は、「Self-hosted runner」をEC2で作っています。
必要に合わせて起動したり停止したりする予定ですが、Fargateなどで必要な時だけ自動で起動、終わったら終了するようにするのもいいかもしれませんね。

時間ができたらやってみたいと思います。


# 余談

SpringNative化したRestAPI アプリケーションの起動時間は「0.134s」と爆速。
もともとは20秒程度だったので、爆速になりました。
kubernetesでのPod起動も数秒になりました！ここはProbe設定の調整が必要です。
オートスケールやノード障害時に正常なノードでのPodの起動処理もめちゃくちゃ早くなって、提供サービスの可用性が高くなるので良さそうです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27112/4d4c062b-3b95-5a6b-ed09-d498b0f01536.png)


あと、「作業マシンのメモリを増強したら？」と言われたんですが、会社のリースのマシンでは箱開けちゃまずいので、それは無理っすｗ