Firebase には、自分の手元で開発を進めやすいようにするためのエミュレーターが用意されているのですが、エミュレーターを停止させる前にそのターミナルのウィンドウを閉じてしまったり、IDE 内蔵ターミナルで起動してて停止前にウィンドウを閉じてしまったりすると、
一部のプロセスが残ったままになってしまい、次に起動しようとしたときにこんなエラーがでて起動できなくなることがあります。
i emulators: Starting emulators: auth, functions, firestore, hosting, storage
⚠ firestore: Port 8080 is not open on localhost (127.0.0.1,::1), could not start Firestore Emulator.
⚠ firestore: To select a different host/port, specify that host/port in a firebase.json config file:
{
// ...
"emulators": {
"firestore": {
"host": "HOST",
"port": "PORT"
}
}
}
i emulators: Shutting down emulators.
Error: Could not start Firestore Emulator, port taken.
たとえば今回の場合だと、firestore
のエミュレータがゾンビ化してしまったみたいです。
ということで、これを直す方法です。
ちなみに Mac での話です。
ポートを使用しているプロセスを探す
今回の場合、firestore のエミュレータが 8080 番ポートを使おうとしたけど、既に他のプロセスがリッスンしてるために利用できず起動に失敗したというものでした。
まぁ、その犯人はゾンビになった firestore エミュレータだったのですが。
ポートがわかってるのであれば、lsof
コマンドで簡単にプロセスを調べることが出来ます。
lsof
は、オープンしているファイルを一覧表示するコマンドなのですが、 -i
オプションをつけると、ネットワークソケットを対象にすることができます。
さらに、-i
は以下のように続けることで絞り込みが出来ます。
-i
ですべてのソケット-i4
,-i6
で IPv4 または IPv6-iTCP
,-iUDP
といったプロトコル指定-i@(ホスト)
のホスト指定-i:(ポート)
でポート指定
今回はポートがわかってるので、-i
を使えば1発でプロセスを探せます。
$ lsof -i:8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 18124 nagi 168u IPv6 0xbfdea6a629893e93 0t0 TCP localhost:http-alt (LISTEN)
はい。ということで、PID 18124 で動いている java が犯人でした。
(Firebaseエミュレータは JAVA で書かれてます)
プロセスを停止する
プロセス番号(PID)がわかったのであとは、kill
コマンドで停止シグナルを送ればOKです。
$ kill -9 18124
kill コマンドについては、前にtmuxの話を書いたときにも触れてますのでよかったらそちらもどうぞ。
もう一度 lsof
を実行して、何も表示されなければプロセスの停止ができてるので、この状態からなら起動できるようになるはずです。
$ lsof -i:8080
感想
IDEとかエディタ内蔵のターミナルだと特に停止し忘れが多い気がして、エミュレータ操作は独立したターミナルアプリのほうが向いてるのかなぁ。
まぁ、ターミナルアプリでも不用意にウィンドウを閉じてしまえば同じことではあるのですが。
というか IDEが親切すぎるとも言えるのかな?
たとえば自分が普段開発に使ってる Jetbrains の各種 IDE の場合、開発サーバーの操作(npm run dev
とか)って run/debug 機能を使ってクリック1つで動かせるし、そういうふうにしておくとウィンドウ閉じるときに一緒に閉じるか聞いてくれるので自分で Ctrl + C
押す癖が抜けかけているのも良くないのかも。。w