pm2の導入 〜Node.jsアプリの自動起動〜

pm2を利用して、Node.jsアプリをOSの起動時にバックグラウンド・プロセス(デーモン)として自動的に起動させるまでの個人的メモです。

環境

  • Ubuntu 18.04.4 LTS
  • Node.js v14.2.0
  • pm2 4.4.0

なお、pm2はグローバル・インストールしている。 即ち、

$ npm install pm2 -g

概要

pm2を利用したOS起動時のNode.jsアプリの自動起動は、

  1. OSの起動
  2. pm2の起動
  3. Node.jsアプリの起動

という流れで進む。

そのため、pm2を利用してOS起動時にNode.jsアプリを自動的に起動させるためには、

の設定が必要となる。

また、以下の手順によると、ログインしているユーザとしてpm2及びNode.jsアプリが自動起動するように設定される。 そのため、前提として、適切なユーザとしてログインしておくことが必要である。

pm2の自動起動設定

$ pm2 startup

これにより、pm2自動起動設定方法が示される。今回は、以下のメッセージが表示された。

[PM2] Init System found: systemd
ubuntu
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/home/ubuntu/.nodebrew/node/v14.2.0/bin /home/ubuntu/.nodebrew/node/v14.2.0/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu --hp /home/ubuntu

従って、

$ sudo env PATH=$PATH:/home/ubuntu/.nodebrew/node/v14.2.0/bin /home/ubuntu/.nodebrew/node/v14.2.0/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu --hp /home/ubuntu

なお、これにより以下のメッセージ(一部)が表示された。

Target path
/etc/systemd/system/pm2-ubuntu.service
Command list
[ 'systemctl enable pm2-ubuntu' ]
[PM2] Writing init configuration in /etc/systemd/system/pm2-ubuntu.service
[PM2] Making script booting at startup...
[PM2] [-] Executing: systemctl enable pm2-ubuntu...
Created symlink /etc/systemd/system/multi-user.target.wants/pm2-ubuntu.service → /etc/systemd/system/pm2-ubuntu.service.
[PM2] [v] Command successfully executed.

どうやら、手動でsudo systemctl enable ...を実行する必要はないようである。

また、これにより以下のメッセージ(一部)も表示された。

[PM2] Remove init script via:
$ pm2 unstartup systemd

どうやら、これによりインストールされたファイルは、sudo pm2 unstartup systemdによりアンインストールできるようである(未確認)。

Node.jsアプリの自動起動設定

まずは、

$ cd ${pathToApp}
$ pm2 ecosystem

${pathToApp}はNode.jsアプリのベース・ディレクトリのパス。 これにより、${pathToApp}にpm2による起動用の設定ファイルecosystem.config.jsが作成されるので、適宜編集する。

次に、

$ pm2 start ecosystem.config.js

これにより、Node.jsアプリがバックグラウンドで起動する。

最後に、

$ pm2 save

これにより、現在起動しているNode.jsアプリが記憶される。

記憶されたNode.jsアプリは、次回のOS起動時のpm2の自動起動時に、自動的に起動する。

Time Machineのバックアップディスクのバックアップ

Netatalkを利用して、Raspberry Pi上にTime Machineサーバを立ててます。

ただ、原因は不明ながら、ときどきTime Machineのバックアップディスクが壊れます。 Time Machineのバックアップディスクが壊れると、とれる手段はバックアップディスクの再作成のみ…(それまでにバックアップしたデータは失われてしまう…) そのため、Time Machineのバックアップディスクをバックアップするという、なかなか冗長な作業を定期的に行なっています。

前置きが長くなりましたが、その際、直感に反して、Raspberry PiにUSB経由で接続しているHDDよりも、有線LAN経由で接続しているWindowsファイル共有をバックアップ先に指定した方が、(若干ながら)時間がかかりませんでした。

以下は、その結果のメモです。

環境

Time Machineのバックアップディスク(/media/hdd/timemachine/)のサイズは以下の通り。

$ du -h -d 0 /media/hdd/timemachine/
129G    /media/hdd/timemachine/

また、Raspberry PiWindowsマシン(192.168.11.4)との間の通信速度は以下の通り。

$ iperf3 -c 192.168.11.4

(省略)

[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec   342 MBytes   287 Mbits/sec    0             sender
[  5]   0.00-10.00  sec   342 MBytes   287 Mbits/sec                  receiver

HDDにバックアップした場合

$ cd /media/hdd/timemachine
$ time sudo tar -zcvf /media/hdd/share/timemachine.tar.gz .

(省略)

real    508m53.297s
user    469m20.277s
sys     33m7.178s

ちなみに、バックアップ先(/media/hdd/share/)はTime Machineのバックアップディスクと同一HDDです。

Windowsファイル共有にバックアップした場合

$ sudo mount -t cifs //192.168.11.4/share /media/windows
$ cd /media/hdd/timemachine
$ time sudo tar -zcvf /media/windows/timemachine.tar.gz .

(省略)

real    490m33.284s
user    474m12.327s
sys     24m50.869s

macOSのターミナルでコマンド履歴が保存されない

通常、ターミナルの終了時には、当該ターミナルにて入力されたコマンドの履歴が保存され、次にターミナルが開かれたときに過去に入力されたコマンドを(↑キー等によって)呼び出すことができるようになっています。

しかしながら、MacBookリカバリしたところ、表題のことが起きました。

環境

  • MacBook (Early 2015)
  • macOS Mojave (10.14.6)
  • ターミナル (2.9.5 (421.2))
  • bash (3.2.57(1)-release (x86_64-apple-darwin18))

解決策

ターミナルにて、以下のコマンドを実行する。

echo : > ~/.bash_history; exit

これによりターミナルが終了します。 終了前のコマンド履歴は保存されていないものの、次回以降に開かれたターミナルにおいては、その終了時にコマンド履歴が保存されるようになりました。

解説

根本的な原因は不明なものの、少なくとも私の環境では、

  • ターミナルにおいてsave/restore mechanismが有効になっており(~/.bash_sessions_disableが存在しない)、且つ、
  • ~/.bash_historyが存在しないか又はそのサイズがゼロである

ときにターミナルが開かれると、その終了時にコマンド履歴が保存されないようになっていました。

即ち、上記コマンドは、ダミーデータ(:)を書き込むことにより、サイズがゼロより大きい~/.bash_historyを作成するためのものです。

libfdk-aac有効化ffmpegのコンパイル

CompilationGuide/Ubuntu1を参考に。

環境

事前準備

なるべくインストールする依存パッケージが少なくなるようにしています。

sudo apt -y install \
 autoconf \
 automake \
 build-essential \
 cmake \
 git-core \
 libass-dev \
 libfreetype6-dev \
 libtool \
 libvorbis-dev \
 pkg-config \
 texinfo \
 wget \
 zlib1g-dev && \
mkdir -p ~/ffmpeg_sources ~/bin

libfdk-aacコンパイル

約9分かかりました。

cd ~/ffmpeg_sources && \
git -C fdk-aac pull 2> /dev/null || git clone --depth 1 https://github.com/mstorsjo/fdk-aac && \
cd fdk-aac && \
autoreconf -fiv && \
./configure --prefix="$HOME/ffmpeg_build" --disable-shared && \
make && \
make install

ffmpegコンパイル

約77分かかりました。

cd ~/ffmpeg_sources && \
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 && \
tar xjvf ffmpeg-snapshot.tar.bz2 && \
cd ffmpeg && \
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
 --prefix="$HOME/ffmpeg_build" \
 --pkg-config-flags="--static" \
 --extra-cflags="-I$HOME/ffmpeg_build/include" \
 --extra-ldflags="-L$HOME/ffmpeg_build/lib" \
 --extra-libs="-lpthread -lm" \
 --bindir="$HOME/bin" \
 --enable-libfdk-aac && \
PATH="$HOME/bin:$PATH" make && \
make install &&\
hash -r

これにて、~/bin/ffmpegが得られます。

Raspberry Pi 関連のメモ

供給電力が足りているかを調べる

こちら1のWebページより.

$ vcgencmd get_throttled
戻り値 二進数 意味
throttled=0x0 00000 00000 00000 00000 正常
throttled=0x50000 01010 00000 00000 00000 低電圧が検出され、スロットリングした(過去)
throttled=0x50005 01010 00000 00000 00101 低電圧が検出され、スロットリング中である

macOSにてWebアプリをネイティブアプリ風に使う

「ネイティブアプリ風に使う」とは、

  • WebアプリのアイコンがDockに登録できる
  • Webアプリ用の独立したウィンドウが開く

ようにすることを意図しています。

なお、Automator及びGoogle Chromeを使用します。

確認環境

  • macOS Mojave 10.14.6
  • Automator (上記OSにプリインストールのもの)
  • Google Chrome 77.0.3865.90 (Webアプリに係るアカウントにはログイン済み)
  • Google フォト (Webアプリの例)

やり方

  1. Automatorにて、新規アプリケーションを作成する。

  2. 「ライブラリ」-「シェルスクリプトを実行」をアクションとして追加。

  3. 追加したアクションに、open -na "Google Chrome" --args "--app=https://photos.google.com/"を追加。 上記コードのhttps://photos.google.com/の部分がWebアプリ(この例ではGoogle フォト)のURLです。

  4. ファイルを適当な名前(例えば、「Google フォト」 )で保存。

f:id:warexperimental:20190929175315p:plain
こんな感じ。

これにより作成されたアプリは、Dockに登録可能且つ独立したウィンドウでWebアプリを起動させるものです。

アプリのアイコンを変更したい場合には、以下の記事を参照すると幸せになれるかもです。

Automatorで作成したアプリケーションのアイコンを変更する - warexperimental’s blog

Automatorで作成したアプリケーションのアイコンを変更する

Automatorで作成したアプリケーション内のContents/Info.plistには、デフォルトで以下のようなコードが含まれています。

<key>CFBundleIconFile</key>
<string>AutomatorApplet</string>

上記コードのAutomatorAppletの部分がアプリーションのアイコンを指定しているようです。 より詳細には、当該部分をXとおくと、アプリケーションのアイコンとしてはContents/Resources/X.icnsが使用されることになるようです。

従って、

  • Contents/Resources/AutomatorApplet.icnsを所望のicnsファイルに置き換えるか、又は、
  • 所望のicnsファイルをContents/Resourcesに追加し、上記コードのAutomatorAppletの部分を追加したicnsファイルの名前に書き換える

ことによって、アプリケーションのアイコンを変更することが可能です。

オリジナルのアイコンを作成したい場合には、以下の記事を参照すると幸せになれるかもです。

最もシンプルなicnsファイルのつくりかた - warexperimental’s blog