Note: Please read the previous post before continuing with this one, I discuss the basics of Docker and show how to deploy a simple application.
Problem
How to containerize multiple ASP.NET Core applications and deploy to Azure.
Scenario
Below is a screenshot of an example solution with two applications, Web and API. You could download the source code from GitHub.
API: has controller with CRUD operations for a movies database. It uses a class library Data, which contains repositories. Database is hosted in Azure and connection string stored in application settings (appsettings.json).
Web: has Razor Pages for CRUD operations and calls the API using HttpClient
.
Solution
Create a Dockerfile for API project (Dockerfile_api
):
# Build Stage
FROM microsoft/aspnetcore-build AS build-env
WORKDIR /src
# Copy only .csproj and restore
COPY ./Fiver.Asp.Docker.Data/Fiver.Asp.Docker.Data.csproj ./Fiver.Asp.Docker.Data/
RUN dotnet restore ./Fiver.Asp.Docker.Data/
COPY ./Fiver.Asp.Docker.Api/Fiver.Asp.Docker.Api.csproj ./Fiver.Asp.Docker.Api/
RUN dotnet restore ./Fiver.Asp.Docker.Api/
# Copy everything else and build
COPY ./Fiver.Asp.Docker.Data/ ./Fiver.Asp.Docker.Data/
RUN dotnet build ./Fiver.Asp.Docker.Data/
COPY ./Fiver.Asp.Docker.Api/ ./Fiver.Asp.Docker.Api/
RUN dotnet build ./Fiver.Asp.Docker.Api/
# publish
RUN dotnet publish ./Fiver.Asp.Docker.Api/ -o /publish --configuration Release
# Publish Stage
FROM microsoft/aspnetcore
ENV MOVIES_DB_CONN=
WORKDIR /app
COPY --from=build-env /publish .
ENTRYPOINT ["dotnet", "Fiver.Asp.Docker.Api.dll"]
Note: in order to optimise the process of building images (using cache in Docker) I am copying .csproj
first to restore packages and then rest of the files. Also note that API project uses the class library so we’ll need to copy this too.
Create a Dockerfile for Web project (Dockerfile_web
):
# Build Stage
FROM microsoft/aspnetcore-build AS build-env
WORKDIR /src
# Copy only .csproj and restore
COPY ./Fiver.Asp.Docker.Web/Fiver.Asp.Docker.Web.csproj ./Fiver.Asp.Docker.Web/
RUN dotnet restore ./Fiver.Asp.Docker.Web/
# Copy everything else and build
COPY ./Fiver.Asp.Docker.Web/ ./Fiver.Asp.Docker.Web/
RUN dotnet build ./Fiver.Asp.Docker.Web/
# publish
RUN dotnet publish ./Fiver.Asp.Docker.Web/ -o /publish --configuration Release
# Publish Stage
FROM microsoft/aspnetcore
ENV API_URL=
WORKDIR /app
COPY --from=build-env /publish .
ENTRYPOINT ["dotnet", "Fiver.Asp.Docker.Web.dll"]
Create a docker-compose.yml
file:
version: '3.3'
services:
api:
build:
context: .
dockerfile: Dockerfile_api
image: naushadt25/api
ports:
- "8080:80"
environment:
- "MOVIES_DB_CONN=Server=..."
web:
build:
context: .
dockerfile: Dockerfile_web
image: naushadt25/web
ports:
- "8090:80"
environment:
- "API_URL=http://api/movies"
depends_on:
- api
Build images for API and Web applications using either docker build
command:
docker build -f Dockerfile_api -t naushadt25/api:latest .
docker build -f Dockerfile_web -t naushadt25/web:latest .
Or Run docker-compose up
to test locally, which will also build the images of not already present:
Note: in order to push images to Docker Hub they need to be in username/image format. In case you’ve named your images differently than this, you could create a copy of image using docker tag
command as discussed in the previous post.
Login to Docker Hub:
Run docker push
to upload images to Docker Hub:
docker push naushadt25/api
docker push naushadt25/web
Next you can deploy to Azure using Azure “Web App for Containers” as discussed in the previous post. You’ll need to change the Application Settings for your applications in Azure; Web application needs a URL to API:
And API application needs a connection string:
You could now browse the application:
Resources
For an excellent and in-depth look at Docker, please check out Wes Higbee courses on Pluralsight.
Source Code
GitHub: https://github.com/TahirNaushad/Fiver.Asp.Docker.Vs