DockerHubのRubyイメージからインストールしたRailsで、rails serverがうまく動かないときにやったこと

Railsチュートリアル第5章を進めていく中で発生した事態と、その対処についてのノートです。

# `rails server`が実行できない

```
# rails server
=> Booting Puma
=> Rails 5.1.6 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.9.1 (ruby 2.5.1-p57), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Exiting
...略
/usr/local/bundle/gems/puma-3.9.1/lib/puma/binder.rb:269:in `initialize': Address already in use - bind(2) for "0.0.0.0" port 3000 (Errno::EADDRINUSE)
```

# プロセスを`kill`してみたが、やっぱり`rails s`が実行できない

まず、Ruby関係のプロセスの実行状況を確認してみます。

```
# ps -ax | grep ruby
   13 pts/1    Tl     0:00 /usr/local/bin/ruby bin/rails c
   16 pts/1    Z+     0:00 [ruby] <defunct>
   38 pts/1    Tl     0:00 /usr/local/bin/ruby bin/rails console
   56 pts/2    Tl     0:00 /usr/local/bin/ruby bin/rails console
   62 pts/2    Tl     0:00 /usr/local/bin/ruby bin/rails console
  610 pts/2    S+     0:00 grep ruby
```

ここから、まずは`rails console`系のプロセスを`kill`してみます。引数なしの`kill`は、対象プロセスに`SIGTERM`シグナルを送信します。`kill -15`と同じ意味になります。

```
# kill 13
# kill 38
# kill 56
# kill 62
```

再びRuby関係のプロセスの実行状況を確認してみます。

```
# ps -ax | grep ruby
   13 pts/1    Tl     0:00 /usr/local/bin/ruby bin/rails c
   16 pts/1    Z+     0:00 [ruby] <defunct>
   38 pts/1    Tl     0:00 /usr/local/bin/ruby bin/rails console
   56 pts/2    Tl     0:00 /usr/local/bin/ruby bin/rails console
   62 pts/2    Tl     0:00 /usr/local/bin/ruby bin/rails console
  612 pts/2    S+     0:00 grep ruby
```

…何も変わらないですね。

最終手段として、`rails console`系のプロセスに`SIGKILL`シグナルを送信します。コマンドは`kill -9`です。

```
# kill -9 13
# kill -9 38
# kill -9 56
# kill -9 62
[1]-  Killed                  rails console
```

改めてRuby関係のプロセスの実行状況を確認してみます。

```
# ps -ax | grep ruby
   16 pts/1    Z+     0:00 [ruby] <defunct>
  615 pts/2    S+     0:00 grep ruby
```

`kill -9`の対象としたプロセスは、（正常かどうかはともかく）消滅したようです。

# `rails server`はやはり実行できない

```
# rails server
=> Booting Puma
=> Rails 5.1.6 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.9.1 (ruby 2.5.1-p57), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Exiting
...略
/usr/local/bundle/gems/puma-3.9.1/lib/puma/binder.rb:269:in `initialize': Address already in use - bind(2) for "0.0.0.0" port 3000 (Errno::EADDRINUSE)
```

最初に出たエラーメッセージと変わらないですね。上述手順で`kill`したプロセスが原因ではありませんでした。

# `lsof`のインストールと実行

TCP3000番ポートを使っているコマンドを確認するために、`lsof`というコマンドを使ってみます。

しかし、DockerHubのRubyイメージには、初期状態で`lsof`コマンドはインストールされていません。

```
# lsof -i:3000
bash: lsof: command not found
```

DockerHubのRubyイメージ（接尾語なし）は、Debian 10(Buster)をベースに構築されています。というわけで、パッケージをインストールするには`apt install`コマンドを実行します。

```
# apt install lsof
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  lsof
0 upgraded, 1 newly installed, 0 to remove and 72 not upgraded.
Need to get 313 kB of archives.
After this operation, 451 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian stretch/main amd64 lsof amd64 4.89+dfsg-0.1 [313 kB]
Fetched 313 kB in 0s (396 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package lsof.
(Reading database ... 36858 files and directories currently installed.)
Preparing to unpack .../lsof_4.89+dfsg-0.1_amd64.deb ...
Unpacking lsof (4.89+dfsg-0.1) ...
Setting up lsof (4.89+dfsg-0.1) ...
```

正常にインストールできたようです。

早速`lsof`コマンドを実行します。

```
# lsof -i:3000
COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ruby    406 root   15u  IPv4  29544      0t0  TCP *:3000 (LISTEN)
```

PIDは406のようですね。`SIGKILL`シグナルを送信します。

```
# kill -9 406
```

再度`lsof`コマンドを実行すると、TCP3000番ポートを使っているプロセスがないことが確認できます。

```
# lsof -i:3000
```

# 改めて`rails server`を実行

```
# rails s
=> Booting Puma
=> Rails 5.1.6 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.9.1 (ruby 2.5.1-p57), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
```

今度は正常に実行できました。