CS296N Web Development 2: ASP.NET

Weekly Topics
1. Intro to course and Identity
6. Load Testing and Performance, Midterm Quiz
2. Authentication and Authorization 7. Creating a Web Service
3. Claims and Third Party Authentication
8. Consuming a Web Service
4. Web Security
9. Docker Containers
5. Publishing to a Production Server 10.  Microservices

Using Docker Containers


Announcements

  • Term Project

Solving the "but it worked on my machine" problem.

Set up Docker

You will need to install the Docker environment on your development machine and on the server. There are several versions of the development environment. You need to choose the one that matches your operating system:

Deploy a Web App in a Container

On your development machine:

We will deploy a framework-dependent ASP.NET Core web app to Linux in a Docker container.
  1. Create a file named Dockerfile in the folder with your web app project.
    Example:
    # download a base image from the repository
    FROM mcr.microsoft.com/dotnet/core/sdk:2.2
    # set the working directory for the Docker image
    WORKDIR /app

    # copy the project file into the image and restore dependencies
    COPY BookInfo.csproj ./
    RUN dotnet restore

    # copy the source code and build it
    COPY . ./
    RUN dotnet publish -c Release -o out

    # run the web app
    ENTRYPOINT ["dotnet", "out/BookInfo.dll"]

    • FROM—initializes a new build stage and sets the Base Image for the remaining instructions.
    • WORKDIR—sets the working directory for any remaining RUN, CMD, ENTRYPOINT, COPY, and ADD Dockerfile instructions.
    • COPY—copies new files or directories from the source path and adds them to the destination container filesystem.
    • RUN—executes any commands and commits the results. The resulting committed image is used for the next step.
    • ENTRYPOINT—specifies the command to run when the container starts, dotnet, and any arguments.

  2. Build the image in the current folder and give it a name, but no tag. (The tag is optional and could be given in the ‘name:tag’ format.)
    docker build -t dotnetapp-dev .       
  3. Run the containerized app
     docker run --rm -p 80:5000 dotnetapp-dev BookInfo from Docker
    Notes:
    • I set the port option to map port 5000 inside the container to 80 outside the container since my web app is configured for port 5000.
    • If you are specifying a port in appsettings.json, be sure you don't specify localhost. use + to represent any domain, like this:  "http://+:5000"
    • Since there is no database application in the image, the web app will throw exceptions when it tries to access its database. But if you have an app that doesn't need a database, you can open your web browser and see the app's web page.
  4. Upload the image to Docker Hub or any other container registry./li>

On the server:

  1. Blah blah

Notes

Using an in-memory database for testing

The Docker base image for the ASP.NET Core SDK, which is the one we are using, does not include a database engine, so our app will fail at startup when it tires to set up a database connection. To solve this, I added code to check an environment variable, ASPNETCORE_MEMDB, to see if it is set to "true" which causes EF to simulate a database in memory.br>In the Startup class:

public void ConfigureServices(IServiceCollection services)
{
    if (Environment.GetEnvironmentVariable("ASPNETCORE_MEMDB").ToLower() =="true") {
      services.AddDbContext<ApplicationDbContext>(
         options => options.UseInMemoryDatabase("TestDb"));
   }
   // Additional code omitted

 

To test this code in Windows, set the environment variable from the from a Windows console like this:

C:\Users\Student>set ASPNETCORE_MEMDB=true

To set the environment variable in the container, add this line to the Dockerfile anywhere before the ENTRYPOINT command:

ENV ASPNETCORE_MEMDB true

Docker Toolbox for Windows


Example

  • BookInfo—Docker branch
    Web app with:
    •  Dockerfile
    • Startup code for an optional in-memory DB selected by environment variable
    • Connection string for MariaDB
    • Other modifications to make the app containter friendly

References