stak
stak

Reputation: 159

For existing ASP.NET Core MVC project on Windows build server, how to target a Docker container without disturbing earlier build pipeline stages?

Can we add two extra steps at the end of the existing build pipeline? It would be a step to publish to an OS independent binary format and a step to run “docker build” to put the published app into a container.


We still need to deploy to a non-container IIS web site. We’d rather not rework our entire build pipeline or change the C# compile to be inside a Docker container.

The early build pipeline stages would most likely not run in a container or have licensing questions. For example, third party code quality scanning, automatic unit tests and code metrics.

Environment: - ASP.NET MVC Core v3.0, Visual Studio 2019, C#, git - Windows build server, Windows production server for hosted web site - Multiple build pipeline related tools unable to run in a container - Docker desktop 19.03.02 and the container will run on a different server than the non-Docker web site - Docker desktop set to use Linux containers. Container will be not hosted in Azure or AWS. Kubernetes may be used in the future.
- Developers develop locally either with a local IIS hosted site or against a Dev server ISS host web site.

Approach 1: I created a Visual Studio 2019 ASP.NET Core v3.0 MVC app with a Docker support. This requires us to rework our entire build pipeline. Did not purse this.

Approach 2: 1. In Visual Studio 2019, create a new ASP.NET Core MVC app without any Docker support. It’s empty with just the default ASP.NET Visual Studio project template’s web page. This app does not reference any databases, external services or read/write to the server’s local disk

2. Compile, build the site and browse to it http://localhost:44327 shows the start page

3. Right click on the project inside the solution and select Publish
Select an empty directory for target location
Delete existing files: True
Configuration: Release
Edit the publish options
Publish method: File System
Configuration: Release
Target Framework: netcoreapp 3.0
Deployment Mode: Framework-Dependent
Target Runtime: Portable
Delete all existing files prior to publish: True
No databases found in the project

4. Build the Docker image
Open a Visual Studio 2019 command prompt, change to the publish directory
Run “docker build -t aspnetcoretestproject2 .” to build the Docker image
Run “docker run -d -p 8080:80 --name myapp aspnetcoretestproject2” to run the Docker container

5. Open a web browser, go to http://localhost:8080 and no page is displayed, Chrome and Firefox both show a can’t connect error
Firefox: Firefox can’t establish a connection to the server at localhost:8080.
Chrome: ERR_NETWORK_ACCESS_DENIED


Dockerfile
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "aspnetcoretestproject2.dll"]
EXPOSE 80

Output from "docker build -t aspnetcoretestproject2 ."

Sending build context to Docker daemon  4.687MB
Step 1/5 : FROM mcr.microsoft.com/dotnet/core/aspnet:3.0
 ---> 675139f95df1
Step 2/5 : WORKDIR /app
 ---> Running in ab5f645d61cf
Removing intermediate container ab5f645d61cf
 ---> 4bb71c776e95
Step 3/5 : COPY . .
 ---> b7d24c41184b
Step 4/5 : ENTRYPOINT ["dotnet", "aspnetcoretestproject2.dll"]
 ---> Running in 557ca917185f
Removing intermediate container 557ca917185f
 ---> 3b578aa4bb7f
Step 5/5 : EXPOSE 80
 ---> Running in c0a9911668a9
Removing intermediate container c0a9911668a9
 ---> 316323857411
Successfully built 316323857411
Successfully tagged aspnetcoretestproject2:latest
SECURITY WARNING: You are building a Docker image from Windows against a   non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directorie

docker image ls

REPOSITORY                             TAG                 IMAGE ID            CREATED              SIZE
aspnetcoretestproject2                 latest              316323857411        About a minute ago   212MB
mcr.microsoft.com/dotnet/core/sdk      3.0-buster          4422e7fb740c        3 weeks ago          689MB
mcr.microsoft.com/dotnet/core/aspnet   3.0                 675139f95df1        3 weeks ago          207MB
mcr.microsoft.com/dotnet/core/aspnet   3.0-buster-slim     675139f95df1        3 weeks ago          207MB
k8s.gcr.io/kube-proxy                  v1.14.6             ed8adf767eeb        8 weeks ago          82.1MB
k8s.gcr.io/kube-apiserver              v1.14.6             0e422c9884cf        8 weeks ago          209MB
k8s.gcr.io/kube-scheduler              v1.14.6             d27987bc993e        8 weeks ago          81.6MB
k8s.gcr.io/kube-controller-manager     v1.14.6             4bb274b1f2c3        8 weeks ago          157MB
docker/kube-compose-controller         v0.4.23             a8c3d87a58e7        4 months ago         35.3MB
docker/kube-compose-api-server         v0.4.23             f3591b2cb223        4 months ago         49.9MB
alpine                                 3.5                 f80194ae2e0c        8 months ago         4MB
k8s.gcr.io/coredns                     1.3.1               eb516548c180        9 months ago         40.3MB
k8s.gcr.io/etcd                        3.3.10              2c4adeb21b4f        10 months ago        258MB
k8s.gcr.io/pause                       3.1                 da86e6ba6ca1        22 months ago        742kB
node                                   6.11.5              852391892b9f        23 months ago        662MB

docker container ls

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
defe82a7223a        f80194ae2e0c        "ping 8.8.8.8"      6 minutes ago           Up 6 minutes                            k8s_testpod_demo_default_dd2702f7-eeac-11e9-a181-00155dde9201_5

Publish directory contents

    10/16/2019  09:31 AM               340 .dockerignore
    10/16/2019  01:29 PM               146 appsettings.Development.json
    10/16/2019  01:29 PM               192 appsettings.json
    10/16/2019  04:24 PM           106,602 AspNetCoreTestProject2.deps.json
    10/16/2019  04:24 PM             9,216 AspNetCoreTestProject2.dll
    10/16/2019  04:24 PM           159,744 AspNetCoreTestProject2.exe
    10/16/2019  03:45 PM               224 AspNetCoreTestProject2.runtimeconfig.json
    10/16/2019  04:24 PM            35,840 AspNetCoreTestProject2.Views.dll
    10/16/2019  07:12 PM               160 Dockerfile
    10/16/2019  04:24 PM               566 web.config
    10/16/2019  04:24 PM              wwwroot

Is there a missing step or miscofiguration in the Dockerfile?

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.0
    WORKDIR /app
    COPY . .
    ENTRYPOINT ["dotnet", "aspnetcoretestproject2.dll"]
    EXPOSE 80

The expected output would be for the web site's main page to be visible when browsing to localhost:8080.

I tried the nodejs based demo for appointment book from the docker help web site and it works and displays the start page for the web site. So a website inside a container on my local machine can be browsed from a browser on the same local machine.

Links .NET Core – including ASP.NET .Core - https://hub.docker.com/_/microsoft-dotnet-core
https://learn.microsoft.com/en-us/dotnet/core/docker/introduction
.NET examples https://github.com/docker/labs/blob/master/windows/readme.md
https://learn.microsoft.com/en-us/dotnet/core/docker/build-container
Visual Studio 2019 Docker support https://learn.microsoft.com/en-us/visualstudio/containers/overview?view=vs-2019
Building a .net core all inside a Docker container - https://docs.docker.com/engine/examples/dotnetcore/
Troubleshooting Docker inside Visual Studio https://learn.microsoft.com/en-us/visualstudio/containers/troubleshooting-docker-errors?view=vs-2019

Upvotes: 2

Views: 1522

Answers (2)

Alexn
Alexn

Reputation: 21

Put the command "EXPOSE" before the command "ENTRYPOINT". Also, you forgot to add environment variables for ASP Core runtime.

Fixed Dockerfile:

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0
WORKDIR /app
EXPOSE 80 # container listens on the port at runtime
ENV ASPNETCORE_URLS=http://+:80 # bind port 80 for http
COPY . .
ENTRYPOINT ["dotnet", "AspNetCoreTestProject2.dll"]

Read more about the ASPNETCORE_URLS here

Upvotes: 0

stak
stak

Reputation: 159

Fixed it by two changes:
1) Change the DLL name in the Dockerfile to be case sensitive. The app runs inside a container whose OS is case sensitive Linux.
2) Change the port number mapping in the "docker run" commmand

Troubleshooting steps:
1. In a Visual Studio 2019 command prompt window, go to the publish directory
2. Run the web site "dotnet AspNetMvcCoreTestApp2.dll". This command is the same one run inside the Docker container.
It produces this output. Notice the port number 5000
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
3. Open a browser and go to http://localhost:5000/ and the start page of the site is displayed
4. Change the Dockerfile to list the correct DLL name including case sensitive letters. Also verify thta the .NET core version in the Dockerfile is the same as the one in the Visual Stuido 2019 explorer.

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "AspNetCoreTestProject2.dll"]
EXPOSE 80
  1. Remove any images for the container in Docker if needed
    Run "docker image ls" and make note of the IMAGE_ID of the existing image if it exists
    Run "docker rmi IMAGE_ID" to remove the image
  2. Build the docker image "docker build -t aspnetcoretestproject2 ."
  3. Enter "docker image ls" and make note of the IMAGE_ID value for aspnetcoretestproject2
    REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
    aspnetcoretestproject2                 latest              58c92979be61        3 minutes ago       212MB
    mcr.microsoft.com/dotnet/core/sdk      3.0-buster          4422e7fb740c        3 weeks ago         689MB
  1. Run the docker image mapping local host port 5000 to port 80 inside the Docker container
    "docker run -d -p 5000:80 58c92979be61"
  2. Verify the docker container is running by "docker container ls"
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
    c52ab21b9c25        58c92979be61        "dotnet AspNetCoreTe…"   4 seconds ago       Up 2 seconds        0.0.0.0:5000->80/tcp   magical_leavitt
    e4152fcb2233        f80194ae2e0c        "ping 8.8.8.8"           3 minutes ago       Up 3 minutes                               k8s_testpod_demo_default_dd2702f7-eeac-11e9-a181-00155dde9201_2
  1. Open web browser and enter http://localhost:5000 in the URL bar. This should show the start page of the ASP.NET web site

Upvotes: 0

Related Questions