Docker with Webstack 2016

Introduction

Over the last year I have spoke about Docker to implement microarchitectures and I lately posted about what I believe to be the best Webstack for 2016. In this post I would like to tie it all together via an application I wrote recently.

Docker and Development

Most people who are familiar with Docker know it as the de facto standard technology to use when building solutions using the so called microarchitecture style. It provides a really nice set of tools to build and manage components that are intended to be deployed in a cloud environment. But what people have not thought about is what containerized components can mean to the development process.

Testing for Upgrade

Imagine, for example, that you have a solution that uses WordPress and MySQL to host a web application. There are 3 main pieces in this solution: the MySQL database, the Web Server and the out of process PHP processor that provides the dynamic content.

I have several of these that I manage in the cloud. They started life within a hosting environment offered by a particular ISP (internet service provider). This provider provisioned specific versions of these pieces of tech. Most notably, MySQL was an older version 5.5. After restoring a backup locally I wondered, what would it take to upgrade MySQL to 5.6? Would this be a straightforward replacement?

Well after I created a Docker-ized version of this setup I ended up with a docker-compose.yml file that contained the following:

mysql:
    image: mysql:5.5
    ports:
      - "3306:3306"
    networks:
      ...
    env_file:
      - ./mysql.env

Well this couldn’t be easier! I simply replaced the reference to the mysql:5.5 image with the 5.6 version.

  mysql:
    image: mysql:5.6
    ports:
      - "3306:3306"
    networks:
      ...
    env_file:
      - ./mysql.env

I then just started up the solution and tested. I quickly found that there were incompatible changes that would require some work on my part. But I completed that test in minutes without installing anything. I just needed to pull the newer version image.

Anyone who has struggled with trying to have multiple versions of MySQL (or any RDBMS for that matter) on the same machine will appreciate my excitement over the value added here.

Building Without Install

I have recently been working with .NET Core (the Open Source, Next version of the .NET platform).

The tools in the Docker images provided by Microsoft are updated more frequently than the tools available via the installers available from their site. So to keep myself working with the latest tools I have a build script that uses the Docker image to build the solution.

CONNAME=ggwebapi-build
GGPROJ=GmailGroups
PUBDIR=dotnet-bin
DATADIR=${PUBDIR}/Data
BUILDCMD="cd /app && dotnet restore && dotnet publish ${GGPROJ} -o ${PUBDIR}"

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

By mounting my local project directory into the Docker image the output from the build process ends up in my local directory. The mounting is accomplished via the following command line option:

-v $PWD:/app

I then deploy using the ASP.NET Core image meant for that purpose.

FROM microsoft/aspnetcore

COPY dotnet-bin /app

WORKDIR /app

EXPOSE 5000/tcp

CMD ["dotnet", "GmailGroups.dll"]

I also use an nginx container to act as a reverse proxy to the Web API hosted in the ASP.NET Core container and also serve up the static content (images, Angular 2 UI, etc.). I have a simple custom Docker image specification for that component as well.

FROM nginx:latest

COPY . /usr/share/nginx/html

A docker-compose.yml ties it all together at runtime.

version: '2'

services:
  ggproxy:
    image: klmcwhirter/ggnginx
    ports:
      - "8080:80"
    volumes:
      - ./etc/ggnginx.conf:/etc/nginx/nginx.conf
    networks:
      - ggweb

  ggwebapi:
    image: klmcwhirter/ggwebapi
    ports:
      - "5000:5000"
    environment:
      - GGDOCKER=true
    networks:
        - ggweb

networks:
  ggweb:
    driver: bridge

With this arrangement I can build with one command and run with a second (docker-compose up).

And all of this runs on Mac OS X, Linux or Windows!

Summary

In the last post I described the development environment I use to work with these tools and technologies. So I won’t duplicate that here.

But I hope I have shown how Docker has afforded me to build a development environment wherein I can stay up to date with current tools easily and produce a product in a repeatable manner. If I run into a snag with a newer version of a Docker image I can easily downgrade to the earlier version to keep my development process flowing; focused on the problem at hand.

At a time of my choosing I can then deal with the upgrade problem.

There are several people exploring using Docker for front end apps like Microsoft Visual Studio Code. I have tried some of this. Very intriguing…

By the way, I am still using the mysql:5.5 image taking advantage of the security updates knowing that I have an upgrade task waiting for me. The mysql image is at version 5.7 now. But perhaps I will take a look at mariadb instead.

Enjoy!

Leave a Reply

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