docker-compose
1. Docker-compose是什么
大多数情况下, 完整的应用由多个服务组合而成, docker解决了单容器(服务)的问题, 但无法同时协调多个容器, docker-compose正是解决这一问题
Unfortunately, when you are a developer you rarely create a stand-alone program (a program that does not require any other services to run, such as a database).
However, how do you know if you need Docker-Compose? It’s very simple — if your application requires several services to run, you need this tool. For example, if you create a website that needs to connect to your database to authenticate users (here 2 services, website and database).
Docker-compose offers you the possibility to launch all these services in a single command.

2. 创建client/server模式应用
2.1 新建工程目录
.
├── client/
├── docker-compose.yml
└── server/
2.2 server容器
Dockerfile + 业务代码
.
├── Dockerfile
├── index.html
└── server.py
server.py内容如下, 创建一个简单的web服务, 监听端口1234
#!/usr/bin/env python3
# Import of python system libraries.
# These libraries will be used to create the web server.
# You don't have to install anything special, these libraries are installed with Python.
import http.server
import socketserver
# This variable is going to handle the requests of our client on the server.
handler = http.server.SimpleHTTPRequestHandler
# Here we define that we want to start the server on port 1234.
# Try to remember this information it will be very useful to us later with docker-compose.
with socketserver.TCPServer(("", 1234), handler) as httpd:
# This instruction will keep the server running, waiting for requests from the client.
httpd.serve_forever()
index.html内容如下, 作为client请求的响应内容
Docker-Compose is magic!
最后编辑Dockerfile文件
FROM python:latest
ADD server.py /server/
ADD index.html /server/
# I would like to introduce something new, the 'WORKDIR' command.
# This command changes the base directory of your image.
# Here we define '/server/' as base directory (where all commands will be executed).
WORKDIR /server/
2.3 client容器
另一个容器
.
├── client.py
└── Dockerfile
client.py内容如下, 向server发出请求并打印结果
#!/usr/bin/env python3
# Import of python system library.
# This library is used to download the 'index.html' from server.
# You don't have to install anything special, this library is installed with Python.
import urllib.request
# This variable contain the request on 'http://localhost:1234/'.
# You must wondering what is 'http://localhost:1234'?
# localhost: This means that the server is local.
# 1234: Remember we define 1234 as the server port.
fp = urllib.request.urlopen("http://localhost:1234/")
# 'encodedContent' correspond to the server response encoded ('index.html').
# 'decodedContent' correspond to the server response decoded (what we want to display).
encodedContent = fp.read()
decodedContent = encodedContent.decode("utf8")
# Display the server file: 'index.html'.
print(decodedContent)
# Close the server connection.
fp.close()
再来编辑Dockerfile
FROM python:latest
ADD client.py /client/
WORKDIR /client/
2.4 组合容器
最后编辑docker-compose.yml文件, 将server容器和client容器组合成一个应用
# A docker-compose must always start by the version tag.
# We use "3" because it's the last version at this time.
version: "3"
# You should know that docker-composes works with services.
# 1 service = 1 container.
# For example, a service maybe, a server, a client, a database...
# We use the keyword 'services' to start to create services.
services:
# As we said at the beginning, we want to create: a server and a client.
# That is two services.
# First service (container): the server.
# Here you are free to choose the keyword.
# It will allow you to define what the service corresponds to.
# We use the keyword 'server' for the server.
server:
# The keyword "build" will allow you to define
# the path to the Dockerfile to use to create the image
# that will allow you to execute the service.
# Here 'server/' corresponds to the path to the server folder
# that contains the Dockerfile to use.
build: server/
# The command to execute once the image is created.
# The following command will execute "python ./server.py".
command: python ./server.py
# Remember that we defined in'server/server.py' 1234 as port.
# If we want to access the server from our computer (outside the container),
# we must share the content port with our computer's port.
# To do this, the keyword 'ports' will help us.
# Its syntax is as follows: [port we want on our machine]:[port we want to retrieve in the container]
# In our case, we want to use port 1234 on our machine and
# retrieve port 1234 from the container (because it is on this port that
# we broadcast the server).
ports:
- 1234:1234
# Second service (container): the client.
# We use the keyword 'client' for the server.
client:
# Here 'client/ corresponds to the path to the client folder
# that contains the Dockerfile to use.
build: client/
# The command to execute once the image is created.
# The following command will execute "python ./client.py".
command: python ./client.py
# The keyword 'network_mode' is used to define the network type.
# Here we define that the container can access to the 'localhost' of the computer.
network_mode: host
# The keyword'depends_on' allows you to define whether the service
# should wait until other services are ready before launching.
# Here, we want the 'client' service to wait until the 'server' service is ready.
depends_on:
- server
2.5 构建与启动
$ docker-compose build
$ docker-compose up