Connecting to application containers from other application containers

Calling the new home page service from the main application container is fundamentally the same as connecting to the database: I will run the home page container with a known name, and I can access the service in other containers using its name and Docker's built-in service discovery.

A simple change to the HomeController class in the main NerdDinner application will relay the response from the new home page service instead of rendering the page from the main application:

static HomeController()
{
var homepageUrl = Environment.GetEnvironmentVariable("HOMEPAGE_URL", EnvironmentVariableTarget.Machine);
if (!string.IsNullOrEmpty(homepageUrl))
{
var request = WebRequest.Create(homepageUrl);
using (var response = request.GetResponse())
using (var responseStream = new StreamReader(response.GetResponseStream()))
{
_NewHomePageHtml = responseStream.ReadToEnd();
}
}
}

public ActionResult Index()
{
if (!string.IsNullOrEmpty(_NewHomePageHtml))
{
return Content(_NewHomePageHtml);
}
else
{
return Find();
}
}

In the new code I get the URL for the home page service from an environment variable. Just as with the database connection, I can set a default value for that in the Dockerfile. This would be bad practice in a distributed application where we can't guarantee where the components are running, but, in a Dockerized application I can do it safely because I will control the names of the containers, so I can be sure the service names are correct when I deploy them.

I've tagged this updated image as dockeronwindows/ch03-nerd-dinner-web:2e-v2. To start the whole solution now, I need to run three containers:

docker container run -d -p 1433:1433 `
--name nerd-dinner-db `
-v C:databases d:C:data `
dockeronwindows/ch03-nerd-dinner-db:2e

docker container run -d -P `
--name nerd-dinner-homepage `
dockeronwindows/ch03-nerd-dinner-homepage:2e

docker container run -d -P dockeronwindows/ch03-nerd-dinner-web:2e-v2

When the containers are running, I browse to the NerdDinner container's published port, and I see the home page from the new component:

The Find Dinner link takes me back to the original web app, and now I can iterate over the home page and release a new UI just by replacing that container – without releasing or testing the rest of the app.

What happened to the new UI? In this simple example, the integrated home page doesn't have the styling of the new ASP.NET Core version because the main application only reads the HTML for the page, not the CSS files or other assets. A better approach would be to run a reverse proxy in a container and use that as the entry point to other containers, so each container serves all its assets. I'll do that later in the book.

Now that I have my solution split across three containers, I've dramatically improved flexibility. At build time I can focus on features that give the highest value without expending effort to test components that haven't changed. At deployment time, I can release quickly and confidently, knowing that the new image we push to production will be exactly what was tested. Then at runtime, I can scale components independently according to their requirements.

I do have a new non-functional requirement, which is to ensure that all the containers have the expected names, are started in the correct order, and are in the same Docker network, so the solution as a whole works correctly. Docker has support for this, which is focused on organizing distributed systems with Docker Compose. I'll show you this in Chapter 6, Organizing Distributed Solutions with Docker Compose. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.187.165