ASP.NET 5: Seamless integration with Drone and Docker

ASP.NET 5: Seamless integration with Drone and Docker

ASP.NET 5 and Docker   Microsoft provides dockerfiles to create images and docker containers containing the ASP.NET

Our Software Developers have deep knowledge on ASP.NET 5 and Seamless integration with Drone and Docker. Learn more about it in this article.

ASP.NET 5 and Docker

Microsoft provides dockerfiles to create images and docker containers containing the ASP.NET 5 execution environment applications. The image contains the following applications:

  • dnvm: .NET runtime versions manager. Equivalent of ruby’s RVM, or virtualenv from python.
  • dnx: SDK and execution environment multi-platform of .NET applications.
  • dnu: Utility to install nuget development agencies. Equivalent to rubygems / bundler in ruby, or NPM in nodejs

Note: At this time (December 2015), dotnet is under development, a tool that combines dnx and dnu.

To serve as an example, a repository on github was created containing a simple test implemented with xunit. It can be cloned as follows:

git clone https://github.com/dgalizzi/asp.net5-drone-ci-example.git
cd asp.net5-drone-ci-example

Then we can test the application using the aforementioned image docker:

docker run -i -t -v `pwd`:/app microsoft/aspnet:1.0.0-rc1-update1-coreclr /bin/bash

The parameters indicate the following:

  • -i: interactive mode.
  • -t: Pseudo-tty.
  • -v: Create a volume, which means, mounting the pwd within / app in the container.
  • microsoft/ aspnet: Image in which we can initiate our container
  • :1.0.0-rc1-update1-coreclr: Version of the image to use
  • /bin/ bash: command to execute within our container

Then, within the container, execute the following dependencies to install and run the xunit tests implemented:

cd /app
dnu restore
dnx test

We should have a similar output to this one:

Feeds used:
https://api.nuget.org/v3-flatcontainer/

Installed:
    89 package(s) to /root/.dnx/packages
root@a074a96c419a:/app# dnx test
xUnit.net DNX Runner (64-bit DNXCore 5.0)
Discovering: app
Discovered:  app
Starting:    app
Finished:    app
=== TEST EXECUTION SUMMARY ===
app  Total: 1, Errors: 0, Failed: 0, Skipped: 0, Time: 0.375s

Drone

Drone is a continuous integration platform that works on docker. Each build is performed on a new container, so if we have a docker image that provides us the tools to build and test our application, we can use drone very easily.

Webhook y github

Drone is responsible for conducting a build for each push that we’ll make to our github repository (it also supports bitbucket and gitlab). To set up drone with github, we go to “our applications” and record a new application. Github then we will give us a Client ID and Client Secret that we will use to configure drone.

Once we have the ID and Client Secret, we create a file with the following format:

REMOTE_DRIVER=github
REMOTE_CONFIG=https://github.com?client_id=....&client_secret=....

Finally, we can start drone with the following command:

docker run 
    --volume /var/lib/drone:/var/lib/drone 
    --volume /var/run/docker.sock:/var/run/docker.sock 
    --env-file /etc/drone/dronerc 
    --restart=always 
    --publish=80:8000 
    --detach=true 
    --name=drone 
    drone/drone:0.4

In -env-file we indicate the file created above, and in -publish we indicate the port that will be running on the host (80 in this case).

drone.yml

.drone.yml is the configuration file required to use drone on our application and should be at the root of the repository. Below, we can see the minimum .drone.yml to run the tests in our application:

build:
    image: microsoft/aspnet:1.0.0-rc1-update1-coreclr
    commands:
        - dnu restore
        - dnx test

Note: dnx test runs the test command as defined in project.json as dnx.runner.xunit.

In the configuration file, we define the services that we will use and configure these services. Here, build represents the service that will be configured and will handle the building and testing of the application. image indicates the docker image that we will use and commands is a list of commands to run within the container docker. All commands should return a successful exit code for the continued integration of success.

NuGet cache

Each build that drone makes will download and install all the dependencies again. To avoid this, we must cache the dependencies and retrieve them on each build. If the dependencies change, dnu restore will be responsible for resolving it.

To define a cache in drone, we use the cache service where we define files or folders to be cached. One drawback is that drone can only cache files within /drone (the working directory that defines drone inside the container), while the image of aspnet that we use installs the packages in /root/.dnx. There are ways around this, the one that we will show here is defining the DNX_PACKAGES environment variable that defines the directory where the nuget packages will be installed.

Then, we only have to define the environment variable in any folder inside /drone and cache it:

build:
    image: microsoft/aspnet:1.0.0-rc1-update1-coreclr
    environment:
        - DNX_PACKAGES=/drone/nuget_cache
    commands:
        - dnu restore
        - dnx test

cache:
    mount:
        - /drone/nuget_cache
        - project.lock.json

The first thing we must do is to add in the environment configuration of the build service the DNX_PACKAGES environment variable, indicating a directory in which the packages nuget will be stored inside /drone.

Finally, we configure the cache service files or folders that you wish to cache the next build.

To finish, here is the drone output when making the corresponding build on the example repository:

[info] Pulling image plugins/drone-cache:latest
Restoring cache /drone/nuget_cache
Restoring cache project.lock.json
[info] Pulling image plugins/drone-git:latest
$ git init
Initialized empty Git repository in /drone/src/github.com/dgalizzi/asp.net5-drone-ci-example/.git/
$ git remote add origin https://github.com/dgalizzi/asp.net5-drone-ci-example.git
$ git fetch --no-tags --depth=50 origin +refs/heads/master:
From https://github.com/dgalizzi/asp.net5-drone-ci-example
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master
$ git reset --hard -q 9771386ff4aaa292f1b3653e3e92b129b4417ecb
$ dnu restore
Microsoft .NET Development Utility CoreClr-x64-1.0.0-rc1-16231

  GET https://api.nuget.org/v3/index.json
  OK https://api.nuget.org/v3/index.json 1550ms
Restoring packages for /drone/src/github.com/dgalizzi/asp.net5-drone-ci-example/project.json
  GET https://api.nuget.org/v3-flatcontainer/xunit/index.json
  GET https://api.nuget.org/v3-flatcontainer/xunit.runner.dnx/index.json
  OK https://api.nuget.org/v3-flatcontainer/xunit.runner.dnx/index.json 935ms
  OK https://api.nuget.org/v3-flatcontainer/xunit/index.json 1005ms
  GET https://api.nuget.org/v3-flatcontainer/system.net.http/index.json
  OK https://api.nuget.org/v3-flatcontainer/system.net.http/index.json 420ms
  GET https://api.nuget.org/v3-flatcontainer/system.net.http/4.0.0/system.net.http.4.0.0.nupkg
  OK https://api.nuget.org/v3-flatcontainer/system.net.http/4.0.0/system.net.http.4.0.0.nupkg 2281ms
  GET https://api.nuget.org/v3-flatcontainer/microsoft.win32.primitives/index.json
  GET https://api.nuget.org/v3-flatcontainer/system.io.compression/index.json
  OK https://api.nuget.org/v3-flatcontainer/microsoft.win32.primitives/index.json 424ms
  GET https://api.nuget.org/v3-flatcontainer/microsoft.win32.primitives/4.0.0/microsoft.win32.primitives.4.0.0.nupkg
  OK https://api.nuget.org/v3-flatcontainer/system.io.compression/index.json 478ms
  GET https://api.nuget.org/v3-flatcontainer/system.io.compression/4.0.0/system.io.compression.4.0.0.nupkg
  OK https://api.nuget.org/v3-flatcontainer/microsoft.win32.primitives/4.0.0/microsoft.win32.primitives.4.0.0.nupkg 1200ms
  OK https://api.nuget.org/v3-flatcontainer/system.io.compression/4.0.0/system.io.compression.4.0.0.nupkg 1318ms
Installing System.Net.Http.4.0.0
Installing Microsoft.Win32.Primitives.4.0.0
Installing System.IO.Compression.4.0.0
Writing lock file /drone/src/github.com/dgalizzi/asp.net5-drone-ci-example/project.lock.json
Restore complete, 6756ms elapsed

Feeds used:
    https://api.nuget.org/v3-flatcontainer/

Installed:
    3 package(s) to /drone/nuget_cache
$ dnx test
xUnit.net DNX Runner (64-bit DNXCore 5.0)
  Discovering: asp.net5-drone-ci-example
  Discovered:  asp.net5-drone-ci-example
  Starting:    asp.net5-drone-ci-example
  Finished:    asp.net5-drone-ci-example
=== TEST EXECUTION SUMMARY ===
   asp.net5-drone-ci-example  Total: 1, Errors: 0, Failed: 0, Skipped: 0, Time: 0.379s
[info] Pulling image plugins/drone-cache:latest
Building cache /drone/nuget_cache
Building cache project.lock.json