Sunday, January 23, 2022

Deploy multi-container docker-compose solution on Azure

In this tutorial I will show you how to deploy a multi-container solution to Azure. The example I will use is an ASP.NET 6.0 Razor web app that works with a SQL Server database. The web app and database server run in separate containers. We will setup the solution on the Azure portal.

Assumptions

  • .NET 6.0 is installed on your computer
  • Docker Desktop is installed on your computer
  • You have an Azure subscription
  • Git is installed on your computer
  • You have a docker hub account

Getting started

In a previous example, I discuss docker-compose with ASP.NET 6.0 & SQL Server.

Clone the ASP.NET 6.0 sample startup application by running the following command from a working directory on your computer:

git clone https://github.com/medhatelmasry/AspMsSQL-docker-compose

Change into the newly cloned directory with:

cd AspMsSQL-docker-compose

The application is a simple ASP.NET 6.0 Razor application that should be very familiar to any .NET developer. 

To understand how you can run this solution, you must inspect the following two files:

Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:6.0
COPY dist /app
WORKDIR /app
EXPOSE 80/tcp
ENTRYPOINT ["dotnet", "AspMsSQL.dll"]

Docker file is used to build the web app. In line 2 above, the dist folder is copied into the image. Therefore, we must create a dist folder with the following command:

dotnet publish -o dist

docker-compose.yml

version: '3.8'

services:
  db:
    image: mcr.microsoft.com/azure-sql-edge
    
    volumes:
      - sqlsystem:/var/opt/mssql/
      - sqldata:/var/opt/sqlserver/data
      - sqllog:/var/opt/sqlserver/log
      - sqlbackup:/var/opt/sqlserver/backup

    ports:
      - "1433:1433"
    restart: always
    
    environment:
      ACCEPT_EULA: Y
      MSSQL_SA_PASSWORD: SqlPassword!

  webapp:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - db
    ports:
      - "8888:80"
    restart: always
    environment:
      - DBHOST=db
      - DBPORT=1433
      - DBUSER=sa
      - DBPASSWORD=SqlPassword!
      - DBNAME=YellowDB
      - ASPNETCORE_ENVIRONMENT=Development

volumes:
  sqlsystem:
  sqldata:
  sqllog:
  sqlbackup:

The db service above starts a SQL Server container from mcr.microsoft.com/azure-sql-edge.

The webapp service builds an image from Dockerfile and runs it. The web app can be accessed on the host computer with http://localhost:8888.

Running the solution on your computer

To run the application on your computer, type the following command from within the root folder of the web app (I.E. inside the AspMsSQL-docker-compose folder):

docker-compose up

Once the script in the terminal windows settles down, point your browser to http://localhost:8888. You will see the following landing page:



Register and login to ensure that the app functions properly with the database.

Cleanup

Let's shutdown and cleanup resources on our computer.

Inside of the terminal window that is running docker-compose, hit Ctrl C on your keyboard to stop the services. Thereafter, enter the following terminal command:

docker-compose down

To remove the webapp docker image, type:

docker rmi -f aspmssql-docker-compose_webapp

To remove all the volumes that were created on your computer, type:

docker volume rm aspmssql-docker-compose_sqlbackup
docker volume rm aspmssql-docker-compose_sqldata
docker volume rm aspmssql-docker-compose_sqllog
docker volume rm aspmssql-docker-compose_sqlsystem

Prepare solution for Azure deployment

We need to make one minor tweak so that our application can run on Azure. The tweak is to build the web app image and deploy it to docker hub.

I am hereby using snoopy a an example docker-hub username. Be sure to replace every instance of snoopy with your docker-hub user name.

The command to build a Docker image named asp-mssql version 1.0.0 is:

docker build --tag snoopy/asp-mssql:1.0.0 .

Note: Make sure you run the above command in the same folder as Dockerfile.

You ensure that you created an image named asp-mssql, type the following command:

docker images

You will see the image that you created among the list of docker images on your computer.

We can now push our image to docker hub. First we need to login into docker-hub with the following command:

docker login --username=snoopy

You will be prompted for your password. If all goes well. you will see the following output:

Login Succeeded


Logging in with your password grants your terminal complete access to your account.

For better security, log in with a limited-privilege personal access token. Learn more at https://docs.docker.com/go/access-tokens/

We now need to push our image to docker-hub with:

docker push snoopy/asp-mssql:1.0.0

The output will be similar to this:

The push refers to repository [docker.io/snoopy/asp-mssql]

5f70bf18a086: Mounted from snoopy/toon
3b9aa4fcf4e8: Pushed
a41af57309b5: Mounted from snoopy/toon
63fa163dde0c: Mounted from snoopy/toon
0f53df05d8e3: Mounted from snoopy/toon
bc1e58de0815: Mounted from snoopy/toon
2edcec3590a4: Mounted from snoopy/toon

If you login to https://hub.docker.com, you will find that the image is sitting in your repository.

Let's modify our docker-compose.yml file so that it used this image on docker-hub instead of building it locally. Open docker-compose.yml in an editor and replace lines 22-24 with:

image: snoopy/asp-mssql:1.0.0

Needless to say that instead of snoopy, you should use your docker-hub username.

The final docker-compose.yml will look like this:

version: '3.8'
services:
  db:
    image: mcr.microsoft.com/azure-sql-edge
    
    volumes:
      - sqlsystem:/var/opt/mssql/
      - sqldata:/var/opt/sqlserver/data
      - sqllog:/var/opt/sqlserver/log
      - sqlbackup:/var/opt/sqlserver/backup
    ports:
      - "1433:1433"
    restart: always
    
    environment:
      ACCEPT_EULA: Y
      MSSQL_SA_PASSWORD: SqlPassword!
  webapp:
    image: snoopy/asp-mssql:1.0.0
    depends_on:
      - db
    ports:
      - "8888:80"
    restart: always
    environment:
      - DBHOST=db
      - DBPORT=1433
      - DBUSER=sa
      - DBPASSWORD=SqlPassword!
      - DBNAME=YellowDB
      - ASPNETCORE_ENVIRONMENT=Development
volumes:
  sqlsystem:
  sqldata:
  sqllog:
  sqlbackup:

Deploying solution to Azure

Login into Azure by going to the portal at https://portal.azure.com. Click on "App Services" on the left-side hamburger menu:



Click on Create:

Add a new resource group:



Here are the remaining settings that I chose:


The most important setting you need to have for Publish is "Docker Container".

Click on the "Next : Docker >" button. On the next screen choose:

Options Docker Compose (Preview)
Image Source Docker Hub
Access Type Public
Configuration File Navigate to the docker-compose.yml file and load it. It will load in the text-area below.

This is what it should look like:


Click on "Review + create" button.


Review the configuration then click on Create.

You will see a blue "Go to resource" button once the deployment is completed.

Click on "Go to resource". This takes you to the control page for your web app. 


Click on the URL on the top right-side to see your solution running in the browser. Be patient because the solution takes some time to load. In my case, the app displayed like this:


At the time of writing this article, the Docker Compose capability in Azure App services is in preview mode. It seems to work quite well and, I am confident, it will be production ready soon.

No comments:

Post a Comment