Exposing DotNet Core 6.0 WebApi From a Cloud Server With Docker
Tags: dotnet, docker, nginx, cloud
Published: 2022-01-23 16:06:15


## Overview
 In this article, we will go over how to deploy a DotNet Core 6.0 Web API endpoint on a cloud server.  I will be using [Linode](https://linode.com) as my cloud hosting provider because you can spin up a hosting instance for $5 / month.  I will use [Cloudflare](https://cloudflare.com) as my public proxy since they have a free service to proxy incoming requests to an SSL connection.

## Getting Started
First, let's set up our Linode instance.  Once you have signed up, you can click on `Create Linode` on the dashboard.  When creating, I used the `Ubuntu` flavor of Linux.  In the Linode Plan section, you can select the Shared CPU plans and pick the Nanode 1GB instance.  This will give you 1GB of RAM, 1CPU, and 25GBs of storage for $5 / month.  Once that is created, you should see your instance now on your dashboard.

## Setting up Linode instance
Now let's go ahead and set up our instance.
+ SSH into our instance by typing `ssh root@<ipaddress>` and entering your password in your terminal.
+ Run `apt-get update`. 
+ Install Git by running `apt install git-all`.
+ Install Docker by running:
````
apt-get update
apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
````

+ Install Nginx by running `apt update` then `apt install nginx`.

For now, we are done with installing what we need on our Linode instance.

## Setting up Cloudflare proxy
Let's set up our Cloudflare public proxy so we can serve our requests over https.  **<em>Note: We can do this on our Linode instance itself by using OpenSSL, but it requires extra configuration set up on nginx and why not  use a free service right?</em>**

+ Sign up for Cloudflare
+ Register a domain name
+ Log on to Cloudflare.
+ On the dashboard, you can click `Add a site`
+ Enter your domain name and select the free plan
+ On the dashboard, select the site you just created then select DNS on the left panel.
+ Add an A record that points to your Linode IP Address
	+ Make sure you select `Proxied` for your proxy status.

Your Cloudflare proxy should now be set up.  **<em>Note: You may have to wait up to 48 hours for your changes to propagate.</em>**

## Setting up our local environment
Since we will be using DotNet Core 6.0 to expose our API, we need to set up our development environment. **<em>Note: We won’t need to do this in our Linode instance since we will be running it inside a container.</em>**

+ Download the [.NET 6.0 SDK and runtime](https://dotnet.microsoft.com/en-us/download/dotnet/6.0).
+ Create a directory on your computer and run the command `dotnet new webapi`.  This will create your .NET project
+ Open the directory and initialize the Git repository by running `git init`.
+ Create a dockerfile in root directory and add the contents below:

````
# Download Microsoft SDK container
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine as build

WORKDIR /test

COPY ./*.csproj .
RUN dotnet restore

COPY . ./
RUN dotnet publish -c Release -o out

#Download Microsoft runtime container
FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine as runtime

WORKDIR /test

COPY --from=build /test/out .

EXPOSE 80

ENTRYPOINT [ "dotnet", "test.dll" ]
````

+ Now we can build this image by running `docker build -t my-dotnet-image .`
	+ The `-t` option specifies the tag name as `my-dotnet-image`
+ Create a container from the image by running `docker run -p 3000:80 my-dotnet-image`
	+ This creates the container and proxies the localhost's port 3000 to the container's port 80.
+ Now you should be able to open Postman and get a response back when you call `http://localhost:3000/weatherforecast`
+ Now you should commit your local changes to your Github repo.
	+ We will be pulling this down on your Linode cloud instance.

## Finishing up
Now let's wrap it up by ssh'ing into our cloud instance, pulling our code down from Github, and spinning up our container.  Then, we will configure nginx to proxy the requests to our container.

+ SSH into our Linode instance
+ Once in, run:

````
cd ..
mkdir dev
cd dev
git init
git remote add origin <your Github repo>
git pull origin <your Github branch>
docker build -t my-dotnet-image .
docker run -p 3000:80 my-dotnet-image
````

+ Here, we pulled down our code we ran locally and now are running it on the cloud.  The last thing to do is proxy incoming traffic to our container.  To do this, we need to go into our nginx config files.  The file we will update is the `default` file in the the `etc/nginx/sites-enabled` directory.

+ Once you `cd` into the directory, run `vi default` to open the default file.  Then, enter `i` to edit the file.  Then,  you can update the server section with the contents below:

````
server {
	listen 80;
	listen [::]:80;
	server_name <your cloudflare url>;
	location / {
		proxy_pass http://localhost:3000;
	}
}
````

+ Press your `esc` key to get out of edit mode, then type `:wq` to save your changes.
+ Lastly, we need to restart nginx by running `nginx -s stop` then `nginx`.

You now should be able to call `https://<your url>/weatherforecast` to get a valid response.

## Conclusion
In this article, we were able to use proxies and containers to cheaply expose an API to the public.  In a future article, I will write about setting up microservices, using this article as a jump point.