Git Product home page Git Product logo

docker-compose-demo's Introduction

docker-compose scaling web service demo

A short demo on how to use docker-compose to create a Web Service connected to a load balancer and a Redis Database. Be sure to check out my blog post on the full overview - brianchristner.io

Install

The instructions assume that you have already installed Docker and Docker Compose.

In order to get started be sure to clone this project onto your Docker Host. Create a directory on your host. Please note that the demo webservices will inherit the name from the directory you create. If you create a folder named test. Then the services will all be named test-web, test-redis, test-lb. Also, when you scale your services it will then tack on a number to the end of the service you scale.

git clone https://github.com/vegasbrianc/docker-compose-demo.git .

How to get up and running

Once you've cloned the project to your host we can now start our demo project. Easy! Navigate to the directory in which you cloned the project. Run the following commands from this directory

docker-compose up -d

The docker-compose command will pull the images from Docker Hub and then link them together based on the information inside the docker-compose.yml file. This will create ports, links between containers, and configure applications as requrired. After the command completes we can now view the status of our stack

docker-compose ps

Verify our service is running by either curlng the IP from the command line or view the IP from a web browser. You will notice that the each time you run the command the number of times seen is stored in the Redis Database which increments. The hostname is also reported.

###Curling from the command line

```
curl -H Host:whoami.docker.localhost http://127.0.0.1

Hostname: 2e28ecacc04b
IP: 127.0.0.1
IP: 172.26.0.2
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.54.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.26.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: a00d29b3a536
X-Real-Ip: 172.26.0.1
``` 

It is also possible to open a browser tab with the URL http://whoami.docker.localhost/

Scaling

Now comes the fun part of compose which is scaling. Let's scale our web service from 1 instance to 5 instances. This will now scale our web service container. We now should run an update on our stack so the Loadbalancer is informed about the new web service containers.

docker-compose scale whoami=5

Now run our curl command again on our web services and we will now see the hostname change. To get a deeper understanding tail the logs of the stack to watch what happens each time you access your web services.

```
docker-compose logs whoami
whoami_5         | Starting up on port 80
whoami_4         | Starting up on port 80
whoami_3         | Starting up on port 80
whoami_2         | Starting up on port 80
whoami_1         | Starting up on port 80
```

Here's the output from my docker-compose logs after I curled the whoami application so it is clear that the round-robin is sent to all 5 web service containers.

```
reverse-proxy_1  | 172.26.0.1 - - [01/May/2019:19:16:34 +0000] "GET /favicon.ico HTTP/1.1" 200 647 "http://whoami.docker.localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36" 10 "Host-whoami-docker-localhost-1" "http://172.26.0.2:80" 1ms
```

docker-compose-demo's People

Contributors

lonix avatar mlbx avatar vegasbrianc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker-compose-demo's Issues

error in docker-compose.yml

Hi,
Thanks for this wonderful example :-)
Unfortunately, I think there's a mistake in the docker-compose.yml file that prevents your demo from running on a remote docker machine.
In the web section, the following lines overrides the app.py you add in DockerFile and make the image fail if app.py is not deployed on the host machine.

  volumes:
   - .:/code

Best regards,
Jean-Marc Astesana

Always responds from web_1 (doesn't seem to be using other scaled containers)

Hi, trying to get my head around this. Followed your instructions:

  • Cloned repos
  • docker-compose up -d
  • docker-compose ps (shows dockercomposedemo_redis_1 / dockercomposedemo_web_1 / dockercomposedemo_lb_1)
  • curl 0.0.0.0 (shows: Hello World!, I have been seen 1 times. My Host name is 2298df0387b0)
  • docker-compose scale web=5 (shows: Creating and starting 2... done, Creating and starting 3... done
    Creating and starting 4... done, Creating and starting 5... done)
  • docker-compose up -d (shows: dockercomposedemo_redis_1 is up-to-date, dockercomposedemo_web_2 is up-to-date, dockercomposedemo_web_5 is up-to-date, dockercomposedemo_web_3 is up-to-date, dockercomposedemo_web_4 is up-to-date, dockercomposedemo_web_1 is up-to-date, dockercomposedemo_lb_1 is up-to-date)
  • curl 0.0.0.0 (5 times)
  • docker-compose logs (shows:
web_1   | 172.17.0.101 - - [17/Sep/2015 09:44:02] "GET / HTTP/1.1" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:44:02] "GET / HTTP/1.1" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:44:02] "GET / HTTP/1.1" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:44:03] "GET / HTTP/1.1" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:44:03] "GET / HTTP/1.1" 200 -

Thought I'd try ab testing it:

ab -n 1000 -c 100 http://localhost/ 

In the logs:

web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
web_1   | 172.17.0.101 - - [17/Sep/2015 09:46:09] "GET / HTTP/1.0" 200 -
etc etc

Outputted in console:

$ ab -n 1000 -c 100 http://localhost/
This is ApacheBench, Version 2.3 <$Revision: 1663405 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Werkzeug/0.10.4
Server Hostname:        localhost
Server Port:            80

Document Path:          /
Document Length:        73 bytes

Concurrency Level:      100
Time taken for tests:   0.884 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      228000 bytes
HTML transferred:       73000 bytes
Requests per second:    1131.11 [#/sec] (mean)
Time per request:       88.409 [ms] (mean)
Time per request:       0.884 [ms] (mean, across all concurrent requests)
Transfer rate:          251.85 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       1
Processing:    16   85  15.7     87     112
Waiting:        6   85  15.7     86     111
Total:         17   85  15.5     87     112

Percentage of the requests served within a certain time (ms)
  50%     87
  66%     92
  75%     95
  80%     97
  90%    100
  95%    105
  98%    108
  99%    110
 100%    112 (longest request)

Cannot start service reverse-proxy

I got the following error while trying to up the composer.

docker-compose-demo$ docker-compose up
WARNING: Some networks were defined but are not used by any service: front-tier
Starting docker-compose-demo_whoami_1 ... 
Starting docker-compose-demo_redis_1  ... 
Starting docker-compose-demo_reverse-proxy_1 ... 
Starting docker-compose-demo_reverse-proxy_1 ... error

Starting docker-compose-demo_whoami_1        ... done
Starting docker-compose-demo_redis_1         ... done
r starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use

ERROR: for reverse-proxy  Cannot start service reverse-proxy: driver failed programming external connectivity on endpoint docker-compose-demo_reverse-proxy_1 (fb04b6009a1f0cd93b6e91effba7259e0d2dab1d49c7e32138e19de587f999c0): Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use
ERROR: Encountered errors while bringing up the project.

Error: Authentication is required.

sharry@sharry-Precision-T1700:~/Development/Projects/docker-compose-demo$ docker-compose up -d
Creating dockercomposedemo_redis_1...
Pulling image redis:latest...
Pulling repository docker.io/library/redis
Traceback (most recent call last):
File "", line 3, in
File "/code/build/docker-compose/out00-PYZ.pyz/compose.cli.main", line 31, in main
File "/code/build/docker-compose/out00-PYZ.pyz/compose.cli.docopt_command", line 21, in sys_dispatch
File "/code/build/docker-compose/out00-PYZ.pyz/compose.cli.command", line 27, in dispatch
File "/code/build/docker-compose/out00-PYZ.pyz/compose.cli.docopt_command", line 24, in dispatch
File "/code/build/docker-compose/out00-PYZ.pyz/compose.cli.command", line 59, in perform_command
File "/code/build/docker-compose/out00-PYZ.pyz/compose.cli.main", line 464, in up
File "/code/build/docker-compose/out00-PYZ.pyz/compose.project", line 208, in up
File "/code/build/docker-compose/out00-PYZ.pyz/compose.service", line 214, in recreate_containers
File "/code/build/docker-compose/out00-PYZ.pyz/compose.service", line 199, in create_container
File "/code/build/docker-compose/out00-PYZ.pyz/compose.progress_stream", line 37, in stream_output
File "/code/build/docker-compose/out00-PYZ.pyz/compose.progress_stream", line 50, in print_output_event
compose.progress_stream.StreamOutputError: Authentication is required.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.