If you plan on attending this workshop, you need:
- A laptop + power cord
- Install docker 1.11:
- Install Toolbox for windows or for Mac
- If you are on linux, and only on linux, grab docker-compose v1.7 and put it in your path somewhere.
- If you haven't done it already, register for the Docker for Desktop Beta at https://beta.docker.com, and give us your hub account name during the sessioni. We can probably do something for you.
- Test that your docker installation works fine:
docker version
should show version1.11
on both Client and Server side.- Run
docker run hello-world
and check you see the welcome message.
- Get the source of the lab by
git clone git@github.com:CodeStory/lab-docker.git
- During the workshop, we'll distribute USB keys with the docker images we need for the lab:
cd lab-docker
docker load -i images.tar
will load all the images you need.
- As an alternate solution, you can load the images directly from the hub:
docker pull dockerdemos/lab-web
docker pull dockerdemos/lab-words-dispatcher
docker pull dockerdemos/lab-words-java
docker pull mongo-express:0.30.43
docker pull mongo:3.2.4
Our first version of the application is composed of four micro-services:
- A
web
service that usesnginx
running on port80
to serve an HTML5/Js application written in angularJs. - A
words-java
service that runs ajava
web server on a random port. This server connects to the database and exposes a Rest Api to theweb
. - A
db
service that runs amongoDb
database on a random port. - A
db-ui
service that runs a web UI on port8081
to edit the content of the database
- Point Docker CLI to the Docker daemon:
-
If you have
Docker for Mac
orDocker for Windows
, there's nothing to be done. Rundocker info
to check that everything is up and running. -
If you have
Docker Toolbox
, either open theQuick Start
terminal or rundocker-machine env
to show the command you have to run to point to the Docker daemon running on the VirtualBox VM. On OSX, it's typically:eval $(docker-machine env default)
- Configure Docker Compose to use the first configuration file:
cd lab-docker
cp docker-compose-v1.yml docker-compose.yml
- Build and start the application:
docker-compose up -d
- Take a look at the logs, to see if there's any error:
docker-compose logs
- List the running containers:
docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------
labdocker_db-ui_1 tini -- node app Up 0.0.0.0:8081->8081/tcp
labdocker_db_1 /entrypoint.sh mongod Up 27017/tcp
labdocker_web_1 nginx -g daemon off; Up 443/tcp, 0.0.0.0:80->80/tcp
labdocker_words-java_1 java -DPROD_MODE=true -Xmx ... Up 8080/tcp
Find the IP and port to the web UI and open a browser to that url:
docker-compose port web 80
Be careful, with docker-machine
, only the port is a valid output.
The IP address should be replaced with the result of docker-machine ip default
instead as the ip address.
Each time the page is refreshed, you will see a sentence composed of 5 random words: a noun, an adjective, a verb, a noun and an adjective. That's a "Cadavre Exquis"! You did it!
The angularJs application served by the nginx
based web
service sends 5
http GET
queries to the nginx
that proxies the words-java
REST service.
On each query, the words-java
loads all the words from the database and chooses
a random one.
- The
db-ui
web UI can be used to configure the list of words in the database.
- Use this command to find the url for the UI:
docker-compose port db-ui 8081
- Add some nouns, adjectives and verbs, use non-plural and male noun and adjectives, or the grammar will not be correct.
- Careful, all words added to the database at this stage will be lost for the next stages.
- You can fiddle with the code from the ui.
- try to change something in
web/static/index.html
- then
docker-compose up --build -d
, see how this only stop & restart the correct container. - Careful, If you are on a slow network, this can be troublesome, as you're going to download new files.
- Things to check in this step
- Notice the db connexion string in
words-java/src/main/java/Main.java
- Notice the nginx configuration in
web/default.conf
onlocation /words/
and check the corresponding code inweb/static/app.js
- Notice in the
docker-compose-v1.yml
file some services havebuild
andimage
instructions while others have onlyimage
- Notice the
Ports
vsExposes
instructions, try to find a way to call the/verb
instruction on thewords-java
, without changing theyml
file.
We are going to change the micro-service based architecture of our application without changing its code. That's neat!
Our idea is to introduce an additional micro-service between the web
and the
java
rest api. This new component is called the words-dispatcher
. It's a Go
based web server that will later help dispatch word queries to multiple words-java
backends.
Thanks to a new compose file, we are able to insert
the words-dispatcher
service between the web
service and the words-java
service without touching our application code.
The web
expectation is that a words
host exists on the network and that
it will be able to connect to it via port 8080
.
Thanks to the links
configuration, we are able to connect the web
service
to the words-java
service using the words
DNS name.
Also, thanks to the expose
configuration, the words-java
service will be
reachable on port 8080
by the other services. Because the 8080
port is not
exposed to the host but only the the other containers, we could have multiple
services running on the port coexist on the same host.
This last point is very important because now we want to insert a new service
between the web
and the words-java
. This service runs on the same 8080
port.
All we have to do is:
- Change the
links
configuration of theweb
service so that when it connects towords
host, it reacheswords-dispatcher
instead ofwords-java
. - Set the
links
configuration of thewords-dispatcher
service to connect it towords-java
. - Both
words-dispatcher
andwords-java
will expose their8080
port to the other containers but it's not an issue because as it is not published to the host, they can co-exist on the same host.
- Stop the application currently running:
cd lab-docker
docker-compose stop
docker-compose rm -f
- Configure Docker Compose to use the second configuration file:
cp docker-compose-v2.yml docker-compose.yml
- Build and start the application:
docker-compose up -d
docker-compose logs
As a user, you should see no difference compared to the original application. That's the whole point!
- Check the logs and see the dispatcher in action
- Run
docker-compose logs -f
and refresh your page at will, check the dispatcher work described in the logs.
- Check the dispatcher code
- Especially the
forward
function in thewords-dispatcher/dispatcher.go
source. - carefull this code is not really efficient but it serves well the purpose of this workshop
We are going to the Cloud! Your containers will be send to a shared Swarm composed of multiple nodes. We have already setup the Swarm for you before the talk. You just need to point your Docker CLI to the Swarm rather than to your local Docker daemon. This is done through environment variables. And because our Swarm has TLS enabled, you need a copy of our certificates. We'll pass along a couple of USB keys with the certificates on them. Then follow the instructions below:
- Stop the application currently running:
cd lab-docker
docker-compose stop
docker-compose rm -f
-
Copy the provided
certificates
from the USB key. -
Point your docker client to the proper machine:
If you are on the Google cloud swarm cluster
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://104.155.27.61:3376"
export DOCKER_CERT_PATH="$(pwd)/certificates"
if you are running in your local swarm cluster in virtualbox
eval $(docker-machine env master)
-
Confirm that
docker info
shows multiple nodes. -
Configure Docker Compose to use the third configuration file:
mv lab-docker team-XX
cd team-XX
cp docker-compose-v3.yml docker-compose.yml
Renaming the folder you are working in is VERY important. It makes it possible to scope the whole project to your team name.
- Build and start the application:
docker-compose up -d
docker-compose logs
The same application that ran on you machine now runs in the Cloud on a shared Swarm.
If you compare docker-compose-v2.yml and docker-compose-v3.yml
you'll see that all the links have been removed and all the services now use a
private network instead. This network is created by Docker Compose. Its name
is private
, prefixed by the name of your project (ie your team name). It's a network
available to your containers only.
Thanks to this private network, multiple similar applications can coexist on the same Swarm.
Also this overlay network and docker's DNS make it possible for the containers to find each other by their service names.
- You can check that consul is correctly running, by checking the numbers of nodes it runs
- Find the Consul server ip by running :
docker-machine ip kv
- Then points your browser to
http://{consul-server-ip}/:8500/ui/#/dc1/kv/docker/nodes/
- You can try to scale the numbers of
words-java
nodes and see how the dispatcher react.
- Add 4 more
words-java
node by issuingdocker-compose scale words-java=4
. - You have now 5 words-java containers. Check their numbers with
docker-compose ps
- Point your browser to the web container on the swarm cluster, don't forget the container can run anywhere on the swarm cluster. You'll find the correct ip/port by issuing
docker-compose port web 80
. You'll likely see the differents words coming from differentsword-java
ip. - Start
docker-compose logs -f
and refresh your browser, pay attention to the logs from the dispatcher. - Connect to one of the containers
docker exec -ti labdocker_words_1 sh
and do anslookup words-java
(changelabdocker
with your team prefix) see that there is 5 values for the entry.
The goal of this last step is to make all the applications communicate transparently.
Every words-dispatcher
will connect to the words-java
deployed by all the teams.
- Stop the application currently running:
cd team-XX
docker-compose stop
docker-compose rm -f
- Configure Docker Compose to use the fourth configuration file:
cd team-XX
cp docker-compose-v4.yml docker-compose.yml
- Start the application:
docker-compose up -d
docker-compose logs
We changed the services so that some of them are now part of multiple networks.
A private
network, project scoped, automatically created and a shared
pre-existing lab-net
network.
All the services with the same name or alias on a shared network will be reachable on the same DNS name. A client can get all the IPs for the DNS name and start load balancing between the nodes. Nothing complicated to setup!
That's exactly what the words-dispatcher
does. To bypass the DNS cache, it
searches for all the IPs for the works-java
services and uses a random one
each time. This effectively load balances queries among all the teams.
Try adding words of your own and play with those "Cadavres Exquis", Swarm style!
- Try adding some specific word again. ( remember the data you typed in on step 1 is not on the cluster )
- Use this command to find the url for the UI:
docker-compose port db-ui 8081
- Add some words.
-
Lookup one of the IP address below one of the words, and check with
docker ps
to which group it belongs. -
Notice how the
lab-net
network is not created during the initialdocker-compose up
if you check the various init script, they are created there.
Last Devoxx & Mix-IT in 2015 was with docker 1.6. Since then, a lot of features were added. Here's the short list of those we demonstrated with this lab.
- Multi-host Networking - Docker 1.9
- New compose file - Docker 1.10
- Use links in networks - Docker 1.10
- Network-wide container aliases - Docker 1.10
- DNS discovery - Docker 1.11
- Build in docker-compose up - Docker-Compose 1.7
Cadavres Exquis is a French word game, you'll find more on wikipedia page (in French)
The swarm cluster has been created on Google Cloud with the init_swarm_google.sh script. Take a look to what we do there but you'll need an account and this may cost you money.
You can also try it on your own laptop by running the init_swarm_virtualbox.sh, you'll need virtualbox and docker-machine