Expressで作成したウェブサーバをSystemdに登録してsystemctlで起動させる

# 概要
## はじめに
- Node.jsを使用してWebアプリケーションを構築し、Unixの上でApacheと同様に常に起動させる方法について今回説明します。
- 対象はUnixについて多少知識がある方、Expressなどでウェブサーバの作成ができる方です。
- ShellScriptを作成して実行しますが、ShellScript内は、シェパン（`#!/bin/bash`）とnodejsを実行させるコマンドのみなので、構えなくても大丈夫です。
## やりたいこと
- Expressで作成したWebサーバをSystemdに登録して、`systemctl`を使用して常に起動させたい。
# 環境
## 対象OS
- Debian/Ubuntu
- RHEL/CentOS Stream
- RHEL/Amazon Linux2

## npmパッケージ
- Express (Webサーバ構築)
    - 公式サイト：https://www.npmjs.com/package/express

# 手順
### 1. ディレクトリ作成とファイルの作成
- ディレクトリ作成
```　bash:mkdir
$mkdir MyProject
```
- ディレクトリ内に移動
```bash:cd
$cd MyProject
```
### 2. npm 初期化とパッケージのインストール
#### npmの初期化
```bash:npm
$npm init
```
#### Expressのインストール
```bash:npm install
$npm i express --save
```

### 3. ソースコード準備
#### 今回は、サンプルとしてGETで`/`にアクセスしたら`hello world`が表示される処理を作成。
```javascript:MyProject/index.js
const express = require('express');
const app = express();

app.get('/',(req,res)=>{
    res.send('hello world');
});

app.listen(3000,()=>{
console.log("Server Start: Posr 3000");
});
```

### 4. ShellScriptファイル作成
#### ShellScriptファイルを作成
- MyServerという実行可能ファイルを出力します。`-o`の後に実行可能ファイルの名前を指定できますが、ここは自由に変更可能です。
- `-o`のオプションをつけない場合は、プロジェクト名（今回の場合、`MyProject`）で出力されます。
```bash:vi ~/MyServer
$vi ~/MyServer
```

```shellscript:/usr/bin/MyServer
#!/bin/bash
node ~/MyProject/index.js
```
### 5. ShellScriptファイルをパスの効いたディレクトリに移動
#### /usr/bin/にSellScriptファイルを移動
```bash
$sudo mv ~/MyServer /usr/bin/
```
- パスが通っているディレクトリは、下記のコマンドで確認できます。
```bash
echo $PATH
```
### 6. Systemdの設定
#### /etc/systemd/system/MyServer.serviceの作成
- `/etc/systemd/system/`内に新たに`/etc/systemd/system/MyServer.service`ファイルを作成
```bash
$sudo vi /etc/systemd/system/MyServer.service
```
- `/etc/systemd/system/MyServer.service`内にの設定を記述
```config:/etc/systemd/system/MyServer.service
[Unit]
Description = MyServer

[Service]
ExecStart = /usr/bin/MyServer
Restart = always
Type = simple

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

### 7. systemcltのdaemon-reloadでdaemonリロード
#### systemctlのdaemonをリロードしてMyService.serviceファイルをUnitに認識させる
```bash
$sudo systemctl daemon-reload
```
- Unitに認識できているかは下記のコマンドで確認できます。

```bash
$sudo systemctl list-unit-files --type=service | grep MyServer
```

### 8. systemctlで起動できるか確認
#### 起動コマンドコマンド実行
```bash
$sudo systemctl start MyServer
```
#### 正常に動作できているか確認
```bash
$sudo systemctl status MyServer
```
- 正常に動作できている場合の表示
```bash
● MyServer.service - MyServer
     Loaded: loaded (/etc/systemd/system/MyServer.service; disabled; vendor preset: enabled)
     Active: active (running) since Wed 2022-11-02 13:25:31 JST; 3s ago
   Main PID: 111384 (sesm)
      Tasks: 6 (limit: 9000)
     Memory: 16.7M
     CGroup: /system.slice/MyServer.service
             └─111384 /usr/bin/MyServer
11月 02 13:25:31 ubuntu-pc systemd[1]: Started MyServer.
11月 02 13:25:33 ubuntu-pc MyServer[111384]: Server Listening : Port 3000

```
- 不具合の場合の表示
```bash
● MyServer.service - 
     Loaded: loaded (/etc/systemd/system/MyServer.service; disabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2022-11-02 13:24:47 JST; 1s ago
    Process: 111093 ExecStart=/usr/bin/MyServer (code=exited, status=203/EXEC)
   Main PID: 111093 (code=exited, status=203/EXEC)
```
- 不具合の原因については、上記のメッセージの下に、処理のログが表示されます。
- エラーメッセージなどが表示されるので、参考にしながら原因の解決を行なってください。

#### 以上で完了！　補足情報
- 以上で設定は完了になります。
- サーバをストップさせるには下記のコマンドを使用します。
```bash
$sudo systemctl stop MyServer
```
- サーバの再起動の場合は
```bash
$sudo systemctl restart MyServer
```
- サーバ本体の再起動などを行なった際に自動でMyServerを起動する場合
```bash
$sudo systemctl enable MyServer
```