DTodd
DTodd

Reputation: 101

Docker containers do not work when run from command line

I have been working on an ASP.NET application using Docker, and when I launch it through Visual Studio it works great! However, if I try to run anything from the command line (or powershell, or VS's CLI/Powershell) it will run, but the container it generates refuses all connections.

I am on Windows 10 NT with Docker Desktop installed trying to run an ubuntu:18.04 image (i've tried Alpine, ubuntu:16.04 as well).

Steps to reproduce:

-Create a default ASP.NET application in Visual Studio

-Add Docker Support

-Run with 'Docker' selected

-Open browser, navigate to localhost:[YourPort]

-Success! Works as intended.

Then, either using the same image or a downloaded one (I tried dockersamples/static-site to confirm it wasn't a problem with the specific project):

-Open CMD

-Run docker run -p [HostPort]:[ContainerPort] [SameImageVSUses:tag] on a different port

-See that docker ps shows both containers running next to each other

-Open browser (Firefox), get error

The connection was reset

Update

I changed the ASP.NET app's program class to use 0.0.0.0 instead of localhost, I believe this was necessary but now I see

Secure Connection Failed PR_END_OF_FILE_ERROR_

If I curl localhost:[MyPort], I get (52) empty reply from server

/Update

Well, maybe Visual Studio does more that I'm not aware of.

A little bit of digging shows yes, it throws in a ton of extra arguments! Using the copy/pasted command Visual Studio does gives me... the exact same error.

To clarify, the containers still run from the command line, I can ssh in or docker inspect them (in fact, the VS-started and CMD-started containers' docker inspect is identical other than network addresses it's bound to). I get no error messages at all from the process of building and starting the container, so if some part of it is failing it is doing so silently.

I'm relatively new to Docker but I can't seem to find a fix for this, or even a reason behind it. What is Visual Studio doing that I'm not? I've tried everything I'm aware of, I even had to wipe my machine (unrelated) and the exact same thing happened when I got everything reinstalled. My gut tells me it's something on my machine, but then the VS-launched one should fail too, right?

I can't find anything that tells me to flip a magic switch if I'm running CLI stuff, and nothing I do to the dockerfile or command arguments seems to work. I've never used VirtualBox or Docker Toolbox, this shouldn't be a wonky configuration screwed up by an old program because It works fine when launched from Visual Studio! Agh!

I hope that this is indeed a magic switch I haven't flipped, otherwise there is something very basic that I don't understand about what I'm working with.

Upvotes: 8

Views: 5904

Answers (3)

DTodd
DTodd

Reputation: 101

Thank you for the suggestions, it ended up being something rather frustrating. I think that it was a combination of two problems:

This stuff could be causing problems for others but I was mistaken, this did not work for me

First and foremost, no amount of docker configuration tells your website to listen for anything inside the container. I believe the website wasn't listening for anything when I initially tried most fixes.

The real problem was that the launchSettings.json in the .csproj Properties folder apparently overrides arguments from the command line!

Remember how I said '...run it alongside the first...'? That means I was never running the website on the correct set of ports. Apparently, -p 8001:443 -e ASPNETCORE_HTTPS_PORT=443 is not enough to make the site listen on 443. You must also set the sslPort in the launchSettings.json. Such is life, I suppose.

This is what finally worked

I ran docker-compose up in the solution directory. That's it. I didn't see a docker-compose.yml when I was looking in VS so I didn't think about it, but that's only because VS doesn't show solution-level items. I guess the thing that VS was doing that I wasn't was running docker-compose instead of individual commands.

Upvotes: 2

Michał Jarzyna
Michał Jarzyna

Reputation: 1916

If you are trying to run recent VS template you just need to follow this instruction:

Go to the Api project directory:

cd ./src/YourApiDirectory

Build Command:

docker build -f ./Dockerfile --force-rm -t yourapiimage:dev ..

Run Command:

docker run -it --rm -e "ASPNETCORE_ENVIRONMENT=Development" -p 58817:80 --name yourapiname yourapiimage:dev

please note that "-it" flag in last command will run your image in "interactive" mode. Also please note I am using only http connection via port 58817.

Upvotes: 3

coolcake
coolcake

Reputation: 2977

When directly launch with Docker profile which is done via docker-compose file in Visual Studio, visual studio behind the screen merges different override files and does different tasks and one of them is attaching remote debugger in the container etc.

To help you I've created a sample asp.net core api via Visual Studio 2019 selecting .Net Core 3.0.

The following is the docker-compose that VS2019 generated on my machine when I launched my API via VS2019.

docker-compose  -f "C:\Users\myuser\source\repos\testwebcore\docker-compose.yml" -f "C:\Users\myuser\source\repos\testwebcore\docker-compose.override.yml" -f "C:\Users\myuser\source\repos\testwebcore\obj\Docker\docker-compose.vs.debug.g.yml" -p dockercompose14364360289538262671 --no-ansi up -d --build --force-recreate --remove-orphans

I can get it work directly on powershell by running the following command, here I am using the same settings used in the override file by default created by VS2019. You have to run this command from parent folder outside the project folder.

docker-compose  -f "C:\Users\myuser\source\repos\testwebcore\docker-compose.yml" -f "C:\Users\myuser\source\repos\testwebcore\docker-compose.override.yml" up

If you have directly build and run with the docker file instead of docker-compose

You can build with the following command and like before should run from outside folder of the project file.

docker build -f testwebcore/Dockerfile -t testcore

After building the image, you can run it with the below command but before that you need to create a certificate and pass couple of environment variables to the run command. The details of this is mentioned in the following page.. Especially the section Windows subsystem for Linux. I am running Linux containers on my Windows 10 laptop.

So you have to run the following command to generate certificate

dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p testpassword

So the complete run command with environment variables and certificate generated above the command is as follows.

docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="testpassword" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -v c:\users\myuser\.aspnet\https:/https/ testcore:latest

Upvotes: 1

Related Questions