Date post: | 06-Aug-2015 |
Category: |
Technology |
Upload: | jonas-rosland |
View: | 374 times |
Download: | 3 times |
Docker Compose and Panamax
Jonas RoslandDeveloper Advocate
emccode.github.ioJune 2015
emccode.github.io
Raffle!Follow and tweet
@emccode
github.com/emccode/training
Different types of management
Developer-focused:- Docker Compose- Panamax
Ops-focused:- Kubernetes- Mesos- Tectonic- Fleet- Docker Swarm
First a bit of history
Fig
Fig
Fast, isolated development environments using Docker.Orchard acquired by Docker July 2014Docker's first acquisition
Docker Compose(Fig 2.0)
First, let's verify your installs1. boot2docker/docker
2. Docker Compose
boot2docker$ boot2docker init$ boot2docker upWaiting for VM and Docker daemon to start................................oooooooooooooooooooooooooooooooooooooooStarted.
Docker$ docker versionClient version: 1.6.2Client API version: 1.18Go version (client): go1.4.2Git commit (client): 7c8fca2OS/Arch (client): darwin/amd64Server version: 1.6.2Server API version: 1.18Go version (server): go1.4.2Git commit (server): 7c8fca2OS/Arch (server): linux/amd64
Docker Compose$ docker-compose psName Command State Ports------------------------------
Optional: Clean up your Docker environmentdocker rm `docker images -q`docker rmi `docker images -q`
Docker Compose example (1/3)
Let's define two services:
web- built from Dockerfile- runs the command python app.py inside the image- forwards the exposed port 5000 on the container to port 5000 on the host machine- connects to the Redis service- mounts the current directory inside the container
redis, which uses the public image redis
Docker Compose example (2/3)
Dockerfile:FROM python:2.7ADD . /codeWORKDIR /codeRUN pip install -r requirements.txt
Docker Compose example (3/3)
docker-compose.yml:web: build: . command: python app.py ports: - "5000:5000" volumes: - .:/code links: - redisredis: image: redis
So what are we defining?build - the dir we are building fromcommand - the command we run inside the containerports - the ports we open and map to the hostvolumes - directory we map as a volume and where we mount itlinks - what service we link to (create /etc/hosts lines)
Run it!$ docker-compose upCreating lab3dockercomposeandpanamax_redis_1...Pulling image redis:latest...latest: Pulling from redis<snip>Creating lab3dockercomposeandpanamax_web_1...Building web...Step 0 : FROM python:2.72.7: Pulling from python<snip>redis_1 | 1:M 05 Jun 16:20:55.105 * DB loaded from disk: 0.000 secondsredis_1 | 1:M 05 Jun 16:20:55.105 * The server is now ready to accept connections on port 6379web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)web_1 | * Restarting with stat
Verify that it's running$ docker-compose ps Name Command State Ports--------------------------------------------------------------------------------------------------lab3dockercomposeandpanamax_redis_1 /entrypoint.sh redis-server Up 6379/tcplab3dockercomposeandpanamax_web_1 python app.py Up 0.0.0.0:5000->5000/tcp
Wanna verify more stuff?
docker ps$ docker psCONTAINER ID IMAGE9f4fe02e2696 lab3dockercomposeandpanamax_web:latestd01f11317166 redis:latest
docker exec$ docker exec -ti 9f4fe02e2696 /bin/bashroot@9f4fe02e2696:/code# lsDockerfile app.py docker-compose.yml requirements.txt test
docker execroot@9f4fe02e2696:/code# cat /etc/hosts172.17.0.7 9f4fe02e2696127.0.0.1 localhost<snip>172.17.0.5 lab3dockercomposeandpanamax_redis_1 d01f11317166172.17.0.5 redis d01f11317166 lab3dockercomposeandpanamax_redis_1172.17.0.5 redis_1 d01f11317166 lab3dockercomposeandpanamax_redis_1
Sooooo, how do we connect to it?$ boot2docker ip192.168.59.103
Refresh!
So what have you done?Built a container from scratchRun a web app using Flask in the containerConnect it to RedisStore data in RedisRetrieve the data and present it
Pretty cool!
What happens if you stop and start it?
Was there anything unneccesary in the Dockerfile or docker-
compose.yml?
Some more info on Docker Compose
External linksLink to containers outside Docker Compose using CONTAINER:ALIASexternal_links: - redis_1 - project_db_1:mysql - project_db_1:postgresql
PortsUsing the HOST:CONTAINER format, don't use ports lower than 60, because YAML will parse numbers in the format xx:yy as sexagesimal (base 60). For this reason, we recommend always adding port mappings as strings.
ports: - "3000" - "8000:8000" - "49100:22" - "127.0.0.1:8001:8001"
What about scaling?
Let's change our docker-compose.ymlweb: build: . command: python app.py ports: - "5000" links: - redisredis: image: redis
Re-run docker-compose up$ docker-compose up<snip>$ docker-compose ps Name Command State Ports---------------------------------------------------------------------------------------------------lab3dockercomposeandpanamax_redis_1 /entrypoint.sh redis-server Up 6379/tcplab3dockercomposeandpanamax_web_1 python app.py Up 0.0.0.0:32770->5000/tcp
See the port number?
Scale it!$ docker-compose scale web=3Creating lab3dockercomposeandpanamax_web_2...Creating lab3dockercomposeandpanamax_web_3...Starting lab3dockercomposeandpanamax_web_2...Starting lab3dockercomposeandpanamax_web_3...
Check the ports$ docker-compose ps Name Command State Ports---------------------------------------------------------------------------------------------------lab3dockercomposeandpanamax_redis_1 /entrypoint.sh redis-server Up 6379/tcplab3dockercomposeandpanamax_web_1 python app.py Up 0.0.0.0:32770->5000/tcplab3dockercomposeandpanamax_web_2 python app.py Up 0.0.0.0:32771->5000/tcplab3dockercomposeandpanamax_web_3 python app.py Up 0.0.0.0:32772->5000/tcp
So what have you done?Scaled a web appConnected all web instances to a shared Redis DBStored persistent data in RedisPresented that persistent data using all web instances
You are awesome :)
One more thing...
Docker Compose Extends!
ExtendsEnables sharing of common configsLets you reuse commonly-defined services
So how do we do this?
Lets take our example app again
app.pyfrom flask import Flaskfrom redis import Redisimport os
app = Flask(__name__)redis = Redis(host=os.environ['REDIS_HOST'], port=6379)
@app.route('/')def hello(): redis.incr('hits') return 'Hello World! I have been seen %s times.\n' % redis.get('hits')
if __name__ == "__main__": app.run(host="0.0.0.0", debug=True)
DockerfileFROM python:2.7ADD . /codeWORKDIR /codeRUN pip install -r requirements.txtCMD python app.py
common.ymlweb: build: . ports: - "5000:5000"
docker-compose.ymlweb: extends: file: common.yml service: web volumes: - .:/code links: - redis environment: - REDIS_HOST=redisredis: image: redis
docker-compose up
Try changing app.py to see what happens :)
production.ymlweb: extends: file: common.yml service: web environment: - REDIS_HOST=redis-production.example.com
docker-compose -f production.yml up
Alright, time for Panamax
Panamax
An open-source project that makes deploying complex containerized apps as easy as Drag-and-DropCreated by CenturyLink LabsReleased in August 2014
Search for images
Run images in "apps"
Manage and add more images to an app
Expose ports
Link containers together
Verify you've got Panamax installed$ panamax init
Port forwarding your Panamax instanceVBoxManage controlvm panamax-vm natpf1 rule1,tcp,,8080,,80
Demotime!!
Hope you all enjoyed this workshop :)
Fin