Configuring SSL On An Asp.Net Core Docker Container
Tags: aspnetcore, docker, ssl, configure
Published: 2019-02-08 12:50:07

---
title: Configuring SSL On An Asp.Net Core Docker Container
published: true
description: 
tags: Asp.Net Core,Docker,SSL,Configure
---
![docker nginx](https://thepracticaldev.s3.amazonaws.com/i/q53mh4of450sz9yctyzz.jpg)

Asp.Net Core is a great platform to develop applications with. With one of the best runtimes, and a powerful language like C# backing it....and yea the cross-platformness of .Net Core it would only make sense to use it.  

So after building that next Billion-Dollar Idea, what next??...It would naturally be to put it up for us to use...well since .Net Core can run anywhere you would have quite a number of options to host your applications. But if you are reading this, chances is you are like me, you want to containerise your app with all the dependencies, Database or even if it is a mirco-services you are deploying. Docker would be a good choice.  After getting your VPS, and doing all the necessary docker configurations, you have been able to host that app.But yet in a world where security is everything, you are thinking of throwing in an ssl support to better your odds.

Well then, it is said _Talk Is Cheap Show Me The Code_ lol...lets get started then  Asp.Net core by default comes with a default light-weight web-server you can use for asp.net core apps. You can read more about kestrel [Here](https://stackify.com/what-is-kestrel-web-server/).

While Kestrel is cool, and gets the job done most of the time, it is not adequate enough in production environments, click [Here](https://stackoverflow.com/questions/48077748/how-to-use-pem-certificate-in-kestrel-directly) to know more

### The solution:

Reverse Proxy!!, we can also host an asp.net core application with a more matured webserver like Nginx...well, not exactly host...more like use the nginx for evrything and mirror the request to the main kestrel, this would allow us configure ssl and enjoy all the awesomeness with Nginx. You can read more about it [Here](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-2.2)

### Configuring The SSL

Well, back to the topic... we would make use of docker, certbot/letsencrypt.

#### Step 1
_SSH_ into your vm, then  run the following commands to install certbot

```
$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot python-certbot-nginx 
```

Then run the following and follow the prompt to install letsencrypt certificate for your domain

```
$ sudo certbot --nginx certonly
```

Make sure you note down the path to where certificate is stored, we would use this later.

#### Step 2
 Prepare your docker image for the web application

``` Docker
FROM microsoft/dotnet:2.1-aspnetcore-runtime
WORKDIR /app
ENV ASPNETCORE_URLS http://+:5000
EXPOSE 5000
COPY . .
ENTRYPOINT ["dotnet", "ExampleApp.dll"]
```
The key thing here is exposing port 5000, this is the port with which nginx would route requests to. 

Then push the image to a private docker registry. You can get a free one from [Treescale](treescale.com)

> Oh, also please forgive me for this method, i prefer to build the app locally and just push the image to a registry, it allows for much lighter file size. And there is no need to copy the app files to the vm, and for CI/CD i find this useful.

#### Step 3
Prepare the docker compose file, yea we are going to use docker compose!!...we are going to orchestrate the web application, and any other dependencies like a database etc together with the nginx server.

so you should have a file called **docker-compose.yml**

```
version: "3"
services:
    web:
        image: repo.treescale.com/herocod3r/{sampleApp}
        expose:
            - "5000"
        depends_on:
            - mongo
    mongo:
       image: mongo:latest
       ports:
       - "27017:27017"
       volumes:
       - "/home/app/mymongo:/data/db"
       command: mongod --auth
    proxy:
        build:
            context:  ./nginx
            dockerfile: Dockerfile
        ports:
            - "80:80"
            - "443:443"
        volumes:
             - /etc/letsencrypt/:/etc/letsencrypt/
        links:
            - web
```
**Note!** in the proxy service we are mounting to the path _/etc/letsencrypt/_ so we can have access to the certificate files.

#### Step 4
Prepare your nginx config file and docker image. Create a folder called **nginx** as seen in the proxy service above. Then create a file called **nginx.conf** and put into it the following

```
worker_processes 4;
 
events { worker_connections 1024; }
 
http {
    sendfile on;
 
    upstream app_servers {
        server web:5000;
    }
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name {url} www.{url};
        return 301 https://www.$server_name$request_uri;
    }
 
    server {
        listen 443 ssl;
        ssl_certificate /etc/letsencrypt/live/{url}/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/{url}/privkey.pem;
 
        location / {
            proxy_pass         http://app_servers;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }
    }
}
```

**Note!!** replace {url} with the registered domain name we did with certbot. So for example if you registered _example.com_ replace {url} with _example.com_

And lastly your **docker** file for the proxy

```
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
```

#### Step 5

In the end you should have a folder with this structure

```
MyApp
    - docker-compose.yml
    nginx
      - nginx.conf
      - Dockerfile
```

In the end you need to copy the _MyApp_ folder to your VM. Also make sure you have installed docker, and docker-compose. 

Then SSH into your vm navigate to the MyApp folder and run

```
docker-compose up
```

**Note** if you are using treescale, Make sure you have signed in to your treescale registry to be able to pull the web image

You might also need to append sudo when running commands, depending on your user privilege.

If all goes right, you should have the ssl all setup, congratz!!