Jump to content

C# Asp.net how to switch Docker to Linux Container

Hello, I am currently developing an Asp.net application I am developing it on windows using Visual Studio 2019, how do I easily make a Docker image that I can run on Linux?
Thanks in advance

 

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, zhnu said:

Both Docker and Microsoft have documentation regarding this, if you can run your docker on windows it won't be a problem on linux.
Just be careful with file paths.

when I try to pull it it says "image operating system "windows" cannot be used on this platform"

Link to comment
Share on other sites

Link to post
Share on other sites

4 minutes ago, dragonboy144 said:

when I try to pull it it says "image operating system "windows" cannot be used on this platform"

If your Container is based on Windows it's not going to run on Linux. The opposite would work (i.e. a Linux container can run on Windows, by running inside a Linux VM)

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

Just now, Eigenvektor said:

If your Container is based on Windows it's not going to run on Linux. The opposite would work (i.e. a Linux container can run on Windows, by running inside a Linux VM)

thats why I asked how to switch the docker build target to linux 

Link to comment
Share on other sites

Link to post
Share on other sites

7 minutes ago, dragonboy144 said:

thats why I asked how to switch the target to linux 

You need to base your container on Linux. The Dockerfile you use to create your docker image needs to use a Linux container as a base. But I'm not sure this is even possible with ASP.NET. Does ASP.NET even run on Linux?

 

~edit

FROM centos:centos7

RUN yum -y update \
 && yum -y install epel-release \
 && yum -y update \
 && yum -y install \
    git \
    java-1.8.0-openjdk-devel \
    jq \
    unzip \
    wget \
 && yum clean all \
 && rm -rf /var/cache/yum

 

For example this is part of a Dockerfile that creates a Docker Image that is based on CentOS 7 and adds Java 8 into it. So the container that is created from this image is running Linux and can be run on any Linux host. It can also (sort of) run on Windows, because Docker on Windows creates a Linux VM which then runs the Docker container. Docker on Linux on the other hand can't create a Windows VM to run containers based on Windows (because, you know, licensing)

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

3 minutes ago, Eigenvektor said:

You need to base your container on Linux. The Dockerfile you use to create your docker image needs to use a Linux container as a base. But I'm not sure this is even possible with ASP.NET. Does ASP.NET even run on Linux?

I think that it's possible, since when I open the project it tells me that my Docker server Host is configured for "Linux" but my Project is configured for "Windows" and also I have found this: https://stackoverflow.com/questions/55997618/changing-asp-net-core-docker-target-from-windows-to-linux, but the first answer doesn't work and I dont understand the second one  

Link to comment
Share on other sites

Link to post
Share on other sites

5 minutes ago, dragonboy144 said:

I think that it's possible, since when I open the project it tells me that my Docker server Host is configured for "Linux" but my Project is configured for "Windows" and also I have found this: https://stackoverflow.com/questions/55997618/changing-asp-net-core-docker-target-from-windows-to-linux, but the first answer doesn't work and I dont understand the second one  

Yeah, I also found a Document from Microsoft

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-5.0

 

Can you see the Dockerfile that is used to create the Docker image? Or is that something that Visual Studio creates under the hood? Normally the file is called "Dockerfile" with no file extension.

 

The second answer is basically what I'm trying to say. Your Dockerfile starts with a line that says "FROM <windows>", which means the Docker image it creates is based on Windows. This needs to be changed so that it is based on some Linux image instead.

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, Eigenvektor said:

Yeah, I also found a Document from Microsoft

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-5.0

 

Can you see the Dockerfile that is used to create the Docker image? Or is that something that Visual Studio creates under the hood?

 

The second answer is basically what I'm trying to say. Your Dockerfile starts with a line that says "FROM <windows>", which means the Docker image it creates is based on Windows. This needs to be changed so that it is based on some Linux image instead.

#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
#For more information, please see https://aka.ms/containercompat 

FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
ARG source
WORKDIR /inetpub/wwwroot
COPY ${source:-obj/Docker/publish} .

This is the Dockerfile, but I dont know how I need to change it, I'm very new to docker

Link to comment
Share on other sites

Link to post
Share on other sites

Just now, dragonboy144 said:

#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
#For more information, please see https://aka.ms/containercompat 

FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
ARG source
WORKDIR /inetpub/wwwroot
COPY ${source:-obj/Docker/publish} .

This is the Dockerfile, but I dont know how I need to change it, I'm very new to docker

 

It's a simple text file, so you should be able to edit it. The first line is the issue here:

FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019

This basically means your Docker image is based on top of some Windows Server core image. You can essentially think of "FROM" as inheritance. Your Image extends another image by adding additional stuff on top of it.

 

So to make it based on Linux, as far as I can tell from the Stackoverflow answer that line should read

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base

instead. This would make it based on a .NET core Linux image.

 

Maybe these will help shed some more light onto it:

https://docs.microsoft.com/en-us/visualstudio/containers/container-tools?view=vs-2019

https://docs.microsoft.com/en-us/dotnet/core/docker/build-container?tabs=linux

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

12 hours ago, Eigenvektor said:

 

It's a simple text file, so you should be able to edit it. The first line is the issue here:


FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019

This basically means your Docker image is based on top of some Windows Server core image. You can essentially think of "FROM" as inheritance. Your Image extends another image by adding additional stuff on top of it.

 

So to make it based on Linux, as far as I can tell from the Stackoverflow answer that line should read


FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base

instead. This would make it based on a .NET core Linux image.

 

Maybe these will help shed some more light onto it:

https://docs.microsoft.com/en-us/visualstudio/containers/container-tools?view=vs-2019

https://docs.microsoft.com/en-us/dotnet/core/docker/build-container?tabs=linux

When I do that and run Docker Build I do get an image, but its just 200mb in size, the normal windows image I get is 8+gb also when I run it I cant find a way to acces the website

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, dragonboy144 said:

When I do that and run Docker Build I do get an image, but its just 200mb in size, the normal windows image I get is 8+gb also when I run it I cant find a way to acces the website

The bigger question is, does the image run? That a Docker image based on a (slim) Linux installation instead of a Windows installation is smaller isn't that surprising, really.

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

4 minutes ago, Eigenvektor said:

The bigger question is, does the image run? That a Docker image based on a (slim) Linux installation instead of a Windows installation is smaller isn't that surprising, really.

It does run, but I cant figure out how to see my website localhost and localhost:80 don't work

Link to comment
Share on other sites

Link to post
Share on other sites

3 minutes ago, dragonboy144 said:

It does run, but I cant figure out how to see my website localhost and localhost:80 don't work

How did you start the container? You need to map ports inside the container to local ports to be able to connect to it from your local machine. Can you post the command line you used?

 

~edit: It should be something like "-p 8080:80". That would make the port "80" inside the container available as "8080" on your local machine.

https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p---expose

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

6 minutes ago, Eigenvektor said:

How did you start the container? You need to map ports inside the container to local ports to be able to connect to it from your local machine. Can you post the command line you used?

 

~edit: It should be something like "-p 8080:80". That would make the port "80" inside the container available as "8080" on your local machine.

https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p---expose

I pressed run on the docker desktop app😅 I will try on the command line in sec

Link to comment
Share on other sites

Link to post
Share on other sites

5 minutes ago, dragonboy144 said:

I pressed run on the docker desktop app😅

I'm afraid I don't know how to do it in the UI 😅 I use Docker primarily from the command line (and usually with a docker-compose.yml) since most of our stuff runs on Linux servers which don't have a UI. I assume the desktop app does not publish ports by default.

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

13 minutes ago, Eigenvektor said:

I'm afraid I don't know how to do it in the UI 😅 I use Docker primarily from the command line (and usually with a docker-compose.yml) since most of our stuff runs on Linux servers which don't have a UI.

Can I just run the command from anywhere on the system or do I have to be in a certain folder?

Link to comment
Share on other sites

Link to post
Share on other sites

Just now, dragonboy144 said:

Can I just run the command from anywhere on the system or do I have to be in a certain folder?

"docker run <image>" should work from anywhere, provided Docker is in your path.

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

7 minutes ago, Eigenvektor said:

"docker run <image>" should work from anywhere, provided Docker is in your path.

I tried docker run -p 8081:80 MYAPPLICATION, it gives me neither an error nor an run confirmation

When I do docker stats it shows no running containers
In the desktop application it shows me that the images got created with the right port but Exited(0)

Link to comment
Share on other sites

Link to post
Share on other sites

8 minutes ago, dragonboy144 said:

I tried docker run -p 8081:80 MYAPPLICATION, it gives me neither an error nor an run confirmation

When I do docker stats it shows no running containers
In the desktop application it shows me that the images got created with the right port but Exited(0)

The command looks correct. It should run in the foreground, blocking the terminal until you press Ctrl+C. So that means your application exited immediately. Can you check whether MYAPPLICATION referenced the correct image?

 

You can use "docker images" to get a list of all the images on your system. Output should look similar to this.

$ docker images
REPOSITORY                                                           TAG           IMAGE ID       CREATED         SIZE
mysql                                                                latest        ab2f358b8612   4 weeks ago     545MB
nginx                                                                stable        05f64a802c26   5 weeks ago     133MB
mariadb                                                              latest        3a348a04a815   7 weeks ago     407MB

 

So e.g. in this case you'd use "docker run -p 3307:3306 mariadb" to start MariaDB and you should see something like this:

$ docker run -p 3307:3306 mariadb
2021-01-15 10:10:00+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.8+maria~focal started.
2021-01-15 10:10:01+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2021-01-15 10:10:01+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.8+maria~focal started.
2021-01-15 10:10:01+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
	You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD

 

In this case it fails, because MariaDB requires some additional environment parameters that I didn't provide, but the command as such was correct.

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

4 minutes ago, Eigenvektor said:

The command looks correct. It should run in the foreground, blocking the terminal until you press Ctrl+C. So that means your application exited immediately. Can you check whether MYAPPLICATION referenced the correct image?

 

You can use "docker images" to get a list of all the images on your system. Output should look similar to this.



$ docker images
REPOSITORY                                                           TAG           IMAGE ID       CREATED         SIZE
mysql                                                                latest        ab2f358b8612   4 weeks ago     545MB
nginx                                                                stable        05f64a802c26   5 weeks ago     133MB
mariadb                                                              latest        3a348a04a815   7 weeks ago     407MB

 

So e.g. in this case you'd use "docker run -p 3307:3306 mariadb" to start MariaDB and you should see something like this:



$ docker run -p 3307:3306 mariadb
2021-01-15 10:10:00+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.8+maria~focal started.
2021-01-15 10:10:01+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2021-01-15 10:10:01+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.5.8+maria~focal started.
2021-01-15 10:10:01+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
	You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD

 

In this case it fails, because MariaDB requires some additional environment parameters that I didn't provide, but the command as such was correct.

I checked, the name is correct when I execute the command the terminal gets blocked for a second then goes back to command line 

Edit: I just noticed that the mcr.microsoft.com/dotnet/core/aspnet image has the same size as the image of my project so I assume that something went wrong when creating the image and my code didnt get added

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, dragonboy144 said:

I checked, the name is correct when I execute the command the terminal gets blocked for a second then goes back to command line 

That would mean your container stops immediately. Does your Dockerfile define a "CMD" or "ENTRYPOINT"? The container must run something that is blocking in nature, otherwise the container terminates again.

 

So e.g. the mariadb container simply runs MariaDB as a foreground service that continues running until you press Ctrl+C. Your container must do something similar, so it would have to e.g. run your ASP.NET app in the foreground. See the tutorial that @zhnu linked. The Dockerfile contains this line:

ENTRYPOINT ["dotnet", "aspnetapp.dll"]

 

Remember to either quote or @mention others, so they are notified of your reply

Link to comment
Share on other sites

Link to post
Share on other sites

4 hours ago, zhnu said:


FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env <- This fetches from docker hub the base image and because it is marked as "AS build-env" it can be used later as it was an image 
WORKDIR /app <- This makes it so all the rest of the commands will run with a base path inside the container /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./ -> So because of previous line it will copy every file on the Dockerfile location with the extension ".csproj" to the /app dir inside the docker container
RUN dotnet restore -> Runs the command "dotnet restore" inside the docker container so it fetches project dependencies

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 <- Because we fetch another image everything inside the container will now be "reseted" to this
WORKDIR /app
COPY --from=build-env /app/out . <- Because with had above set those steps to run "AS build-env" we can access their content and copy the compiled code from build-env:/app/out to this container /app
ENTRYPOINT ["dotnet", "aspnetapp.dll"] <- This tells "docker run" the command to run after it start

 

I tried and it doesn't work, I am now 99% sure that you can't run Asp.Net Webforms on Linux, just Asp.Net Core so I just gave up and setup an windows server 

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×