Easily migrate from IIS to Nginx with DockerFile and Do ckerCompose in Dotnet Application

Tohid haghighi
4 min readNov 12, 2023

--

For serve dotnet application we need to IIS and somebody can’t migrate to use linux base server because they think it is so hard but I learn you how to serve your application with nginx easily.

IIS vs Nginx

For running your application easily into Nginx you must do these 3 steps.

1- you must write DockerFile to your applicatio

2- You must write Docker-compose for your application and write all requiement for your project in this file like database,caching ,…

3- You must install Nginx and config this file.

At the countinue of this article we try to run over application with these 3 steps.

Up to this point in the tutorial, we’ve created a .NET console application and an ASP.NET Core web application. That’s a great start on our Docker journey, but containerization is about distributed systems, right? Let’s add a database to our ASP.NET Core web application and use Docker Compose to create a logical application.

# Learn about building .NET container images:
# https://github.com/dotnet/dotnet-docker/blob/main/samples/README.md
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG TARGETARCH
WORKDIR /source

# copy csproj and restore as distinct layers
COPY aspnetapp/*.csproj .
RUN dotnet restore -a $TARGETARCH

# copy and publish app and libraries
COPY aspnetapp/. .
RUN dotnet publish -a $TARGETARCH --no-restore -o /app


# final stage/image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app .
USER $APP_UID
ENTRYPOINT ["./aspnetapp"]

Using the application we created in the previous section, let’s modify our project. We’ll start by adding two NuGet packages of Dapper and System.Data.SqlClient, which will allow us to query our eventual Microsoft SQL Server instance.

<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.78" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.2" />
</ItemGroup>

</Project>

Now, let’s modify our ASP.NET Core application to register a SqlConnection instance along with using it to query our database.

using System.Data;
using System.Data.SqlClient;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Dapper;

namespace HelloDockerWeb
{
public class Startup
{
private IConfiguration Configuration { get; }

public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IDbConnection>(_ => {
var connectionString = Configuration.GetConnectionString("mssql");
var connection = new SqlConnection(connectionString);
connection.Open();
return connection;
});
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseRouting();

app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
var connection = context
.RequestServices
.GetRequiredService<IDbConnection>();

var result = await connection
.QueryFirstAsync<string>("Select @@version");

await context.Response.WriteAsync(result!);
});
});
}
}
}

Finally, let’s add a connection string to our yet-to-be-created database instance. In our appsettings.json file, we need to add a new ConnectionStrings section.

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"mssql": "Server=mssql;Database=master;User Id=sa;Password=Pass123!;"
}
}

Our next step is to create a docker-compose.yml file in our project. As mentioned previously, Docker Compose is a tool that allows us to define our application topology. We can configure any number of services and describe their relationship to each other. Once we’ve created an empty docker-compose.yml file in our project, we’ll want to paste the following description.

version: "3.3"
services:
web:
container_name: web
build:
context: ..
dockerfile: ./HelloDockerWeb/Dockerfile
depends_on: [mssql]
ports:
- "8080:80"
mssql:
image: "mcr.microsoft.com/mssql/server"
container_name: mssql
hostname: mssql
environment:
SA_PASSWORD: "Pass123!"
ACCEPT_EULA: "Y"
restart: unless-stopped
ports:
# So we can access the database
# From a tool like JetBrains Rider
# Optional for this demo
- "11433:1433"

Based on upper code our web application is depend on mssql database and you can set all ports in your file.

As we can see, our Compose definition has two services.

The web application uses the Dockerfile we defined in our previous example. We can set the file context, along with what other services this container requires. Finally, we map our port 80 on the container to our host port of 8080.

The Microsoft SQL Server container uses a Linux variant of the popular database. Reading the image’s documentation, we must set an administrator password and accept the end-user license agreement. We also set the hostname to mssql, which we’ve used in defining the connection string.

We may have noticed several run markers appearing in our editor when we pasted the compose definition. Compose allows us to start the complete description or select elements of the application. In this case, we’ll select the top-most run mark, which will execute a docker-compose up command. Our Deploy Log should contain messages from both containers.

Now for final step we want to serve our application in linux for this firstly you must install nginx in your server.

sudo apt install nginx

If your server don’t have git you can install Git because we must clone source code and pull new version then run docker-compose file.

sudo apt install git

Then you can go to Nginx location in etc/nginx/nginx.conf and edit this file with nano nginx.conf and add below code into http part.

  server { # simple load balancing
listen 80;
server_name big.server.com;
access_log logs/big.server.access.log main;

location / {
alias /var/www/html/panel;
index index.html index.php;
try_files $uri $uri/ $uri.html =404;
}

location /login {
alias /var/www/html/login;
index index.html index.php;
try_files $uri $uri/ $uri.html =404;
}

}

For each domain you can add location and then clone your file in other folder and then add locatio /login.

With this 4 line code you can serve your application easily and enjoy using dotnet application in linux.

--

--

Tohid haghighi
Tohid haghighi

Written by Tohid haghighi

Full-Stack Developer | C# | .NET Core | Vuejs | TDD | Javascript

No responses yet