Docker Compose网络配置

注意:本文涉及的compose只适用于compose文件格式为version 2的版本。verion 1(旧的)不支持网络功能。

默认下compose为你的app配置一个单独的网络。服务中的每个容器都加入到这个默认的网络且在这个网络的容器都能互相通信,它们也能通过与容器名称相同的主机名发现对方。

注意:app的网络基于“项目名称”设置网络名称,这个项目名称基于项目所处的目录名称。可以使用–project-name选项或COMPOSE_PROJECT_NAME环境变量来覆盖它。

例如,假设app在一个名为myapp的目录,docker-compose.yml类似如下:

  1. version: ‘2’
  2.  
  3. services:
  4.   web:
  5.     build: .
  6.     ports:
  7.       – "8000:8000"
  8.   db:
  9.     image: postgres

当执行docker-compose up时,网络部分设置如下:
1.创建了称为myapp_default的网络。
2.使用web的配置创建了容器,然后这个容器加入到myapp_default网络。
3.使用db的配置创建容器,这个容器加入到myapp_default网络。

每个容器现在能查找web或db来得到容器的IP地址。例如,web应用程序的代码可以连接URL postgres://db:5432并开始使用postgres数据库。

由于web明确地映射了一个端口,外部网络也就能通过在docker主机的网络接口的8000端口连接容器。

更新容器

如果更改了服务的配置并执行docker-compose up来更新它,将删除旧的容器并且新的容器加入到相同的网络,分配到了不同的IP地址不过主机名不变。运行中的容器应该能够查找主机名并连接到新的地址,不过旧的地址将失效。

如果任何一个容器与旧的容器有连接,它们会被关闭掉。容器有责任检测这种情况然后重新查找旧容器的主机来重新连接。

链接

链接可以为一个容器定义额外的别名。它们不需要启用服务进行通信 – 默认情况下,任何服务都可以通过该服务的名称访问任何其他服务。在下面的示例中,在web容器中可以通过db和database访问db容器。

  1. version: ‘2’
  2. services:
  3.   web:
  4.     build: .
  5.     links:
  6.       – "db:database"
  7.   db:
  8.     image: postgres

指定自定义网络

除了使用默认的app网络之外,还可以使用最顶层networks关键词指定自己定义的网络。这让你可以创建更复制的网络拓扑并指定自定义网络驱动及其选项。也可以使用它来连接服务到不由compose管理的外部创建的网络。

每个服务都能指定连接由networks关键词配置的网络。

下面的示例compose文件定义了两个自定义网络。proxy服务与db服务隔离,因为它们没有指定相同的网络。

  1. version: ‘2’
  2.  
  3. services:
  4.   proxy:
  5.     build: ./proxy
  6.     networks:
  7.       – front
  8.   app:
  9.     build: ./app
  10.     networks:
  11.       – front
  12.       – back
  13.   db:
  14.     image: postgres
  15.     networks:
  16.       – back
  17.  
  18. networks:
  19.   front:
  20.     # Use a custom driver
  21.     driver: custom-driver-1
  22.   back:
  23.     # Use a custom driver which takes special options
  24.     driver: custom-driver-2
  25.     driver_opts:
  26.       foo: "1"
  27.       bar: "2"

也可以通过设置ipv4_address和/或ipv6_address为每个附着的网络配置静态的IP地址。

Docker Compose: 在文件和项目间共享compose配置

compose支持两种共享通用配置的方法:
1.通过使用多个compose文件扩展整个compose文件
2.使用extends字段扩展单个服务

多个compose文件

使用多个compose文件可以为不同的环境或不同的工作流自定义compose应用程序。

理解多compose文件

默认下,compose读取两个文件,一个docker-compose.yml和一个可选的docker-compose.override.yml文件。通常来说,docker-compose.yml包含基本的配置。而override文件包含覆盖已存在服务或整个新服务的配置。

如果一个服务在两个文件中都有定义,那么compose就使用在”添加和覆盖配置”中描述的规则合并配置。

要使用多个override文件或不同名称的override文件,可以使用-f选项指定文件列表。compose根据在命令行指定的顺序来合并它们。

当使用多个配置文件时,必须确保文件中所有的路径是相对于base compose文件的(-f指定的第一个compose文件)。这样要求是因此override文件不需要是一个有效的compose文件。override文件可以只包含配置中的小片段。跟踪一个服务的片段是相对于哪个路径的是很困难的且令人困惑的,所以要保持路径容易理解,所以的路径必须定义为相对于base文件的路径。

示例

在本段介绍两个常见的多compose文件用例:为不同的环境更改compose app和针对compose app运行管理任务。

不同的环境

使用多文件的一个常见用例是更改用于类生产环境(可能是生产环境,临时环境或配置项)的开发compose app。要支持这样的更改,可以把一个compose配置文件分割为多个不同的文件:

从定义服务的规范配置的基本文件开始。

docker-compose.yml

  1. web:
  2.   image: example/my_web_app:latest
  3.   links:
  4.     – db
  5.     – cache
  6.  
  7. db:
  8.   image: postgres:latest
  9.  
  10. cache:
  11.   image: redis:latest

在下面这个示例中开发配置暴露了一些端口到主机上,挂载代码目录到容器然后构建web镜像。

docker-compose.override.yml

  1. web:
  2.   build: .
  3.   volumes:
  4.     – ‘.:/code’
  5.   ports:
  6.     – 8883:80
  7.   environment:
  8.     DEBUG: ‘true’
  9.  
  10. db:
  11.   command: ‘-d’
  12.   ports:
  13.     – 5432:5432
  14.  
  15. cache:
  16.   ports:
  17.     – 6379:6379

当执行docker-compose up命令时它会自动读取这个override文件。

现在我们创建另一个用于生产环境的override文件。

docker-compose.prod.yml

  1. web:
  2.   ports:
  3.     – 80:80
  4.   environment:
  5.     PRODUCTION: ‘true’
  6.  
  7. cache:
  8.   environment:
  9.     TTL: ‘500’

要使用这个生产compose文件部署,运行如下命令:

  1. docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

这个将会使用docker-compose.yml和docker-compose.prod.yml(没有用到docker-compose.override.yml)来部署这三个服务。

管理任务

另一个常见的用例是针对在compose app中的一个或多个服务运行adhoc或管理任务。这个示例演示备份运行中的数据库。

docker-compose.yml

  1. web:
  2.   image: example/my_web_app:latest
  3.   links:
  4.     – db
  5.  
  6. db:
  7.   image: postgres:latest

在docker-compose.admin.yml中添加一个新服务用到导出数据库或备份。

  1. dbadmin:
  2.   build: database_admin/
  3.   links:
  4.     – db

要启动一个正常的环境运行docker-compose up -d。要备份数据库,运行:

  1. docker-compose -f docker-compose.yml -f docker-compose.admin.yml
  2.     run dbadmin db-backup

扩展服务

docker compose的extends关键词能够在不同的文件或甚至完全不同的项目之间共享通用的配置。如果有几个重用通用配置项集的服务,则扩展服务非常有用。使用extends你可以在一个地方定义一个通用的服务选项集然后在任何地方引用它。

注意:不能使用extends来共享links, volumes_from和depends_on配置。这是为了避免隐式依赖 – 始终在本地定义links和volumes_fromm。这确保了当读取当前文件时服务之间的依赖是清晰可见的。在本地定义这些还确保对引用文件的更改不会导致破坏。

理解extends配置

当在docker-compose.yml定义任何服务时,可以像这样声明扩展另一个服务:

  1. web:
  2.   extends:
  3.     file: common-services.yml
  4.     service: webapp

这告诉compose重用定义在comm-services.yml文件的webapp服务配置。假设common-services.yml看起来像这样的:

  1. webapp:
  2.   build: .
  3.   ports:
  4.     – "8000:8000"
  5.   volumes:
  6.     – "/data"

在这种情况下,docker-compose.yml中定义的web服务将与webapp配置一样。

我们可以进一步在本地定义(或重新定义)docker-compose.yml:

  1. web:
  2.   extends:
  3.     file: common-services.yml
  4.     service: webapp
  5.   environment:
  6.     – DEBUG=1
  7.   cpu_shares: 5
  8.  
  9. important_web:
  10.   extends: web
  11.   cpu_shares: 10

也可以定义其它服务并在web服务链接它们:

  1. web:
  2.   extends:
  3.     file: common-services.yml
  4.     service: webapp
  5.   environment:
  6.     – DEBUG=1
  7.   cpu_shares: 5
  8.   links:
  9.     – db
  10. db:
  11.   image: postgres

示例用例

当多个服务有一个通用的配置时,扩展单个服务非常有用。下面示例是有两个服务的compose app:一个web应用程序和一个queue worker。两个服务使用相同的代码和共享许多配置项。

在common.yml我们定义通用的配置:

  1. app:
  2.   build: .
  3.   environment:
  4.     CONFIG_FILE_PATH: /code/config
  5.     API_KEY: xxxyyy
  6.   cpu_shares: 5

在docker-compose.yml文件我们定义使用通用配置的具体服务:

  1. webapp:
  2.   extends:
  3.     file: common.yml
  4.     service: app
  5.   command: /code/run_web_app
  6.   ports:
  7.     – 8080:8080
  8.   links:
  9.     – queue
  10.     – db
  11.  
  12. queue_worker:
  13.   extends:
  14.     file: common.yml
  15.     service: app
  16.   command: /code/run_worker
  17.   links:
  18.     – queue

添加和覆盖配置

compose从original服务复制配置到local服务。如果配置项定义在original服务和local服务中,local服务的值替换或扩展original服务的值。

对于单值选项如image,command或mem_limit,新值替换旧值。

  1. # original service
  2. command: python app.py
  3.  
  4. # local service
  5. command: python otherapp.py
  6.  
  7. # result
  8. command: python otherapp.py

注意:当使用的是version 1的compose文件格式时,build和image两个选项,在local服务使用一个选项会导致compose忽略另一个如果定义在original服务的选项。

例如,如果orginal服务定义了image: webapp且local服务定义了build: . 那么结果是服务有build: .选项没有image选项。

这是因为在verion 1文件中build和image不能一起使用。

对于多值选项ports,expose,external_link,dns,dns_search物tmpfs,compose连接两组值:

  1. # original service
  2. expose:
  3.   – "3000"
  4.  
  5. # local service
  6. expose:
  7.   – "4000"
  8.   – "5000"
  9.  
  10. # result
  11. expose:
  12.   – "3000"
  13.   – "4000"
  14.   – "5000"

对于environment, labels, volumes和devices,compose以本地定义的值优先原则来合并它们:

  1. # original service
  2. environment:
  3.   – FOO=original
  4.   – BAR=original
  5.  
  6. # local service
  7. environment:
  8.   – BAR=local
  9.   – BAZ=local
  10.  
  11. # result
  12. environment:
  13.   – FOO=original
  14.   – BAR=local
  15.   – BAZ=local

关于Docker Compose的环境变量

在compose文件中引用环境变量

可以在compose文件中引用运行docker-compose所在的shell中的环境变量,如:

  1. web:
  2.   image: "webapp:${TAG}"

在容器中设置环境变量

可以在compose文件中的environment关键词下设置容器的环境变量,就像docker run -e VARIABLE=VALUE …:

  1. web:
  2.   environment:
  3.     – DEBUG=1

将环境变量传递到容器

可以在compose文件中的environment关键词下定义一个环境变量而不赋值,就像docker run -e VARIABLE …:

  1. web:
  2.   environment:
  3.     – DEBUG

容器中环境变量DEBUG的值是从执行compose文件所在的shell的同一个环境变量取得。

env_file配置选项

可以使用compose文件中的env_file选项从一个外部的文件传递多个环境变量到容器中,就像docker run –env-file=FILE …:

  1. web:
  2.   env_file:
  3.     – web-variables.env

使用docker-compose run设置环境变量

就像docker run -e,可以使用docker-compose run -e为一次性容器设置环境变量:

  1. docker-compose run -e DEBUG=1 web python console.py

也可以不赋值从shell变量中取值:

  1. docker-compose run -e DEBUG web python console.py

DEBUG的值是从执行compose文件所在的shell的同一个环境变量取得。

.env文件

可以在环境文件.env设置默认的环境变量,这些环境变量可以在compose文件引用:

  1. $ cat .env
  2. TAG=v1.5
  3.  
  4. $ cat docker-compose.yml
  5. version: ‘2.0’
  6. services:
  7.   web:
  8.     image: "webapp:${TAG}"

当执行docker-compose up命令,上面定义的web服务将使用webapp:v1.5镜像。可以使用config命令来打印出来:

  1. $ docker-compose config
  2. version: ‘2.0’
  3. services:
  4.   web:
  5.     image: ‘webapp:v1.5’

在shell中的环境变量将比定义在.env文件中的环境变量优先。如果在shell中设置了一个不同的TAG,镜像将使用shell中定义的而不是.env文件中的:

  1. $ export TAG=v2.0
  2. $ docker-compose config
  3. version: ‘2.0’
  4. services:
  5.   web:
  6.     image: ‘webapp:v2.0’

Docker Compose: 在一个文件声明默认的环境变量

compose支持在执行docker-compose命令的所在目录的.env文件中声明默认的环境变量。

env文件每行声明一个变量,格式为VAR=VAL。以#开头的行会忽略,也包括空行。

注意:那些在存在于运行时的环境变量始终会覆盖定义在.env文件的变量。类似地,通过命令行参数传递的值也优先。

可以在compose文件引用环境变量,也可以定义下面的CLI变量:

  • COMPOSE_API_VERSION
  • COMPOSE_CONVERT_WINDOWS_PATHS
  • COMPOSE_FILE
  • COMPOSE_HTTP_TIMEOUT
  • COMPOSE_TLS_VERSION
  • COMPOSE_PROJECT_NAME
  • DOCKER_CERT_PATH
  • DOCKER_HOST
  • DOCKER_TLS_VERIFY
  • 快速入门: Compose和WordPress

    我们可以使用docker compose很容易地在使用docker容器的隔离环境运行wordpress。本快速指南演示如何使用compose配置和运行wordpress。

    定义项目

    1.创建一个空的项目目录。
    可以用容易记住和理解的名称命名此项目。这个目录是应用程序镜像的上下文。此目录应该只包含用于构建那个镜像的资源。
    2.切换目录到项目目录。
    例如,如果命名项目目录为my_wordpress:

    1. cd my_wordpress/

    3.创建启动wordpress博客的docker-compose.yml文件,以及为了数据持久性挂载一个数据卷的独立的mysql实例:

    1. version: ‘2’
    2.  
    3. services:
    4.    db:
    5.      image: mysql:5.7
    6.      volumes:
    7.        – db_data:/var/lib/mysql
    8.      restart: always
    9.      environment:
    10.        MYSQL_ROOT_PASSWORD: wordpress
    11.        MYSQL_DATABASE: wordpress
    12.        MYSQL_USER: wordpress
    13.        MYSQL_PASSWORD: wordpress
    14.  
    15.    wordpress:
    16.      depends_on:
    17.        – db
    18.      image: wordpress:latest
    19.      ports:
    20.        – "8000:80"
    21.      restart: always
    22.      environment:
    23.        WORDPRESS_DB_HOST: db:3306
    24.        WORDPRESS_DB_PASSWORD: wordpress
    25. volumes:
    26.     db_data:

    注意:docker数据卷db_data将保持由wordpress对mysql的更新的数据。

    构建项目

    现在从项目目录执行docker-compose -up命令。
    这个命令将拉取所需的镜像和启动wordpress和数据库容器。

    1. $ docker-compose up -d
    2. Creating network "my_wordpress_default" with the default driver
    3. Pulling db (mysql:5.7)…
    4. 5.7: Pulling from library/mysql
    5. efd26ecc9548: Pull complete
    6. a3ed95caeb02: Pull complete
    7. Digest: sha256:34a0aca88e85f2efa5edff1cea77cf5d3147ad93545dbec99cfe705b03c520de
    8. Status: Downloaded newer image for mysql:5.7
    9. Pulling wordpress (wordpress:latest)…
    10. latest: Pulling from library/wordpress
    11. efd26ecc9548: Already exists
    12. a3ed95caeb02: Pull complete
    13. 589a9d9a7c64: Pull complete
    14. Digest: sha256:ed28506ae44d5def89075fd5c01456610cd6c64006addfe5210b8c675881aff6
    15. Status: Downloaded newer image for wordpress:latest
    16. Creating my_wordpress_db_1
    17. Creating my_wordpress_wordpress_1

    浏览器配置wordpress

    在浏览器中打开ip:8000,开始配置wordpress。

    快速入门: Compose和Rails

    本快速入门指南介绍如何使用docker compose配置和运行一个Rails/PostgreSQL app。

    定义项目

    定义用来构建app的三个文件。首先由于app是运行在包含它的所有依赖的容器内,你需要定义哪些文件需要包括在容器内。这个可以使用Dockerfile来完成。这个Dockerfile包括:

    1. FROM ruby:2.3.3
    2. RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
    3. RUN mkdir /myapp
    4. WORKDIR /myapp
    5. ADD Gemfile /myapp/Gemfile
    6. ADD Gemfile.lock /myapp/Gemfile.lock
    7. RUN bundle install
    8. ADD . /myapp

    上面把应用程序代码放到了镜像内,这个镜像将用来运行一个包含Ruby,Bundler和其所有的依赖的容器。

    下一步,创建一个只加载Rails的bootstrap Gemfile文件。在后面将由rails new覆盖它。

    1. source ‘https://rubygems.org’
    2. gem ‘rails’, ‘5.0.0.1’

    需要一个空的Gemfile.lock文件,构建Dockerfile用到。

    1. touch Gemfile.lock

    最后,开始创建docker-compose.yml文件。这个文件描述了你的app由什么服务构建(数据库和web app),如何获取每一个的镜像以及需要链接它们到一起和暴露web app的端口的配置。

    1. version: ‘2’
    2. services:
    3.   db:
    4.     image: postgres
    5.   web:
    6.     build: .
    7.     command: bundle exec rails s -p 3000 -b ‘0.0.0.0’
    8.     volumes:
    9.       – .:/myapp
    10.     ports:
    11.       – "3000:3000"
    12.     depends_on:
    13.       – db

    构建项目

    准备好那三个文件后,就可以使用docker-compose run来生成Rails skeleton app了:

    1. docker-compose run web rails new . –force –database=postgresql –skip-bundle

    首先,compose使用Dockerfile构建web服务的镜像。然后使用那个镜像生成容器,在容器内运行rails new命令。一旦完成,将生成一个全新的app:

    1. $ ls -l
    2.   total 56
    3.   -rw-r–r–   1 user  staff   215 Feb 13 23:33 Dockerfile
    4.   -rw-r–r–   1 user  staff  1480 Feb 13 23:43 Gemfile
    5.   -rw-r–r–   1 user  staff  2535 Feb 13 23:43 Gemfile.lock
    6.   -rw-r–r–   1 root  root   478 Feb 13 23:43 README.rdoc
    7.   -rw-r–r–   1 root  root   249 Feb 13 23:43 Rakefile
    8.   drwxr-xr-x   8 root  root   272 Feb 13 23:43 app
    9.   drwxr-xr-x   6 root  root   204 Feb 13 23:43 bin
    10.   drwxr-xr-x  11 root  root   374 Feb 13 23:43 config
    11.   -rw-r–r–   1 root  root   153 Feb 13 23:43 config.ru
    12.   drwxr-xr-x   3 root  root   102 Feb 13 23:43 db
    13.   -rw-r–r–   1 user  staff   161 Feb 13 23:35 docker-compose.yml
    14.   drwxr-xr-x   4 root  root   136 Feb 13 23:43 lib
    15.   drwxr-xr-x   3 root  root   102 Feb 13 23:43 log
    16.   drwxr-xr-x   7 root  root   238 Feb 13 23:43 public
    17.   drwxr-xr-x   9 root  root   306 Feb 13 23:43 test
    18.   drwxr-xr-x   3 root  root   102 Feb 13 23:43 tmp
    19.   drwxr-xr-x   3 root  root   102 Feb 13 23:43 vendor

    如果这个时候或之后编辑了Gemfile,需要重新构建镜像。

    1. docker-compose build

    连接数据库

    使用如何内容替换config/database.yml文件:

    1. development: &default
    2.   adapter: postgresql
    3.   encoding: unicode
    4.   database: myapp_development
    5.   pool: 5
    6.   username: postgres
    7.   password:
    8.   host: db
    9.  
    10. test:
    11.   <<: *default
    12.   database: myapp_test

    开始启动app:

    1. docker-compose up

    如果一切正常,将会看到PostgrepSQL的输出,然后再过几秒钟,将看到

    1. myapp_web_1 | [2014-01-17 17:16:29] INFO  WEBrick 1.3.1
    2. myapp_web_1 | [2014-01-17 17:16:29] INFO  ruby 2.2.0 (2014-12-25) [x86_64-linux-gnu]
    3. myapp_web_1 | [2014-01-17 17:16:29] INFO  WEBrick::HTTPServer#start: pid=1 port=3000

    最后,在另一个终端创建一个数据库:

    1. docker-compose run web rails db:create

    现在app已经运行在主机的3000端口。
    虚拟化技术

    快速入门: Compose和Django

    这个快速入门指南将演示如何使用docker compose来配置和运行一个简单的Django/PostgrepSQL app。

    定义项目组件

    需要为这个项目创建一个Dockerfile,一个Python依赖文件和一个docker-compose.yml文件。
    1.创建一个空的项目目录。
    可以以容易记忆的名称命名项目。这个目录是你的应用程序镜像的上下文。此目录应该只包含用来构建镜像的资源。
    2.在项目目录中创建一个新的Dockerfile文件。
    Dockerfile通过一个或多个构建命令来定义应用程序镜像内容。一旦构建完成,可以在容器运行这个镜像。
    3.添加如下内容到Dockerfile文件。

    1. FROM python:2.7
    2.  ENV PYTHONUNBUFFERED 1
    3.  RUN mkdir /code
    4.  WORKDIR /code
    5.  ADD requirements.txt /code/
    6.  RUN pip install -r requirements.txt
    7.  ADD . /code/

    这个Dockerfile从一个Python 2.7 base镜像开始构建新镜像。然后添加了一个新的code目录到此镜像。最后安装定义在requirements.txt文件的python依赖。
    4.保存并关闭Dockerfile。
    5.在项目目录创建requirements.txt文件。
    在Dockerfile中的RUN pip install -r requirements.txt命令需要用到这个文件。
    6.添加如下内容到requirements.txt.

    1. Django
    2.  psycopg2

    7.保存并关闭requirements.txt文件。
    8.在项目目录中创建一个docker-compose.yml文件。
    这个docker-compose.yml文件描述组成你的app的服务。在这个示例中那么服务是web server和database。这个compose文件也描述了这些服务使用哪个docker镜像,它们如何链接到一起以及它们可能需要挂载到容器内的数据卷。最后这个docker-compose.yml文件描述这些服务暴露了哪个端口。
    9.添加如何内容到docker-compose.yml文件。

    1. version: ‘2’
    2.  services:
    3.    db:
    4.      image: postgres
    5.    web:
    6.      build: .
    7.      command: python manage.py runserver 0.0.0.0:8000
    8.      volumes:
    9.        – .:/code
    10.      ports:
    11.        – "8000:8000"
    12.      depends_on:
    13.        – db

    这个文件定义了两个服务:db服务和web服务。
    10.保存并关闭docker-compose.yml文件。

    创建一个Django项目

    在本步骤中,我们通过构建在上一步骤中定义的镜像来创建一个Django项目。
    1.切换到项目目录的根目录。
    2.使用docker-compose命令创建一个Django项目。

    1. docker-compose run web django-admin.py startproject composeexample .

    指示compose使用了web服务的镜像和配置文件在容器中运行django-admin.py start project composeexample命令。由于web镜像还不存在,compose就按照在docker-compose.yml中的build: .行定义的在当前目录构建镜像。
    一旦web服务镜像构建完成,compose就运行它并在容器内执行django-admin.py startproject命令。这个命令创建了Django项目使用到的一系列文件和目录。
    3.当docker-compose命令完成后,列出项目的内容。

    1. $ ls -l
    2.  drwxr-xr-x 2 root   root   composeexample
    3.  -rw-rw-r– 1 user   user   docker-compose.yml
    4.  -rw-rw-r– 1 user   user   Dockerfile
    5.  -rwxr-xr-x 1 root   root   manage.py
    6.  -rw-rw-r– 1 user   user   requirements.txt

    如果是在Linux运行的docker,django-admin文件所有者应该是root。这是因为容器以root用户运行。更改这个新文件的所有者。

    1. sudo chown -R $USER:$USER .

    如果在Mac或Windows运行的Docker,你应该已经是这些文件的所有者了,包括那些由django-admin生成的文件。

    1. $ ls -l
    2.     total 32
    3.     -rw-r–r–  1 user  staff  145 Feb 13 23:00 Dockerfile
    4.     drwxr-xr-x  6 user  staff  204 Feb 13 23:07 composeexample
    5.     -rw-r–r–  1 user  staff  159 Feb 13 23:02 docker-compose.yml
    6.     -rwxr-xr-x  1 user  staff  257 Feb 13 23:07 manage.py
    7.     -rw-r–r–  1 user  staff   16 Feb 13 23:01 requirements.txt

    连接数据库

    在本步骤,我们来设置Django数据库的连接。
    1.在项目目录中,编辑composeexample/settings.py文件。
    2.使用如下行替换DATABASES = …

    1. DATABASES = {
    2.      ‘default’: {
    3.          ‘ENGINE’: ‘django.db.backends.postgresql’,
    4.          ‘NAME’: ‘postgres’,
    5.          ‘USER’: ‘postgres’,
    6.          ‘HOST’: ‘db’,
    7.          ‘PORT’: 5432,
    8.      }
    9.  }

    这些设置取决于在docker-compose.yml指定的postgres docker镜像。
    3.保存并关闭文件。
    4.执行docker-compose up命令。

    1. $ docker-compose up
    2.  Starting composepractice_db_1…
    3.  Starting composepractice_web_1…
    4.  Attaching to composepractice_db_1, composepractice_web_1
    5.  …
    6.  db_1  | PostgreSQL init process complete; ready for start up.
    7.  …
    8.  db_1  | LOG:  database system is ready to accept connections
    9.  db_1  | LOG:  autovacuum launcher started
    10.  ..
    11.  web_1 | Django version 1.8.4, using settings ‘composeexample.settings’
    12.  web_1 | Starting development server at http://0.0.0.0:8000/
    13.  web_1 | Quit the server with CONTROL-C.

    在这时候,Django app已经运行在docker主机上的8000端口。
    虚拟化技术

    Docker Compose入门学习

    在本文我们来学习使用docker compose来构建一个简单的Python web应用程序。这个应用程序使用的是Flask框架并在Redis维护一个点击计数器。虽然这个示例使用到了Python,不过即使你不熟悉Python也可以很容易理解这些操作。

    第一步:配置

    1.创建一个项目目录:

    1. $ mkdir composetest
    2. $ cd composetest

    2.在项目目录中创建一个app.py文件并复制下面的内容到这个文件:

    1. from flask import Flask
    2. from redis import Redis
    3.  
    4. app = Flask(__name__)
    5. redis = Redis(host=’redis’, port=6379)
    6.  
    7. @app.route(‘/’)
    8. def hello():
    9.     count = redis.incr(‘hits’)
    10.     return ‘Hello World! I have been seen {} times.n’.format(count)
    11.  
    12. if __name__ == "__main__":
    13.     app.run(host="0.0.0.0", debug=True)

    3.在项目目录创建另一个文件requirements.txt并复制下面这些内容:

    1. flask
    2. redis

    这个文件定义了应用程序的依赖。

    第二步:创建一个Dockerfile

    在这个步骤中,我们创建一个Dockerfile用来构建docker镜像。这个镜像包含了Python应用程序所需的所有依赖,包含Python。

    在项目目录中,创建一个Dockerfile文件并复制如下内容:

    1. FROM python:3.4-alpine
    2. ADD . /code
    3. WORKDIR /code
    4. RUN pip install -r requirements.txt
    5. CMD ["python", "app.py"]

    这个文件解释如下:

  • 从Python 3.4镜像开始构建镜像
  • 添加当前的目录到镜像中的/code目录
  • 设置工作目录为/code
  • 安装Python依赖
  • 设置容器的默认命令为python app.py
  • 第三步:在compose文件中定义服务

    在项目目录中创建docker-compose.yml文件并复制如下内容:

    1. version: ‘2’
    2. services:
    3.   web:
    4.     build: .
    5.     ports:
    6.      – "5000:5000"
    7.     volumes:
    8.      – .:/code
    9.   redis:
    10.     image: "redis:alpine"

    compose文件定义了两个服务,web和redis。web服务部分介绍如下:

  • 使用了一个从当前目录的Dockerfile构建的镜像。
  • 映射容器的5000端口到主机的5000端口。
  • 挂载主机上的项目目录到容器内的/code目录,这样更新代码时就不需要重建镜像了。
  • redis服务使用了从docker hub registry拉取的公共Redis镜像。

    第四步:使用compose构建和运行你的app

    1.从项目目录,启动你的应用程序。

    1. $ docker-compose up
    2.  Pulling image redis…
    3.  Building web…
    4.  Starting composetest_redis_1…
    5.  Starting composetest_web_1…
    6.  redis_1 | [8] 02 Jan 18:43:35.576 # Server started, Redis version 2.8.3
    7.  web_1   |  * Running on http://0.0.0.0:5000/
    8.  web_1   |  * Restarting with stat

    compose拉取一个redis镜像,为你的代码构建了一个镜像并启动你所定义的服务。

    2.在浏览器键入http://0.0.0.0:5000/来查看你的应用程序运行情况。
    3.刷新页面。数字应该会递增了。

    第五步:更新应用程序

    因为使用了数据卷把应用程序代码挂载到了容器里,可以对代码进行更新,然后就会马上看到更新了,而不需要重建镜像。
    1.更新app.py并保存。例如:

    1. return ‘Hello from Docker! I have been seen {} times.n’.format(count)

    2.在浏览器中刷新app。应该能看到更新了。

    第六步:尝试一些其它命令

    如果想让你的服务在后台运行,传递-d参数到docker-compose up并使用docker-compose ps查看现在运行的是什么。

    1. $ docker-compose up -d
    2. Starting composetest_redis_1…
    3. Starting composetest_web_1…
    4.  
    5. $ docker-compose ps
    6. Name                 Command            State       Ports
    7. ——————————————————————-
    8. composetest_redis_1   /usr/local/bin/run         Up
    9. composetest_web_1     /bin/sh -c python app.py   Up      5000->5000/tcp

    docker-compose run命令允许你对你的服务运行一次性的命令。例如,查看web服务有哪些可用的环境变量:

    1. $ docker-compose run web env

    通过docker-compose –help可以查看其它可用的命令。

    如果使用了docker-compose up -d启动应用,当不需要时可能要停止服务:

    1. $ docker-compose stop

    使用down命令可以关掉所有,删除整个容器。传递–volume也会删除由redis容器使用的数据卷:

    1. $ docker-compose down –volumes

    安装Docker Compose

    可以在macOS,Windows和64-bit Linux运行compose。下面介绍如何安装它。
    1.安装Docker Engine:
    这里不再介绍,参考官方文档

  • macOS安装
  • Windows安装
  • Ubuntu安装
  • 其它系统安装
  • 2.如果安装的是Docker Toolbox,它包括了Engine和Compose,所以Mac和Windows用户在这里就安装完成了。其它用户继续。
    3.到https://github.com/docker/compose/releases
    4.按照上面页面的介绍,执行curl命令。
    如下命令下载compose:

    1. $ curl -L "https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

    5.增加执行权限

    1. chmod +x /usr/local/bin/docker-compose

    6.可选地,为bash和zsh shell安装command completion
    7.测试安装

    1. $ docker-compose –version
    2.  docker-compose version: 1.9.0

    其它安装选项

    使用pip安装

    可以使用pip从pypi安装compose。如果使用pip安装,推荐使用virtualenv,因此许多系统的python系统包与docker-compose的依赖冲突。

    1. pip install docker-compose

    注意:需要pip version 6.0或以上版本。

    使用容器安装

    compose也可以运行在容器内,使用一个小的bash脚本。

    1. $ curl -L https://github.com/docker/compose/releases/download/1.9.0/run.sh > /usr/local/bin/docker-compose
    2. $ chmod +x /usr/local/bin/docker-compose

    Docker Compose概述

    Compose是用来定义和运行多个容器docker应用程序的工具。可以使用一个compose文件来配置你的应用程序服务。然后使用一个命令根据配置文件来创建和启动所有的服务。

    Compose非常适合用于开发,测试和临时环境,也包括CI工作流。

    使用compose就三步。
    1.使用Dockerfile定义应用程序的环境,以便可以在任何地方重建环境。
    2.在docker-compose.yml定义服务构建你的应用程序,以便它们能在一个隔离的环境一起运行。
    3.最后,执行docker-compose up然后compose会启动和运行整个app。

    一个docker-compose.yml类似如下:

    1. version: ‘2’
    2. services:
    3.   web:
    4.     build: .
    5.     ports:
    6.     – "5000:5000"
    7.     volumes:
    8.     – .:/code
    9.     – logvolume01:/var/log
    10.     links:
    11.     – redis
    12.   redis:
    13.     image: redis
    14. volumes:
    15.   logvolume01: {}

    compose提供了管理应用程序整个生命周期的命令:

  • 启动,停止和重建服务
  • 查看运行中服务的状态
  • 输出运行中服务的日志
  • 在服务上运行一次性命令
  • 功能

    单台主机多个隔离环境

    compose使用一个项目名称相互隔离环境。可以在几个不同的上下文使用这个项目名称:

  • 在一个开发主机创建单个环境的多个副本(例如,你想为一个项目中的每个功能分支运行一个稳定的副本)
  • 在CI服务器上,为了使构建不会相互干扰,可以将项目名称设置为唯一的内部版本号
  • 在共享主机或开发主机上,为了避免不同的可能使用相同的服务名称的项目互相干扰。
  • 默认项目名称是项目目录的basename。可以通过使用-p命令行选项或COMPOSE_PROJECT_NAME环境变量设置一个自定义项目名称。

    容器创建时保留数据卷数据

    compose保留用于服务的所有数据卷。当执行docker-compose up时,如果找到先前用到数据卷的容器,就把数据卷从旧的容器复制到新的容器。这样确保了你保存到数据卷的数据不会丢失。

    只重建有更新的容器

    compose缓存用于创建容器的配置。当重启一个没有更新的服务时,compose重用现有的容器。重用容器意味着你可以快速改变你的环境。

    compose支持在compose文件中使用变量。可以使用这些变量为不同的环境或不同的用户自定义组件。

    可以使用extends字段或通过创建多个compose文件扩展你的compose文件。

    常见用例

    compose可以以许多不同的方式使用。一些常见的用例如下:

    开发环境

    当正在开发一个软件时,能够在一个隔离的环境运行应用程序并与之交互很重要。compose命令行工具可以用来创建这样的环境并与之交互。

    compose文件提供了一个方法来记录和配置所有的应用程序的服务依赖(数据库,队列,缓存,web服务API等)。使用这个compose命令行工具可以为每个依赖创建和启动一个或多个容器。

    总之,这些功能为开发人员提供了一个方便的方法来开始项目。compose把很多页的开发人员入门指南减小到单个机器可读的compose文件和一些命令。

    自动测试环境

    持续部署或持续集成的一个重要部分是自动测试套件。自动端到端测试依赖运行测试的环境。compose为你的测试套件提供了一个方便的方法来创建和销毁隔离的测试环境。通过在一个compose文件中定义完整的环境,只需要几个命令就可以创建和销毁这些环境。

    1. $ docker-compose up -d
    2. $ ./run_tests
    3. $ docker-compose down

    单主机部署

    compose传统上专注在开发和测试工作流上,不过目前每次发布compose都在使它能够在生产环境在使用有所进展。可以使用compose来部署到一个远程的docker engine。