Securing an ASP.NET Core app on Ubuntu using Nginx and Docker – Part II

 In Part I of this tutorial, we created a self-contained ASP.NET Core web application using the new dotnet CLI tools, configured PuTTY and PSCP to SSH and transfer files, and then finally transfer the self-contained app from a Windows environment to the Ubuntu VM.

Currently, you should have a .NET Core Hello World application self-contained in the /etc/netcore/ directory on your Ubuntu machine. Now we will set up Docker to host the self-contained app.

Part II

  • Setting up Docker and creating a Docker Image on Ubuntu 16.04

Part III

  • Configuring Nginx for SSL termination
  • Building and Running the Docker Image.


Step 1: Install Docker 


Docker allows us to package our application into a standardized unit by wrapping it in a complete filesystem that contains everything needed to run. Since anything may be wrapped in a docker container, we are guaranteed it will always run the same, regardless of its environment. Docker is lightweight, open source, and secure by default. To find out more, visit the docker info page.

Ensure Ubuntu has a 64-bit kernel of version 3.10 or greater.

To check the version, simply type uname -r in the Ubuntu console.

Update package information and ensure that APT installs https method and CA certificates.

sudo apt-get update

sudo apt-get install apt-transport-https ca-certificates

Add the new GPG key (import an RSA key) (tip: right click = paste in PuTTY)

sudo apt-key adv --keyserver hkp:// --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

Open (or create) /etc/apt/sources.list.d/docker.list

sudo nano /etc/apt/sources.list.d/docker.list

In the docker.list file, remove any existing entries and add an entry for Ubuntu 16.04 (paste the following) (ctrl+O to save, ctrl+X to exit nano text editor)

deb ubuntu-xenial main

Update the APT package index, purge the old repo if it exists, and verify APT is pulling form the right repository

sudo apt-get update

sudo apt-get purge lxc-docker

apt-cache policy docker-engine

Install the linux-image-extra-* kernal package to allow use of aufs storage driver

sudo apt-get update

sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual

Update APT package index and install Docker

sudo apt-get install docker-engine

Start the docker daemon and ensure docker is installed correctly.

sudo service docker start

sudo docker run hello-world

Note: docker checks to see if you created an image “hello-world” and if it doesn’t find it, it downloads it from the docker hub.

Step 2: Creating your Docker image

To create a Docker image, we need to provide a set of instructions for Docker to execute every time it wants to build the image. To do this, we need a Dockerfile, a text document that contains all the commands a user could call on the command line to assemble an image. 

Create the Dockerfile in the project directory.
cd /etc/netcore/mySecureApp/
sudo nano Dockerfile

Enter the following in your Dockerfile

FROM microsoft/dotnet:latest
COPY . /app
RUN ["dotnet", "restore"]
RUN ["dotnet", "build"]
EXPOSE 443/tcp
EXPOSE 5001/tcp
ENTRYPOINT ["dotnet", "run"]

The instructions do the following:

FROM – Tells Docker that we are basing the image from microsoft/dotnet:latest . This image exists in the Docker Hub and is downloaded upon building, and since it is from Microsoft themselves we are guaranteed it will be the latest version containing all the dependencies for .NET Core on Linux.

COPY – copies the current directory to /app which will be our work directory

WORKDIR – Sets the working directory to /app for the following instructions.

RUN – Executes the following commands. Note that whitespace isn’t really considered, so we must provide a string array and Docker will take care of putting spaces between each index.

EXPOSE – Exposes a port on the container. We will need 5001 exposed for http and 443 for ssl traffic.

ENV – Sets the ASPNETCORE_URLS environment so that .NET Core knows what port it should belong on. 

Now it’s time to build the docker image.

sudo docker build -t mydemos:mySecureApp .

Note: -t adds a tag that we can identify the image by and the trailing period tells docker to look in the current directory for the Dockerfile to build from.

Run the Docker image

sudo docker run -p 8080:5001 -p 8081:443 -t mydemos:mySecureApp

Note:     -p specifies which port to map on the local machine to inside the container

After completing Part I and Part II, you may now visit the dockerized self-contained app at

http://<linux machine ip>:5001

In Part III we shall discuss setting up Nginx so we may secure our app via SSL termination.


Leave a Reply