Instructor Demo: Docker Compose
In this demo, we'll illustrate:
- Starting an app defined in a docker compose file
- Inter-service communication using DNS resolution of service names
Exploring the Compose File
Please download the DockerCoins app from Github and change directory to ~/orchestration-workshop-net/dockercoins:
PS: node-0 Administrator> git clone -b ee2.1 ` https://github.com/docker-training/orchestration-workshop-net.git PS: node-0 Administrator> cd ~/orchestration-workshop-netLet's take a quick look at our Compose file for Dockercoins:
version: "3.1" services: rng: image: training/dc_rng:1.0 networks: - nat ports: - "8001:80" hasher: image: training/dc_hasher:1.0 networks: - nat ports: - "8002:80" webui: image: training/dc_webui:1.0 networks: - nat ports: - "8000:80" redis: image: redis:3.2-nanoserver networks: - nat worker: image: training/dc_worker:1.0 networks: - nat networks: nat: external: trueThis Compose file contains 5 services, and a pointer to the default
natnetwork. The imagestraining/dc_rng:1.0et cetera are pre-built images containing the application logic you can explore in the subfolders of~/orchestration-workshop-net.Start the app in the background:
PS: node-0 orchestration-workshop-net> docker-compose up -dMake sure the services are up and running, and all the containers are attached to the local
natnetwork:PS: node-0 orchestration-workshop-net> docker-compose ps PS: node-0 orchestration-workshop-net> docker network inspect natIf everyting is up, visit your app at
<node-0 public IP>:8000to see Dockercoins in action.
Communicating Between Containers
In this section, we'll demonstrate that containers created as part of a service in a Compose file are able to communicate with containers belonging to other services using just their service names. Let's start by listing our DockerCoins containers:
PS: node-0 orchestration-workshop-net> docker container ls | findstr 'dc'Now, connect into one container; let's pick
webui:PS: node-0 orchestration-workshop-net> docker container exec ` -it <Container ID> powershellFrom within the container, ping
rngby name:PS C:\> ping rngLogs should be outputted resembling this:
Pinging rng [172.20.137.174] with 32 bytes of data: Reply from 172.20.137.174: bytes=32 time<1ms TTL=128 Reply from 172.20.137.174: bytes=32 time<1ms TTL=128 Reply from 172.20.137.174: bytes=32 time<1ms TTL=128 Reply from 172.20.137.174: bytes=32 time<1ms TTL=128 Ping statistics for 172.20.137.174: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 0ms, Average = 0msDNS lookup for the services in DockerCoins works because they are all attached to the local
natnetwork.After exiting this container, let's navigate to the
workerfolder and take a look at the top ofProgram.cs:PS: node-0 orchestration-workshop-net> cd worker PS: node-0 worker> cat Program.cs using System; using System.Net.Http; using System.Threading; using ServiceStack.Redis; public class Program { private static HttpClient Client = new HttpClient(); private const string rng_uri = "http://rng"; private const string hasher_uri = "http://hasher"; ...Our worker is configured to contact the random number generator and hasher directly by their service names,
rngandhasher. No service discovery or IP lookups required - Docker ensures that service names are DNS-resolvable, abstracting away our service-to-service communication.Shut down Dockercoins and clean up its resources:
PS: node-0 orchestration-workshop-net> docker-compose down
Conclusion
In this exercise, we stood up an application using Docker Compose. The most important new idea here is the notion of Docker Services, which are collections of identically configured containers. Docker Service names are resolvable by DNS, so that we can write application logic designed to communicate service to service; all service discovery and load balancing between your application's services is abstracted away and handled by Docker.