5

I Installed .NET Core SDK v3.1 on an Ubuntu VPS,
and I am now experimenting with ASP.NET Core projects.

I use
dotnet new webapp -o <ProjectName> --no-https
to create an ASP.NET Core project,
and
dotnet run
to run it, using .NET Core's built-in Web Server.

I have a small problem, which is the fact that .NET Core's built-in Web Server binds to IP 127.0.0.1 (localhost),
and not to the Public IP of my VPS.

This means that I cannot connect to my ASP.NET Core project from a browser on a remote computer, only from a browser on that VPS.

If instead of binding to 127.0.0.1 the Web Server would bind to 0.0.0.0,
then it will be good, since 0.0.0.0 means "All Network Interfaces", and not just the localhost IP.

After searching in Google, people recommend to go to the project's folder,
then enter the Properties folder,
and there, to Edit a file called launchSettings.json.

In that file, we need to change:
"applicationUrl": "http://localhost:5000"
to
"applicationUrl": "http://0.0.0.0:5000"

After doing this and re-running the project, the problem is solved,
and I can connect to the web server from a remote computer.

So this solution works,
yet I have 1 problem with it:
It requires editing every project's launchSettings.json file.

I am looking for a solution that does not require changing every project for this,
but more like changing the Web Server's settings, once..

Does such a solution exist?

For example some Settings file for the Web Server, that defined which IP and Port to bind to,
or If not that, then maybe there's some Template for ASP.NET Core projects, and I can go to that Template's folder, and then edit there the launchSettings.json file of the Template,
so all new ASP.NET Core projects that will be created from that moment on, will be created with the right IP (0.0.0.0).

Any solution that can be done Once, instead of Every Time, will be great.

spaceman
  • 1,061
  • 1
  • 11
  • 31

1 Answers1

15

The launchSettings.json is only really meant to be used for development purposes. At that time, you are usually developing only locally and are not looking for external devices to access your server. That’s why the default on the loopback interface makes sense.

For production or general non-development purposes, you should properly bundle the application using dotnet publish (or through Visual Studio). At that time, the published application will not include the launchSettings.json, so that configuration doesn’t actually apply.

Instead, you should set the URL your application should listen on through configuration. For example using the environment variable ASPNETCORE_URLS:

# E.g. on Linux:
ASPNETCORE_URLS=http://0.0.0.0:80 dotnet MyApp.dll

Or by passing the URL to the --url command line argument

MyApp.exe --urls http://0.0.0.0:80

You can also put this into the appsettings.json or an environment-specific appsettings.ENV.json:

{
    // …
    "urls": "http://0.0.0.0:80"
}

Since the appsettings are usually committed to source control, this allows you to keep the configuration across machines.

As for changing multiple projects at once, the only option would be to set a global environment variable with the updated URL. But since multiple applications cannot be hosted on the same interface/port combination, this probably wouldn’t be the best idea since the value from the enviroment variable would overwrite the value from the appsettings, making this more complicated to reason about.

poke
  • 369,085
  • 72
  • 557
  • 602
  • Thank you very much poke. Will the 3 solutions that you wrote work even If I don't use `dotnet publish` and only use `dotnet run`? Since I am in development and don't want to do publish after each iteration.. just having the constraint of having to open a broser on a remote computer, since the computer with Kestrel is a VPS, with Ubuntu that does not have a Desktop Environment (I connect to it with SSH, so no browser there..) – spaceman Feb 04 '20 at 22:51
  • 1
    Yes, all of these will work fine in development mode with `dotnet run`. E.g. `dotnet run --urls http://0.0.0.0:80`. – poke Feb 04 '20 at 22:55
  • You're amazing, it works fantastic and bypasses what's written in the project's `launchSettings.json` file. Out of curiosity, I am checking the other options that you wrote, so regarding the Environment Variable `ASPNETCORE_URLS`, you specified in its value a DLL's name, so this means it cannot work in general for all projects, but only for the project that I specify in the variable.. So (If I understand correctly), I will not use that one, since it's not general. Regarding `appsettings.json` or an environment-specific `appsettings.ENV.json`, this seems general, I will check it now.. – spaceman Feb 04 '20 at 23:04
  • The `var=value command` syntax on Linux is just a way to set a environment variable locally for that single process. You can absolutely set the environment variable for the whole session using `export ASPNETCORE_URLS=http://0.0.0.0:80` (or in your shell profile) and have that apply to all processes you start. It’s just that most commonly, you want this variable only apply to a single process explicitly; so that’s the syntax for that. Oh, and `dotnet MyApp.dll` is the way to launch .NET applications using the .NET Core runtime on Linux. – poke Feb 04 '20 at 23:41
  • Thank you. I executed `export ASPNETCORE_URLS=http://0.0.0.0:5000`, and then ran `dotnet run`. It did not succeed like the `--urls` succeeded before - it still binds to `127.0.0.1`. I verified that the `export` is indeed in memory via executing `export`, and it's in the list.. Is there any way to make the `ASPNETCORE_URLS` solution work too? – spaceman Feb 05 '20 at 07:18
  • Hm, you could confirm that the variable was set using `set`. Does it work with prefixing the `dotnet run` the way I did in the answer? If that works, you should check with your Linux distribution how to properly set the environment variable. – poke Feb 05 '20 at 18:19
  • if you need to set one more url, you can add this line: `"urls": "http://0.0.0.0:5000;https://0.0.0.0:5001"` – scil May 11 '22 at 06:18