参考文档:https://docs.docker.com/compose/

docker 使我们能够把应用的各个部分单独打包成不同的 container(如把网站的 apache 放到一个 container,数据库放到另一个 container )来提高可靠性和实现更灵活的配置。然而每次都得打开一堆 container 才能打开一个应用显得并不方便,Docker Compose 就是用来解决这个痛点的。

总体介绍

Docker Compose 定义:定义和运行多个 docker container 的工具。你只需要在一个文件中定义一个多 container 的应用,然后就能通过一条命令来管理这个应用了。

Compose 对于开发环境、演示环境及 CI 环境中相当实用,然而目前官方并不推荐在生产环境中使用它。

使用 Compose 主要有 3 步:

  1. 使用 Dockerfile 定义你的应用的环境(一个 Dockerfile 对应一个 container)
  2. 使用 docker-compose.yml 定义你的应用需要用到的服务。
  3. 运行 docker-compose up ,Compose 就会启动你的整个应用及所需要的服务。

docker-compose.yml 大致格式如下:

web:
  build: .
  ports:
   - "5000:5000"
  volumes:
   - .:/code
  links:
   - redis
redis:
  image: redis

Compose 的命令主要有:

快速入门

以一个 python 应用为例子介绍 compose 的使用

安装及配置

首先,安装 docker 和 compose。目前 docker-toolbox 中已经自带了 compose ,因此 mac/windows 上不需要额外安装了。

然后,为你的项目建立一个文件夹:

$ mkdir composetest
$ cd composetest

创建一个 app.py 文件。文件中使用了 Flask 和 Redis ,因此,我们后面定义服务的时候会为这两个服务创建 container

from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    redis.incr('hits')
    return 'Hello World! I have been seen %s times.' % redis.get('hits')

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

requirement.txt 文件中定义 python 的依赖:

flask
redis

创建 Docker image

创建 Dockerfile 文件:

# Build an image starting with the Python 2.7 image.
FROM python:2.7

# Add the current directory . into the path /code in the image.
ADD . /code

# Set the working directory to /code.
WORKDIR /code

# Install your Python dependencies.
RUN pip install -r requirements.txt

# Set the default command for the container to python app.py
CMD python app.py

定义服务

重头戏来了。创建一个 docker-compose.yml 来定义一系列服务:

web:
  # Builds from the Dockerfile in the current directory.
  build: .

  # Forwards the exposed port 5000 on the container to port 5000 on the host machine.
  ports:
   - "5000:5000"

  # Mounts the current directory on the host to /code inside the container allowing you to modify the code without having to rebuild the image.
  volumes:
   - .:/code

  # Connects the web container to the Redis service via a link.
  links:
   - redis

redis:
  # Uses the public Redis image which gets pulled from the Docker Hub registry.
  image: redis

使用 Compose 来 build 和运行你的应用

可通过在浏览器中打开 http://192.168.99.100:5000 查看网页。此时会看到网页中显示:

Hello World! I have been seen 1 times.

同时命令行中会显示网络请求的 log :

web_1   | 192.168.99.1 - - [23/Aug/2015 13:52:34] "GET / HTTP/1.1" 200 -
web_1   | 192.168.99.1 - - [23/Aug/2015 13:52:34] "GET /favicon.ico HTTP/1.1" 404 -

$ docker-compose ps

Name Command State Ports

composetest_redis_1 /entrypoint.sh redis-server Up 6379/tcp
composetest_web_1 /bin/sh -c python app.py Up 0.0.0.0:5000->5000/tcp


* 在单独服务中运行命令,如在 web 这个服务中查看环境变量:

$ docker-compose run web env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=7681a42c0560
TERM=xterm
COMPOSETEST_WEB_1_PORT=tcp://172.17.0.15:5000
COMPOSETEST_WEB_1_PORT_5000_TCP=tcp://172.17.0.15:5000
COMPOSETEST_WEB_1_PORT_5000_TCP_ADDR=172.17.0.15
COMPOSETEST_WEB_1_PORT_5000_TCP_PORT=5000
COMPOSETEST_WEB_1_PORT_5000_TCP_PROTO=tcp
COMPOSETEST_WEB_1_NAME=/composetest_web_run_1/composetest_web_1
COMPOSETEST_WEB_1_ENV_affinity:container==6edaa1eb27095dd320de439516f28a1431169949c49a2588a72a9520a97d6ff2
COMPOSETEST_WEB_1_ENV_LANG=C.UTF-8
COMPOSETEST_WEB_1_ENV_PYTHON_VERSION=2.7.10
COMPOSETEST_WEB_1_ENV_PYTHON_PIP_VERSION=7.1.1
REDIS_PORT=tcp://172.17.0.14:6379
REDIS_PORT_6379_TCP=tcp://172.17.0.14:6379
REDIS_PORT_6379_TCP_ADDR=172.17.0.14
REDIS_PORT_6379_TCP_PORT=6379
REDIS_PORT_6379_TCP_PROTO=tcp
REDIS_NAME=/composetest_web_run_1/redis
REDIS_ENV_REDIS_VERSION=3.0.3
REDIS_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.0.3.tar.gz
REDIS_ENV_REDIS_DOWNLOAD_SHA1=0e2d7707327986ae652df717059354b358b83358
REDIS_1_PORT=tcp://172.17.0.14:6379
REDIS_1_PORT_6379_TCP=tcp://172.17.0.14:6379
REDIS_1_PORT_6379_TCP_ADDR=172.17.0.14
REDIS_1_PORT_6379_TCP_PORT=6379
REDIS_1_PORT_6379_TCP_PROTO=tcp
REDIS_1_NAME=/composetest_web_run_1/redis_1
REDIS_1_ENV_REDIS_VERSION=3.0.3
REDIS_1_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.0.3.tar.gz
REDIS_1_ENV_REDIS_DOWNLOAD_SHA1=0e2d7707327986ae652df717059354b358b83358
WEB_PORT=tcp://172.17.0.15:5000
WEB_PORT_5000_TCP=tcp://172.17.0.15:5000
WEB_PORT_5000_TCP_ADDR=172.17.0.15
WEB_PORT_5000_TCP_PORT=5000
WEB_PORT_5000_TCP_PROTO=tcp
WEB_NAME=/composetest_web_run_1/web
WEB_ENV_affinity:container==6edaa1eb27095dd320de439516f28a1431169949c49a2588a72a9520a97d6ff2
WEB_ENV_LANG=C.UTF-8
WEB_ENV_PYTHON_VERSION=2.7.10
WEB_ENV_PYTHON_PIP_VERSION=7.1.1
WEB_1_PORT=tcp://172.17.0.15:5000
WEB_1_PORT_5000_TCP=tcp://172.17.0.15:5000
WEB_1_PORT_5000_TCP_ADDR=172.17.0.15
WEB_1_PORT_5000_TCP_PORT=5000
WEB_1_PORT_5000_TCP_PROTO=tcp
WEB_1_NAME=/composetest_web_run_1/web_1
WEB_1_ENV_affinity:container==6edaa1eb27095dd320de439516f28a1431169949c49a2588a72a9520a97d6ff2
WEB_1_ENV_LANG=C.UTF-8
WEB_1_ENV_PYTHON_VERSION=2.7.10
WEB_1_ENV_PYTHON_PIP_VERSION=7.1.1
COMPOSETEST_REDIS_1_PORT=tcp://172.17.0.14:6379
COMPOSETEST_REDIS_1_PORT_6379_TCP=tcp://172.17.0.14:6379
COMPOSETEST_REDIS_1_PORT_6379_TCP_ADDR=172.17.0.14
COMPOSETEST_REDIS_1_PORT_6379_TCP_PORT=6379
COMPOSETEST_REDIS_1_PORT_6379_TCP_PROTO=tcp
COMPOSETEST_REDIS_1_NAME=/composetest_web_run_1/composetest_redis_1
COMPOSETEST_REDIS_1_ENV_REDIS_VERSION=3.0.3
COMPOSETEST_REDIS_1_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.0.3.tar.gz
COMPOSETEST_REDIS_1_ENV_REDIS_DOWNLOAD_SHA1=0e2d7707327986ae652df717059354b358b83358
LANG=C.UTF-8
PYTHON_VERSION=2.7.10
PYTHON_PIP_VERSION=7.1.1
HOME=/root


* 停止应用(对应后台运行。若没加 `-d` 则直接 ctrl+c 即可)

$ docker-compose stop
Stopping composetest_web_1... done
Stopping composetest_redis_1... done


## 遇到的问题

1. 在 build server 的过程中出现此错误:

Collecting redis (from -r requirements.txt (line 2))
Downloading redis-2.10.3.tar.gz (86kB)
Exception:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/pip/basecommand.py", line 211, in main
status = self.run(options, args)
File "/usr/local/lib/python2.7/site-packages/pip/commands/install.py", line 305, in run
wb.build(autobuilding=True)
File "/usr/local/lib/python2.7/site-packages/pip/wheel.py", line 705, in build
self.requirement_set.prepare_files(self.finder)
File "/usr/local/lib/python2.7/site-packages/pip/req/req_set.py", line 334, in prepare_files
functools.partial(self._prepare_file, finder))
File "/usr/local/lib/python2.7/site-packages/pip/req/req_set.py", line 321, in _walk_req_to_install
more_reqs = handler(req_to_install)
File "/usr/local/lib/python2.7/site-packages/pip/req/req_set.py", line 491, in _prepare_file
session=self.session)
File "/usr/local/lib/python2.7/site-packages/pip/download.py", line 825, in unpack_url
session,
File "/usr/local/lib/python2.7/site-packages/pip/download.py", line 673, in unpack_http_url
from_path, content_type = _download_http_url(link, session, temp_dir)
File "/usr/local/lib/python2.7/site-packages/pip/download.py", line 886, in _download_http_url
_download_url(resp, link, content_file)
File "/usr/local/lib/python2.7/site-packages/pip/download.py", line 621, in _download_url
for chunk in progress_indicator(resp_read(4096), 4096):
File "/usr/local/lib/python2.7/site-packages/pip/utils/ui.py", line 133, in iter
for x in it:
File "/usr/local/lib/python2.7/site-packages/pip/download.py", line 586, in resp_read
decode_content=False):
File "/usr/local/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/response.py", line 307, in stream
data = self.read(amt=amt, decode_content=decode_content)
File "/usr/local/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/response.py", line 267, in read
raise ReadTimeoutError(self._pool, None, 'Read timed out.')
ReadTimeoutError: HTTPSConnectionPool(host='pypi.python.org', port=443): Read timed out.
You are using pip version 7.1.1, however version 7.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Service 'web' failed to build: The command '/bin/sh -c pip install -r requirements.txt' returned a non-zero code: 2


 **解决方法**
在 Dockerfile 中添加一行:

FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install --upgrade pip # add this line to upgrade pip first
RUN pip install -r requirements.txt
CMD python app.py


添加后问题解决。


↙↙↙阅读原文可查看相关链接,并与作者交流