values screenshot

Session with Docker and Webstack 2016

Phew – just got this post published in 2016.

Last time I introduced you to the concepts I use to develop Docker hosted applications using what I am calling Webstack 2016. The post before that introduced the stack.

This time, I will walk through the development workflow I use to start a new app project, create new versions of the Docker containers and then test those.

Prerequisites

I documented the prerequisite tools in the previous post and so I will not duplicate those links here.

But you will need the dotnet cli, the Yeoman aspnet generator (install it globally), the angular-cli npm package (install it globally as well) and Microsoft’s Visual Studio Code (or the editor of your choosing).

Also, of course, the Docker tools are needed. They are available at https://www.docker.com/.

The companion code is available at https://github.com/klmcwhirter/hellowebstack2016 if you would like to follow along.

Getting Started

If you are starting a new project follow these steps.

  1. Run Yeoman generator: yo aspnet
  2. Select Web API Application
  3. Give your app a name: hello
  4. A directory named hello will be created in the current directory and populated with a starter Web API application. Instructions will be output on the screen to restore the dependencies, build and run the application. But don’t do that yet.
  5. Change to the directory: cd hello
  6. Run the Angular CLI tool to generate the starter Angular application: ng init
  7. You will be asked whether to overwrite a couple of files, answer ‘n’

At this point I like to clean things up some. I like to arrange for the .NET files to be in a project directory. I create a directory named after the project (hello in our case) and move all of the related files into that dir: the *.cs and .gitignore files, the Controllers and Properties dirs, project.json and web.config files. Then create a global.json in the workspace root dir that contains the single project name. As I add projects I need to remember to add them to this file.

{
 "projects": [
   "hello"
 ]
}

And then, of course, run git init to initialize a git repository.

I typically use gulp to construct a combined build system for the .NET and Angular pieces. But that is beyond the scope of what I am trying to accomplish in this post.

Once my cleanup is done I can build and run the .NET app with:

dotnet build hello

dotnet run -p hello

Open a browser and go to http://localhost:5000/api/values. You should see the following output.

["value1","value2"]

To test the Angular app run it using the following command:

npm start

Then open a browser to http://localhost:4200 to see the output:

app works!

Using Docker container to build

I create a docker directory in the workspace root to hold all of my docker stuff.

It usually looks like this.

docker/
    etc/
        hello.conf          # nginx config for the proxy
    build.sh                # build the docker images
    docker-compose.yml      # config file for docker-compose to run the app
    hellonginx.dockerfile   # Dockerfile describing the nginx proxy image
    hellowebapi.build.sh    # script to build the Web API using Docker containers
    hellowebapi.dockerfile  # renamed from Dockerfile - generated for .NET app

For now we will focus on just the hellowebapi.build.sh script. It looks like this:

#!/bin/bash
#*---------------------------------------------------------------------------*
#* Name: hellowebapi.build.sh
#*
#* Description: build the webapi bits using the dotnet sdk supplied as a 
#* Docker image.
#*
#* Note that it uses the latest version which at the time is 1.1.0
#*
#*---------------------------------------------------------------------------*
#* Constants
CONNAME=hellowebapi-build
PROJ=hello
PUBDIR=dotnet-bin
DATADIR=${PUBDIR}/Data

BUILDCMD="cd /app && dotnet restore && dotnet publish ${PROJ} -o ${PUBDIR}"

#*---------------------------------------------------------------------------*
#* M A I N  P R O G R A M
#*---------------------------------------------------------------------------*

rm -fr ${PUBDIR}
mkdir -p ${PUBDIR}

docker run --name ${CONNAME} -v $PWD:/app microsoft/dotnet /bin/bash -c "${BUILDCMD}" 

docker rm -v ${CONNAME} 

mkdir -p ${DATADIR}

#*---------------------------------------------------------------------------*

This script expects to be executed in the workspace root directory. The build.sh script will arrange for that.

Take a look at the other config files and scripts in the docker dir. The following are noteworthy.

  • etc/hello.conf is the nginx config file that is installed into the proxy Docker image. it contains a link at line 70 to the Web API Docker container. The host name used there matches the corresponding service name in the docker-compose.yml file.
  • build.sh drives the overall build process. When it is done you are ready to run the containers.
  • hellowebapi.dockerfile installs just the published binaries and uses the microsoft/aspnetcore Docker image. This image is lightweight containing just the runtime for an ASP.NET Core application.

Writing the UI

At this point we are ready to hook the web app up to the service. The default service doesn’t do much – it just returns an array of 2 strings. But, it should be enough for our purposes.

Note that I assume familiarity with ASP.NET Web API and Angular 2 here.

In order to get the UI going, modify the following files.

  • Program.cs – see the UseUrls addition and the handler for the HELLODOCKER environment variable – this fixes up some paths when executing in a container
  • app.component.html – add an unordered list to display the strings returned from the service call
  • app.component.ts – add code to retrieve the strings from the ValuesService and populate the this.values array
  • values.service.ts – service class to perform the Web API call; use the ng generate service command to add a new service

After building and running with docker-compose you should now see the following output.

values screenshot

Summary

Through this post we have created a new ASP.NET Core Web API solution, add an Angular application, tie them together, and create Docker images that host the results.

Leave a Reply

Your email address will not be published. Required fields are marked *