firebase-tools
firebase-tools copied to clipboard
Allow disabling IPv6 for emulators (e.g. for Codespaces port forwarding)
Environment info
firebase-tools: 9.16.6
Platform: Linux
Test case
Install firebase-tools.
Steps to reproduce
Run the firebase emulators with npx firebase emulators:start
Expected behavior
All services would bind to 127.0.0.1
(and, optionally, also to [::ffff:127.0.0.1]
).
The codespaces port forwarding feature would work as expected.
Actual behavior
Some services (in particular the firestore emulator) only bind to IPV6 localhost:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 [::ffff:127.0.0.1]:43299 *:* users:(("java",pid=19991,fd=78))
LISTEN 0 4096 [::ffff:127.0.0.1]:8080 *:* users:(("java",pid=19991,fd=79))
LISTEN 0 50 [::ffff:127.0.0.1]:36567 *:* users:(("java",pid=19991,fd=22))
LISTEN 0 4096 [::ffff:127.0.0.1]:34265 *:* users:(("java",pid=19991,fd=53))
and the codespaces port forwarding is not working.
Does setting the host
option to 1270.0.1
in firebase.json
help? For example for Firestore (repeat for all emulators if needed):
// ...
"emulators": {
"firestore": {
"host": "127.0.0.1",
"port": "8080"
},
// ...
}
// ...
@yuchenshi It does help! The port is now bound to 127.0.0.1
.
It shows as being tcp6
though:
tcp6 0 0 127.0.0.1:8080 :::* LISTEN 4985/java
and is not automatically picked up by the Codespaces port forwarding.
Adding it manually there works, even though VSCode shows the message No running process:
@silviot Would you mind helping us to experiment a little bit more here? The behavior you're seeing is due to the IPv6 dual-stacking behavior in Java and can be disabled by the env var WSL_DISTRO_NAME
(introduced for an unrelated issue). Would you mind trying to set that env var to any non-empty string before starting the emulators and see how it goes?
If that hack works, we can maybe change the CLI to also disable IPv6 when the env var CODESPACES
is set or something.
@yuchenshi It worked! Giving WSL_DISTRO_NAME
a non-empty value made ipv6 to get skipped, and in turn the port forwarding from codespaces worked as expected.
Okay, marking this as a feature request then now we have a workaround. +1 if you'd like even better support for disabling IPv6 (e.g. a better env var name or autodetect codespace) to help us prioritize! PRs welcome.
@yuchenshi I'd like to help with this as I'm not able to get some emulators working
is there a place in the codebase where we've already established a pattern for automatically determining the environment?
In codespaces, there are env vars that exist like CODESPACES=true
- so, just wondering where we could leverage this
@markgoho we have a function that does check for that variable specifically isCloudEnvironment
: https://github.com/firebase/firebase-tools/blob/master/src/utils.ts#L554-L559
(not sure how it's used throughout the codebase, but that seems like a good exercise for the reader 🙂 )
I think the newest version no longer support this. I just upgraded to 11.14.2 and even though my firebase.json says:
"emulators": {
"hub": {
"host": "127.0.0.1",
"port": 4400
},
"functions": {
"host": "127.0.0.1",
"port": 5001
},
"firestore": {
"host": "127.0.0.1",
"port": 8080
},
"hosting": {
"host": "127.0.0.1",
"port": 5000
},
"auth": {
"host": "127.0.0.1",
"port": "9099"
},
"pubsub": {
"host": "127.0.0.1",
"port": "8085"
}
}
I get the following error inside of my firebase-debug.json and the emulator just shuts down immediately. I can no longer run the emulators in my circleci build.
[info] i emulators: Shutting down emulators. {"metadata":{"emulator":{"name":"hub"},"message":"Shutting down emulators."}}
[debug] [2022-10-13T11:25:29.116Z] Error: listen EADDRNOTAVAIL: address not available ::1:4000
at Server.setupListenHandle [as _listen2] (node:net:1415:21)
at listenInCluster (node:net:1480:12)
at doListen (node:net:1629:7)
at processTicksAndRejections (node:internal/process/task_queues:84:21)
Should this be a new ticket or was this never resolved?
I can add a definition for the ui port to make that particular error go away but then there is still a ipv6 listener for 4500 but that port number doesn't seem to be documented. Looking through the code.
Ok to solve this you need to define more ports. There are some undocumented ones and the table inside of the docs doesn't have the names defined.
"logging": {
"name": "logging",
"host": "127.0.0.1",
"port": 4500
},
"ui": {
"name": "ui",
"host": "127.0.0.1",
"port": 4000
},
"hub": {
"name": "hub",
"host": "127.0.0.1",
"port": 4400
},
"eventarc": {
"name": "eventarc",
"host": "127.0.0.1",
"port": 9299
},
"database": {
"name": "database",
"host": "127.0.0.1",
"port": 9000
},
"functions": {
"name": "functions",
"host": "127.0.0.1",
"port": 5001
},
"firestore": {
"name": "firestore",
"host": "127.0.0.1",
"port": 8080
},
"hosting": {
"name": "hosting",
"host": "127.0.0.1",
"port": 5000
},
"auth": {
"name": "auth",
"host": "127.0.0.1",
"port": "9099"
},
"pubsub": {
"name": "pubsub",
"host": "127.0.0.1",
"port": "8085"
}
I am not using all emulators so there might be some more in other use cases, but logging and eventarc were not easy to find (also ui was a guess as to the name of the port)
v11.14.3
has better logic in it that should help with not binding to ipv6 if it's unavailable. Give that a whirl (without overriding all the things) and see if that helps?