Part 0.1 - 1000 foot overview

Part 1 - Things to consider when containerizing an app

Part 2 - Running MySQL in a container

Previously…

We discussed the plan to migrate a site from a legacy 2-tier design into something more modern. One question is, “Why not just move straight to rewriting?”

A few reasons:

  • Lifting-and-shifting the current code into a container is much easier and quicker
  • I already have Kubernetes running in a cloud-provider (where this blog is served from) -> so we can easily just deploy the site to that cluster
  • It’s a good thought excercise to document how to containzerize something
  • The site isn’t running anywhere publicly accessible and we need to do that first before anything else can happen, as I want to be serving ‘production’ traffic
  • I don’t want to pay for extra services

What is this review site?

Home/search page looks like this:

Has standard webpage functionality:

  • Ability to search for a wifi hotspot within a given area
  • Ability to use browser geolocation to detect ‘current’ location
  • Ability to register an account
  • Ability to leave a ‘review’ for a given hotspot, and give it a rating
  • Ability to perform basic administative duties on your own reviews
  • Ability to filter search based on multiple criteria -> name, suburb, radius-from-location, minimum rating etc.
  • Bunch of backend type validation and other things to facilitate the above

However it’s all static, lots of hardcode and quite poor PHP and javascript. We will change all of this.

What do we have to firstly do to get into a container

Regardless if you use kubernetes or not, the usual/ideal way to get variable settings into a container is via environment variables. Docker is passed through as key=value pairs, and kubernetes usually uses what’s called a configmap.

So we have to:

  • Identify all things which are hardcoded
  • Identify all ‘settings’ used
  • Migrate those hardcoded settings to environment variables
  • Decide where to host our persistent database?
  • Move onto next step, putting services into a container

In the code, we have things hardcoded like below:

<?php
    $dbConn = new PDO('mysql:host=localhost;dbname=databaseNameHere', 'admin', 'hunter2');
    $dbConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
?>

Which we will move to this:

setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); ?>

The end result is that we will still be running PHP and MySQL locally, but instead of hardcoding everything it will be somewhat more flexible. We will create a powershell-core script to manage these variables, using a key-reference files for required settings and ensuring they’re set.

Given I’m using PHP strictly in a scripting-manner (no classes) or anything at all in this site design, it’s pretty straight-forward. If you’re using something like .net core, you could add a config option to your configurationbuilder in startup.cs:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
    Configuration = builder.Build();
}

The order is important, putting it last ensures they take precedence. Point being is to ensure you’re using environmental variables for settings in your code.

Next up, we will discuss data persistence with containers, and why/how you’d run a database out of a container.