GAE のローカル開発用サーバーが BindError で起動できない場合の対処法

2019年3月17日 20:21

サーバ上でサービスを起動する場合、他のサービスやアプリケーションとポート番号が競合しないよう留意する必要がある。一般的な Web サーバ(HTTP サーバ)は 80 番ポートで起動するが、ブラウザ上では省略されていることが多い。そのため、開発環境などで簡易 Web サーバを起動する場合は、8000 番や 8080 番ポートを指定するのが一般的である。

ツイート中にある lsof コマンドは本来、オープン中のファイルやそのファイルをオープンしているプロセスのリストを出力するものだが、-i および -P オプションを指定することでポートの使用状況がチェックできる。前者は「ネットワークソケットファイルを指定する」、後者は「ポート番号をサービス名に変換しない」というオプションだ。

今回のケースでは、Google App Engine(GAE)のローカル開発用サーバである dev_appserver.py を実行しようとして、BindError が発生。サーバで使用する 8080 番ポートがすでに使用中だと予想したわけだ。

$ dev_appserver.py .

(途中略)

  File "/Users/somin/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/wsgi_server.py", line 406, in start
    raise BindError('Unable to bind %s:%s' % self.bind_addr)
google.appengine.tools.devappserver2.wsgi_server.BindError: Unable to bind localhost:8080

ツイートでは、ポート番号での絞り込みに grep コマンドを利用しているが、-i オプションに続いてポート番号を指定する方法もある。ポート番号はカンマ区切りで複数指定も可能。ちなみに 8000 番は、管理用コンソールに使用されるポートである。

$ lsof -i:8080,8000 -P
Google    20432 somin   98u  IPv6 0xb2ad471e0d55bf47      0t0  TCP localhost:58026->localhost:8080 (ESTABLISHED)
Python    26757 somin   11u  IPv6 0xb2ad471e117d7ac7      0t0  TCP localhost:8080 (LISTEN)
Python    26757 somin   12u  IPv4 0xb2ad471e0b3704c7      0t0  TCP localhost:8080 (LISTEN)
Python    26757 somin   13u  IPv4 0xb2ad471e096cc1c7      0t0  TCP localhost:8000 (LISTEN)
Python    26757 somin   14u  IPv6 0xb2ad471e117d8c07      0t0  TCP localhost:8000 (LISTEN)

この場合、20432 と 26757 が「8080 番と 8000 番ポートを指定しているネットワークソケットファイル」のプロセス ID(PID)なので、これらを kill すればいい。

$ kill -kill 20432 26757
$ lsof -i:8080,8000
(何も表示されない)