I'm currently experiencing issues with port forwarding for remote development containers. I have tried following the walkthrough in the documentation, and using the port forward command in VSCode. But so far I have been unable to call my API running in the container from my local machine.
UPDATE: I have worked out if I remove the appPort from the devcontainer.json and forward it manually then the port forwarding works without issue. Not sure if this is desired behaviour for the appPort or not?
Has anyone else experienced similar issues?
Steps to Reproduce:
Does this issue occur when you try this locally?: No
Does this issue occur when you try this locally and all extensions are disabled?: No
Additional Troubleshooting:
Possibly related issues:
Files:
{
"name": "Python and Couchbase",
"context": "..",
"dockerFile": "docker-setup.sh",
"dockerComposeFile": "docker-compose.yml",
"appPort": [
5000
],
"extensions": [
"ms-python.python"
],
"settings": {
"python.pythonPath": "/usr/local/bin/python",
"python.linting.pylintEnabled": true,
"python.linting.pylintPath": "/usr/local/bin/pylint",
"python.linting.enabled": true
}
}
version: '1'
services:
web:
ports:
- 5000
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "app.py",
"FLASK_ENV": "development",
"FLASK_DEBUG": "0"
},
"args": [
"run",
"--no-debugger",
"--no-reload",
],
"jinja": true
}
]
}
VS Code Remote Containers supports 2 ways to forward ports:
temporarily https://code.visualstudio.com/docs/remote/containers#_temporarily-forwarding-a-portalways https://code.visualstudio.com/docs/remote/containers#_always-forwarding-exposing-publishing-a-portWhat you observe is that the always setup never works for you?
The always setup works for me, pls try https://github.com/microsoft/vscode-remote-try-node.
What I suspect is that Flask opens another port than you expect
I have the same issue.
temporarily: works fine.
always: is not reachable.
[EDIT]
I tried your configuration and it seems to work, so it's something on my end!
I fixed this by changing my launchSettings.json from:
"applicationUrl": "http://localhost:5001;http://localhost:5000",
to
"applicationUrl": "http://0.0.0.0:5001;http://0.0.0.0:5000",
This allowed the always setup mentioned above in the devcontainer.json file work, instead of having to manually forward my ports everytime.
EDIT: I was having this problem with a ASP.NET Core Development Container, but the problem seems to be the same regardless of what is hosted.
Yes, this makes sense - when you set things up to "always" connect, it's actually "publishing" the port from the container rather than forwarding it per-se. (This is "-p" in the Docker case.) When you connect to the server, it looks like a non-local IP coming across.
By updating to 0.0.0.0, you're telling the server inside the container accept connections on all (virtual) interfaces rather than just the container's localhost (127.0.0.1). So, when a connection comes in on a published port, the Flask server accepts it.
In the case of temporary, this is an actual forwarding mechanism - it will look to the server like it actually is coming from localhost. This is done because you cannot publish ports on a running container and as a side effect you can connect to things that you would not normally be able to connect to. Our examples show using 0.0.0.0 instead of localhost because of these differences.
I have the exact same problem: temporarily port forwarding via VS Code works fine, appPort does not.
For future readers that are working with a Flask standalone application:
app.run(host='0.0.0.0') to bypass this problem.
when you set things up to "always" connect, it's actually "publishing" the port from the container rather than forwarding it per-se. (This is "-p" in the Docker case.) When you connect to the server, it looks like a non-local IP coming across.
In the case of temporary, this is an actual forwarding mechanism - it will look to the server like it actually is coming from localhost.
Ahh! This makes _so much_ sense! Thank you Mr @Chuxel, for the explanation!
I'm experiencing the same port forwarding issue. My environment is Windows 10 1903. VSCode 1.39.1.
My configuration is based on the vscode-remote-try-node git. The only change is "appPort" : [4200] on devcontainer.json. Then I npmed angular/cli and used ng serve on the bash terminal to start the server.
The server printed
Project is running at http://localhost:4200/webpack-dev-server/
* Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ *
But when I tried the URL on my host, neither of the URLs worked. If I ctrl-clicked the URL shown on the terminal, the URL opened on the host was with port 8811 or some other random port.
I double checked on docker using docker port on the running container, it showed 0.0.0.0:4200->4200/tcp correctly.
I also tried "appPort" : ["4200:4200"] and rebuilt the container. The issue remained the same.
The netstat -ab command showed the port 8811 was associated with Code.exe and it seemed to me that Code was acting as a proxy?
You can fix that by asking Angular to listen on 0.0.0.0:4200 instead of localhost. In your case, yes, VSCode acted as a proxy. You can verify that with the server logs; they show up as a connection originating from localhost.
Refer to the comment by chuxel to get an idea of what's happening.
@MythreyaK Thanks for your advice. Once I run ng serve on 0.0.0.0:4200 instead of localhost I could access it from port 4200 on host as expected. Then chuxel's comments started making sense to me.
It's very interesting to know VSCode acting as proxy and "forwarding" the port. I could access the web server via both 4200 and the random port!
@Chuxel The discussion makes me wonder if we should change appPort to use the dynamic port forwarding. It seems like many samples and scaffolds might be listening on the local interface only. (/cc @alexandrudima who has brought this up.)
At the same time there are efforts to make setting up the dynamic port forwarding easier. So it might not make sense to change the existing behavior and we might instead just remove appPort from the definitions. (E.g.: Following a link in the debug console or terminal will automatically set up a tunnel. There are discussions around setting up tunnels based on the output in the debug console and terminal. And the upcoming UI for port forwarding will show ports being listened on.)
/cc @alexr00
One thing that might help this with the new port UI is that I want to show address:port, so for published ports it would be clear that it isn't just localhost.
The plan here is to introduce "forwardPorts" in the devcontainer.json the same way we have that for the attach configurations today. (Unlike that we wouldn't automatically update it, at least not by default.)
We would then rewrite all samples and definitions to use "forwardPorts" because that also works for remote Docker hosts and can fallback to a random port when the given port is already in use on localhost.
There is some overlap with the core's plan on restoring previous forwardings per workspace URI (disabled by default at first), but it still seems to make sense to have this support in the devcontainer.json for initially setting up the forwarded ports.
On my .NET Core project using dev containers, I was able to get my project to work by making the following change:
I fixed this by changing my launchSettings.json from:
"applicationUrl": "https://localhost:5001;http://localhost:5000",
to
"applicationUrl": "https://*:5001;http://*:5000",
I utilized the * instead of changing to 0.0.0.0. I also added these 2 ports in my devcontainer.json so they would always be published:
"appPort": [5000, 5001],
@joswalt With the upcoming release (currently available for VS Code Insiders) you can also: Keep listening on localhost and use "forwardPorts" instead of "appPort".
Most helpful comment
The plan here is to introduce
"forwardPorts"in thedevcontainer.jsonthe same way we have that for the attach configurations today. (Unlike that we wouldn't automatically update it, at least not by default.)We would then rewrite all samples and definitions to use
"forwardPorts"because that also works for remote Docker hosts and can fallback to a random port when the given port is already in use on localhost.There is some overlap with the core's plan on restoring previous forwardings per workspace URI (disabled by default at first), but it still seems to make sense to have this support in the
devcontainer.jsonfor initially setting up the forwarded ports.