# OS 起動時の自動起動（systemd）

MAESTRO を systemd サービスとして登録し、マシンの起動時に自動で立ち上げる手順。
プロセス監督・異常終了時の自動再起動・ログ集約（journald）も systemd が担う。

## 前提と役割分担

- **`scripts/server.sh`** … ビルド・手動運用・開発用。`start` は毎回ビルドしてから
  `dist/main.js` を起動する。
- **systemd サービス** … boot 自動起動と本番のプロセス監督用。ビルドはしない
  （`node dist/main.js` を直接監督する）。

> **同時起動しないこと**。`server.sh start` が動かしているプロセスと systemd の
> サービスを両方立てると、同じ DB に対して二重起動になる（`instance-lock` が最悪の
> 破損は防ぐが、正しくない状態）。systemd に任せると決めたら、運用中の起動・停止は
> `systemctl start/stop` に統一し、`server.sh start` は使わない。

## インストール

まずビルドして `dist/` を最新にする（**root では実行しない**。アプリを動かすユーザーで）。

```bash
scripts/server.sh start   # ビルド＋起動を確認。この後 stop して systemd に委ねる
scripts/server.sh stop
```

生成されるユニットを先に確認したいときは `--print`（何もインストールしない）。

```bash
scripts/install-systemd.sh --print
```

### user サービス（既定・推奨）

root 不要。スクリプトを叩いたユーザー自身のサービスとして動く。引数なしがこれ。

```bash
scripts/install-systemd.sh
```

やっていること: `deploy/maestro.service`（テンプレート）を現在のチェックアウトから
埋めて `~/.config/systemd/user/maestro.service` に配置し、`systemctl --user enable
--now` する。ユニットに `User=` は付かない（起動ユーザーで動く）。

boot 時にログインなしで動かすため **linger** を有効化する（インストーラが自動で試す）。
自分のユーザーの linger は通常 root なしで有効化できる。ポリシー上できなかった場合だけ
警告が出るので、そのときは一度 `sudo loginctl enable-linger <user>` を実行する。

```bash
systemctl --user status maestro    # 状態
journalctl --user -u maestro -f     # ログ
systemctl --user restart maestro    # 再起動（ビルドし直した後など）
```

### system サービス（マシン全体・root が使える場合）

ログインユーザーに依らずマシン起動時に立ち上げたいとき。インストールに sudo が要る。

```bash
scripts/install-systemd.sh --mode system --run-as <app-user>
```

`/etc/systemd/system/maestro.service` に配置し、`User=<app-user>` で動く。
状態・ログは `systemctl status maestro` / `journalctl -u maestro -f`。

## よく使うオプション

| オプション | 意味 |
|---|---|
| `--print` / `--dry-run` | 生成されるユニットを表示するだけ。インストールしない |
| `--mode system` | マシン全体の system サービスとして入れる（既定は `user`） |
| `--run-as <user>` | system モードのアプリ実行ユーザー |
| `--name <n>` | サービス名（既定 `maestro`）。複数インスタンス用 |
| `--no-start` | boot 用に enable するが、いますぐ起動はしない |

## デプロイ後の更新

新しいコードを反映するとき（user サービスの場合）:

```bash
git pull
npm run build                     # または scripts/server.sh を使わず build のみ
systemctl --user restart maestro  # system サービスなら sudo systemctl restart maestro
```

## 設定・環境変数

- ポートやモードなどはリポジトリ内 `config.yaml` を読む（アプリが自前で読み込む）。
- `.env` があれば `EnvironmentFile` として読み込む（任意）。ただし systemd の
  `.env` 解釈は素朴な `KEY=value` 前提。`server.sh` が対応している凝ったクォートは
  効かないので、systemd 経由で使う値は単純な形式にすること。
- 既定の実行モードは `AAO_MODE=worker`（フルオーケストレータ）。gateway として
  動かすなら `.env` に `AAO_MODE=gateway` を書く。

## アンインストール

```bash
# system
sudo systemctl disable --now maestro
sudo rm /etc/systemd/system/maestro.service && sudo systemctl daemon-reload

# user
systemctl --user disable --now maestro
rm ~/.config/systemd/user/maestro.service && systemctl --user daemon-reload
```
