Type=simple -> プロセスの起動方法を指定している。simpleはデフォルトであり、プロセスが起動した時点で起動完了のステータスとする。
ExecStart=/usr/local/src/main & -> 起動時に実行していているコマンド。バイナリファイルをバックグラウンド実行している。
WantedBy=multi-user.target -> 起動の依存を一応表している。(一応というのは、Unitに記載するBefore・Afterで十分だからだ。)multi-user.targetは通常のサービスの実行グループだと思ってもらえれば良い。
Created symlink /etc/systemd/system/multi-user.target.wants/start-apiserver.service → /etc/systemd/system/start-apiserver.service.
○ start-apiserver.service - Start nabelog API server
Loaded: loaded (/etc/systemd/system/start-apiserver.service; enabled; vendor preset: disabled)
Active: inactive (dead)
enabledとなっているので、起動待機状態になっております。
起動してみる
× start-apiserver.service - Start nabelog API server
Loaded: loaded (/etc/systemd/system/start-apiserver.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2023-01-14 19:21:19 JST; 1min 43s ago
Process: 580417 ExecStart=/usr/local/src/main & (code=exited, status=1/FAILURE)
Main PID: 580417 (code=exited, status=1/FAILURE)
CPU: 10ms
Jan 14 19:21:19 ik1-127-70159.vs.sakura.ne.jp systemd[1]: Started Start nabelog API server.
Jan 14 19:21:19 ik1-127-70159.vs.sakura.ne.jp main[580417]: 2023/01/14 19:21:19 Error loading .env file
Jan 14 19:21:19 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Main process exited, code=exited, stat>
Jan 14 19:21:19 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Failed with result 'exit-code'.
あんれ、起動してない。というか.env fileが読み込めないって言ってんな。
普通に実行してみる。
:@tcp(:3306)/~~~~~~~
...........................
envファイルは読み込めてそうだな。だけど、dbと接続できてない。
rootじゃなくてrockyユーザーでやってみるか。
DB接続成功
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] Loaded HTML Templates (2):
-
- index.html
[GIN-debug] GET / --> main.main.func1 (4 handlers)
[GIN-debug] GET /hello --> main.main.func2 (4 handlers)
[GIN-debug] GET /shops --> main.main.func3 (4 handlers)
[GIN-debug] POST /shops --> main.main.func4 (4 handlers)
[GIN-debug] GET /shops/:id --> main.main.func5 (4 handlers)
[GIN-debug] PATCH /shops/:id --> main.main.func6 (4 handlers)
[GIN-debug] DELETE /shops/:id --> main.main.func7 (4 handlers)
[GIN-debug] GET /influencers --> main.main.func8 (4 handlers)
[GIN-debug] POST /influencers --> main.main.func9 (4 handlers)
[GIN-debug] GET /influencers/:id --> main.main.func10 (4 handlers)
[GIN-debug] PATCH /influencers/:id --> main.main.func11 (4 handlers)
[GIN-debug] DELETE /influencers/:id --> main.main.func12 (4 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
あれ、繋がった...?
じゃあ、rockyアカウントでユニットファイルを実行してみる。
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to start 'start-apiserver.service'.
Authenticating as: rocky
Password:
==== AUTHENTICATION COMPLETE ====
× start-apiserver.service - Start nabelog API server
Loaded: loaded (/etc/systemd/system/start-apiserver.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2023-01-14 19:34:36 JST; 7s ago
Process: 580585 ExecStart=/usr/local/src/main & (code=exited, status=1/FAILURE)
Main PID: 580585 (code=exited, status=1/FAILURE)
CPU: 8ms
Jan 14 19:34:36 ik1-127-70159.vs.sakura.ne.jp systemd[1]: Started Start nabelog API server.
Jan 14 19:34:36 ik1-127-70159.vs.sakura.ne.jp main[580585]: 2023/01/14 19:34:36 Error loading .env file
Jan 14 19:34:36 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Main process exited, code=exited, stat>
Jan 14 19:34:36 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Failed with result 'exit-code'.
変わんね〜〜。
シェルスクリプトを通じて実行できるか確認。
作成
これを実行。
DB接続成功
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] Loaded HTML Templates (2):
-
- index.html
[GIN-debug] GET / --> main.main.func1 (4 handlers)
[GIN-debug] GET /hello --> main.main.func2 (4 handlers)
[GIN-debug] GET /shops --> main.main.func3 (4 handlers)
[GIN-debug] POST /shops --> main.main.func4 (4 handlers)
[GIN-debug] GET /shops/:id --> main.main.func5 (4 handlers)
[GIN-debug] PATCH /shops/:id --> main.main.func6 (4 handlers)
[GIN-debug] DELETE /shops/:id --> main.main.func7 (4 handlers)
[GIN-debug] GET /influencers --> main.main.func8 (4 handlers)
[GIN-debug] POST /influencers --> main.main.func9 (4 handlers)
[GIN-debug] GET /influencers/:id --> main.main.func10 (4 handlers)
[GIN-debug] PATCH /influencers/:id --> main.main.func11 (4 handlers)
[GIN-debug] DELETE /influencers/:id --> main.main.func12 (4 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
おお、起動した。
じゃあ、やっぱりshellスクリプトを実行する形にするか。
ファイルの作成
シェルスクリプト自体はさっきのファイル。
一応改めて書いておく。
権限の付与
権限付与して、確認する。
drwxr-xr-x 2 rocky rocky 4096 Dec 24 17:46 config
-rw-r--r-- 1 rocky rocky 1212 Jan 2 15:09 go.mod
-rw-r--r-- 1 rocky rocky 11547 Jan 2 15:09 go.sum
-rwxr-xr-x 1 rocky rocky 15576907 Jan 2 15:09 main
-rw-r--r-- 1 rocky rocky 6376 Jan 2 15:09 main.go
drwxr-xr-x 2 rocky rocky 4096 Dec 24 16:25 mock
drwxr-xr-x 2 rocky rocky 4096 Dec 24 16:25 model
-rwxr-xr-x 1 root root 19 Jan 14 19:55 start-main.sh
drwxr-xr-x 2 rocky rocky 4096 Dec 24 16:25 templates
試しに実行
多分なんだけど、root権限で実行しようとするとエラー起こるわ。
root以外の権限で実行してみると、envファイルを読み込めてないわ。
。。。。。あーーーーーーー!
root環境に環境変数を置いてないからかも。
確認。
production
Password:
Last login: Sat Jan 14 19:02:09 JST 2023 on pts/2
Last failed login: Sat Jan 14 20:04:50 JST 2023 from ~~~~ on ssh:notty
There were 298 failed login attempts since the last successful login.
その通りすぎた。ということで、root環境にも環境変数を導入してあげましょ。
++ export NABELOG_ENV="production"
反映と確認。
いいね、そしたら実行してみよう。
だめなんかい!!!
ようわからんかったけど、まぁ実行ユーザー変えれば良いかな。
ユニットファイルの実行ユーザーを変更
systemdの.serviceファイルで、実行ユーザーを指定する - Qiita
これを参考にしてやってみる。
変更後のファイルがこちら。
UserとGroupを足しました。
[Unit]
Description=Start nabelog API server
[Service]
Type=simple
ExecStart=/usr/local/src/main &
Restart=no
User=rocky
Group=rocky
[Install]
WantedBy=multi-user.target
じゃあ、ユニットファイルを反映して実行。
× start-apiserver.service - Start nabelog API server
Loaded: loaded (/etc/systemd/system/start-apiserver.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2023-01-14 20:27:18 JST; 10s ago
Process: 581608 ExecStart=/usr/local/src/main & (code=exited, status=1/FAILURE)
Main PID: 581608 (code=exited, status=1/FAILURE)
CPU: 9ms
Jan 14 20:27:18 ik1-127-70159.vs.sakura.ne.jp systemd[1]: Started Start nabelog API server.
Jan 14 20:27:18 ik1-127-70159.vs.sakura.ne.jp main[581608]: 2023/01/14 20:27:18 Error loading .env file
Jan 14 20:27:18 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Main process exited, code=exited, stat>
Jan 14 20:27:18 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Failed with result 'exit-code'.
なんやねん!!!!
以下のように変更
#!/bin/sh
cd /usr/local/src/
./main &
[Unit]
Description=Start nabelog API server
After=local-ts.target
ConditionPathExists=/opt/nabelog/
[Service]
Type=simple
Restart=no
User=rocky
Group=rocky
ExecStart=/opt/nabelog/start-main.sh
StandardOutput=journal+console
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl reset-failed start-apiserver.service
$ sudo systemctl start start-apiserver
$ sudo systemctl status start-apiserver.service
× start-apiserver.service - Start nabelog API server
Loaded: loaded (/etc/systemd/system/start-apiserver.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2023-01-14 20:27:18 JST; 10s ago
Process: 581608 ExecStart=/usr/local/src/main & (code=exited, status=1/FAILURE)
Main PID: 581608 (code=exited, status=1/FAILURE)
CPU: 9ms
Jan 14 20:27:18 ik1-127-70159.vs.sakura.ne.jp systemd[1]: Started Start nabelog API server.
Jan 14 20:27:18 ik1-127-70159.vs.sakura.ne.jp main[581608]: 2023/01/14 20:27:18 Error loading .env file
Jan 14 20:27:18 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Main process exited, code=exited, stat>
Jan 14 20:27:18 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Failed with result 'exit-code'.
なんかエラーは出ないけど、Deactivatedになって、何もされない。
せめてログに出てほしいなぁ。
別のコマンドでログを出してみるも
$ journalctl -xeu start-apiserveer.service
~
~
-- No entries --
何もでねぇ〜〜。
これを参考にちょっと変えてみるか。
systemdので起動したアプリケーションのprintfを標準出力に表示したい | Armadillo
[Unit]
Description=Start nabelog API server
After=local-ts.target
ConditionPathExists=/opt/nabelog/
[Service]
Type=simple
Restart=no
User=rocky
Group=rocky
ExecStart=/opt/nabelog/start-main.sh
StandardOutput=tty
[Install]
WantedBy=multi-user.target
結論、でねぇ。
journalctlでログを探ってみてるが、なんとも手がかりがない。げせぬ。
ユニットファイルの実行対象をmainに戻してもう一度考察
そしたらちゃんと前のエラーログも出た。よかった。
そして、エラーログを見たら新たな事実がわかった。
- やっぱり環境変数を読み込めていない
- カレントディレクトリ以外のenvファイルをgodotenvで読み込めていない。
調べてみたらやっぱりそう。
systemd のユーザーインスタンスは .bashrc などに設定された環境変数を全く継承しません。
参考:
systemd/ユーザー - ArchWiki
いやしろよww
そしたら、以下の方針。
- systemdでも環境変数を読み込むようにする
- ユニットファイルを変更
- main実行時にcd でmainがある環境まで移動する
- シェルスクリプトを実行させる
systemdでも環境変数を読み込むようにする
参考
systemdで環境変数を読み込む - Qiita
以下を作成
そして、ユニットファイルを編集
++ EnvironmentFile=/etc/sysconfig/nabelog_env
リロードして、実行。
$ sudo systemctl status start-apiserver.service
× start-apiserver.service - Start nabelog API server
Loaded: loaded (/etc/systemd/system/start-apiserver.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2023-01-21 18:31:18 JST; 7s ago
Process: 710112 ExecStart=/usr/local/src/main & (code=exited, status=1/FAILURE)
Main PID: 710112 (code=exited, status=1/FAILURE)
CPU: 8ms
Jan 21 18:31:18 ik1-127-70159.vs.sakura.ne.jp systemd[1]: Started Start nabelog API server.
Jan 21 18:31:18 ik1-127-70159.vs.sakura.ne.jp main[710112]: 2023/01/21 18:31:18 Error loading .env.production file
Jan 21 18:31:18 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Main process exited, code=exited, status=1/FAILURE
Jan 21 18:31:18 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Failed with result 'exit-code'.
おおーーー。環境変数読み込めてる〜〜!
ユニットファイルを編集
じゃあ、ユニットファイルからcdファイルも実行するようにする。
けど、これみる限りシェル実行でいけるっぽいな、やってみよ。
[CentOS7] systemdにサービスを登録して、サーバ起動時に自動でサービスを立ち上げる | RE:ENGINES
うーん、ダメだな。できなかった。
そしたら、シェル実行はやめて、コマンド自体をユニットファイルに書こう。
[Unit]
Description=Start nabelog API server
[Service]
Type=simple
ExecStart=cd /usr/local/src; /usr/local/src/main &
Restart=no
User=rocky
Group=rocky
[Install]
WantedBy=multi-user.target
$ sudo systemctl status start-apiserver.service
× start-apiserver.service - Start nabelog API server
Loaded: loaded (/etc/systemd/system/start-apiserver.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2023-01-21 22:44:32 JST; 6s ago
Process: 713420 ExecStart=cd /usr/local/src/ && /usr/local/src/main & (code=exited, status=1/FAILURE)
Main PID: 713420 (code=exited, status=1/FAILURE)
CPU: 2ms
Jan 21 22:44:32 ik1-127-70159.vs.sakura.ne.jp systemd[1]: Started Start nabelog API server.
Jan 21 22:44:32 ik1-127-70159.vs.sakura.ne.jp cd[713420]: /usr/bin/cd: line 2: cd: too many arguments
Jan 21 22:44:32 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Main process exited, code=exited, status=1/FAILURE
Jan 21 22:44:32 ik1-127-70159.vs.sakura.ne.jp systemd[1]: start-apiserver.service: Failed with result 'exit-code'.
cdがダメっぽいな。
なんか、WorkingDirectoryで設定できるっぽい。
[Unit]
Description=Start nabelog API server
[Service]
WorkingDirectory=/usr/local/src/
EnvironmentFile=/etc/sysconfig/nabelog_env
Type=simple
ExecStart=/usr/local/src/main &
Restart=no
User=rocky
Group=rocky
StandardOutput=journal+console
[Install]
WantedBy=multi-user.target
じゃあ、実行。
$ sudo systemctl status start-apiserver.service
● start-apiserver.service - Start nabelog API server
Loaded: loaded (/etc/systemd/system/start-apiserver.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2023-01-21 22:50:23 JST; 17min ago
Main PID: 713575 (main)
Tasks: 3 (limit: 2696)
Memory: 8.7M
CPU: 36ms
CGroup: /system.slice/start-apiserver.service
└─713575 /usr/local/src/main "&"
Jan 21 22:50:23 ik1-127-70159.vs.sakura.ne.jp main[713575]: [GIN-debug] PATCH /influencers/:id --> main.main.func11 (4 handlers)
Jan 21 22:50:23 ik1-127-70159.vs.sakura.ne.jp main[713575]: [GIN-debug] DELETE /influencers/:id --> main.main.func12 (4 handlers)
Jan 21 22:50:23 ik1-127-70159.vs.sakura.ne.jp main[713575]: [GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Jan 21 22:50:23 ik1-127-70159.vs.sakura.ne.jp main[713575]: Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
Jan 21 22:50:23 ik1-127-70159.vs.sakura.ne.jp main[713575]: [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
Jan 21 22:50:23 ik1-127-70159.vs.sakura.ne.jp main[713575]: [GIN-debug] Listening and serving HTTP on :8080
Jan 21 22:50:43 ik1-127-70159.vs.sakura.ne.jp main[713575]: DB接続成功
へ!!!でけた!!!!wwwwww
WorkingDirectoryを設定すればよかったのか。
enable設定もして、掃除して終わろう。
$ sudo systemctl enable start-apiserver.service
$ rm -rf /opt/nabelog/
確認作業
さくらインターネットでサーバーを再起動してみましょ。
サーバーをシャットダウンして、また起動してみる。
順番は、client → db → serverの順番にしましょう。
client起動
おおーー、おk
db起動
ちゃんと接続できるからok
server起動
データがちゃんと取得できる!!
よし、done。