In the “Redis Clients :: ASP.NET Core” post; we made a minimalist ASP.NET Core MVC application that uses Redis; we made v2 Docker Compose file that we used to deploy our application on the Docker as two Containers; one running Redis Server and the other running the ASP.NET Core application. Even though we used Redis and Distributed Caching; but our application still was deployed on the single host. Given its based on a micro-service Docker friendly architecture, we can write a v3 Compose file and using Stack Deploy command we can deploy it on a multi-host Docker Swarm setup. Here’s one such v3 compose file
- If you are following the Dotnet Core Series; you might have noticed that build and restart options are gone from the v2 compose file that we made in the previous post. This is because if deploying to Docker Swarm; those two are not supported
Before doing stack deploy; given we need a “custom” image; we need to ensure that this image exists with the Docker Daemon and for this we obviously need to first publish our Dotnet Core app; and then we can build the Docker image from the Dockerfile against the Docker Daemon.
- I have used docker-compose to build the image above; as have the Docker Client and Docker Machine in Linux Subsystem configured against the Swarm and given the Linux Subsystem is still “beta” due to https://github.com/Microsoft/BashOnWindows/issues/1123 we cannot build the image against a remote Docker Daemon (Swarm Node in this case); however docker-compose works fine; and we can use it to build the image
Once our custom image is made; we can do Stack Deploy using the v3 Compose file we made earlier
The mvcapp container needs to be globally deployed but it gets deployed only on the one node against which we made it:
We need to make that mvcapp image available to the remaining participating nodes as well; we either build the image against each Docker Daemon of the Swarm nodes; or we can setup a “Docker Registry” where we can make our image available and then update the v3 compose file and redeploy the stack and all the swarm nodes will get the image from the “Registry”. There exists an open source Docker Registry as an official Docker Container image; and running it just a docker run away
There is an excellent TL;DR; at https://docs.docker.com/registry; you basically tag the existing custom image prefixing the registry url; in our case we will tag mvcapp as 192.168.10.14:5000/mvcapp; and then push it; and Docker Daemon will upload the image to the Registry; similar to Docker Hub! But it would not work
The problem is; that our Registry is not “secured” and Docker Daemon by default only likes secured remote registries; but we can add such unsecured remote registries as “trusted” in the docker daemon configuration. It depends what setup you are using; for instance I am using RancherOS to run the Docker Engines; and to add the remote registries; I have to do this:
Once the registry is added; we can push our registry tagged image from where other nodes can download and consume it when required
All we need to do now is update our v3 Compose File for the Docker Stack Deploy to use the our-registry/mvcapp image instead of just mvcapp so that all nodes can get it from “our-registry” address
- Notice mvcapp image is changed accordingly
- Notice the newly added Healthcheck section; it done so that if Redis Container is not available; the MVC app will break; this can happen if the node running the Redis container is not available; the Swarm will reschedule the Redis Container soemwhere else; and due to this healthceck; the MVC containers will also get rescheduled picking new Redis IP. This was done because the MVC app is talking to Redis using the IP and not the host name; details are in Redis Clients -- ASP.NET Core post.
Lets redeploy the stack, and we will have our mvcapp containers running on all the participating nodes; each node downloading the required image from the Registry automatically
Now to try a failure recovery; lets turn off the swarm3 node; and Docker Swarm should be able to recover automatically
Check https://docs.docker.com/registry/recipes for other use cases of Docker Registry
If we are using Docker for Windows; we can add our insecure Registry into its Daemon; and once added; can make a docker container tagging directly for the registry and push it from the development machine/environment from where it can be used/picked by Swarm Nodes accordingly; giving us seamless deployment to cluster experience!