Amazon Linux 2 で unicorn を systemd を使って立ち上げる

# 環境

- Amazon Linux 2

# まとめ

- systemd 用ユニットファイルを作成する
- systemd を使って起動、及び自動起動の設定を行う

# 手順

## ユニットファイルの作成

- nginx の前に起動する前提。nginx のインストール及び設定手順は[こちら](https://qiita.com/piggydev/items/db3bb03d8b6ad10fafa4)。
  - 依存関係と起動順序は別の概念。 
  - 起動順序の指定がない場合、依存関係のあるユニットについても並列に起動処理が行われます。
- permission は 644 にする（実行権限が付いていた場合、エラーになります）。
- 停止した場合は、自動復旧（起動）を行う。

```/etc/systemd/system/unicorn.service
[Unit]
Description=The unicorn process
Before=nginx.service
After=network.target remote-fs.target nss-lookup.target

[Service]
User=some_unicorn_user
WorkingDirectory=/var/www/somewhere
SyslogIdentifier=unicorn
Type=simple
Restart=on-failure

Environment=RAILS_ENV=production
Environment=UNICORN_CONF=/var/www/somewhere/config/unicorn.rb
Environment=BUNDLE_GEMFILE=/var/www/somewhere/Gemfile
EnvironmentFile=/etc/environment

ExecStart=/bin/bash -l -c 'bundle exec unicorn_rails -c ${UNICORN_CONF} -E ${RAILS_ENV} -D'
ExecStop=/usr/bin/kill -QUIT $MAINPID
# The unicorn process is gracefully restarted with `kill -USR2 <PID>` along with the setting
# in the before_fork hook in config/unicorn.rb.
# ref: https://tachesimazzoca.github.io/wiki/rails3/unicorn.html
ExecReload=/usr/bin/kill -USR2 $MAINPID

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

- `/usr/lib/systemd/system` には RPMパッケージが提供するデフォルト設定が配置されます。
  - ユーザが追加するものは `/etc/systemd/system/<foo>.service` とします。
  - 両方のディレクトリに同名のユニットファイルがある場合は、後者（`/etc/systemd/system/`）のファイルが優先されます。
- 今回はやっていませんが、systemd の起動ファイルから更にシェルスクリプトを呼ぶ場合は `/opt/<package_name>/bin/<script_name>(.sh)` に置きます。unicorn の場合は `/opt/unicorn/bin/unicorn`（要実行権限）。それを `ExecStart` 等に指定します。
- [Environment / EnvironmentFile では変数展開できません](https://qiita.com/kobanyan/items/f8e8a3bd5406e1d290fb)

## config の書式が正しいことを確認する

```
$ sudo systemd-analyze verify /etc/systemd/system/unicorn.service
```

## 設定を反映する

- ユニットファイルを追加、削除、修正した場合は、必ず以下のコマンドを実行する（実行せずに `start` しようとした場合は、エラーが出力され起動できない）。

```
$ sudo systemctl daemon-reload
```

## 起動順の依存関係を確認する

```
$ systemctl list-dependencies --before unicorn.service
unicorn.service
● ├─nginx.service
● ├─multi-user.target

```

## 起動

```
$ sudo systemctl start unicorn.service
```

## 起動確認

```
$ sudo systemctl status unicorn
```

## 停止確認

```
$ sudo systemctl stop unicorn.service

$ sudo systemctl status unicorn

$ ps -ef | grep unicorn | grep -v grep
→ プロセスが存在しないことを確認
```

## 再起動確認

```
$ sudo systemctl start unicorn.service

$ sudo systemctl reload unicorn.service

$ sudo systemctl status unicorn

$ ps -ef | grep unicorn | grep -v grep
→ プロセスが存在すること確認
```

## 自動起動設定

```
$ systemctl is-enabled unicorn.service
disabled

$ sudo systemctl enable unicorn.service

$ systemctl is-enabled unicorn.service
enabled
```

## OS を再起動してみて、nginx が自動起動されることを確認

```
$ sudo reboot
```

## systemd に関する参考資料

以下のページを参考にさせて頂きました。

- [Systemd入門(1) - Unitの概念を理解する](https://enakai00.hatenablog.com/entry/20130914/1379146157)
- [Systemd入門(4) - serviceタイプUnitの設定ファイル](https://enakai00.hatenablog.com/entry/20130917/1379374797)
- [SYSTEMD のユニットファイルの作成および変更@Red Hat Customer Portal](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files)
  - ほとんどの場合、ユニットファイルオプションの After および Before で依存関係の並び順を設定するだけで十分です。Wants (推奨) または Requires で要件の依存関係も設定する場合は、依存関係の並び順を指定する必要があります。これは、並び順と要件の依存関係が相互に依存していないためです。