Compose 是用于配置和运行多个 Docker 容器的工具。经过Compose,你可使用 YAML 文件来配置应用程序,而后使用 docker-compose
命令,就能够从配置文件中建立并启动全部服务。php
说通俗点,Docker Compose 就是一个容器编排工具(固然了,容器编排工具不知这一种,事后咱们要学习的 Kubernetes 就是一种使用很普遍的容器编排工具)。好比你如今要使用 Docker 部署一套 lnmp 环境,以前的方案是分别拉取 Nginx
、MySQL
、PHP
三个镜像,而后基于这三个镜像分别启动三个容器,这期间你还得考虑数据持久化、网络互通等问题,这个过程是有点麻烦的;那么有没有什么办法能够简化这些步骤? Docker Compose 的出现解决了这个问题,经过 YAML 格式的配置文件,你能够一步到位的部署好你的 lnmp 环境,后面咱们将手动操做,以便加深理解。html
经过 Dockerfile 能够管理一个单独的容器,而经过 Docker Compose 你能够更方便的管理一组相关联的容器。前端
使用Compose基本上是一个三步的过程:node
Dockerfile
定义应用程序的环境;docker-compose.yml
中定义组成您的应用程序的服务,以便不一样的容器能够相互通讯;docker-compose up
启动并运行您的整个应用程序。 Docker Compose 的核心就是这个 YAML
文件,当你建立好这个 YAML
文件后,你能够经过 docker-compose 命令来同时管理(建立、启动、中止、删除等)一组相关联的容器。python
随着 Docker 的发展,Docker 迭代了不少个版本,那么对应的 Docker Compose 的 YAML 文件的书写格式也进行了几回升级,目前最新版为 3.7,支持 Docker 18.06.0 以上的版本,也是咱们用的比较多的格式版本。mysql
YAML 文件书写格式能够参考此连接。linux
Docker Compose 的 YAML
文件一般由三大部分组成的(固然还有其余模块),分别是:nginx
HOST:CONTAINER
) 或加上访问模式 (HOST:CONTAINER:ro
)。docker run -v HOST:CONTAINER
若是未指定 “rw
” 或 “ro
”,则默认为 ”rw
“,即 ”read-write
“ 模式——”docker run -v HOST:CONTAINER:rw
“,若是你但愿挂载文件为只读,则可使用 ”ro
“ 选项,即 ”docker run -v HOST:CONTAINER:ro
“
Services 很像 docker container create
;一样地,Networks
和 Volumes
相似于docker network create
和docker volume create
。git
不一样平台安装方法不一样,若是你是 Mac 平台,那么你安装 Docker 时,就已经安装好了 docker-compose 工具;下面以经常使用的 CentOS 为例,介绍安装 docker-compose 的过程,其余平台安装方法参考 https://docs.docker.com/compose/install/github
Docker Compose 是使用 python 编写的,你可使用 pip 的方式安装;这种安装方式相比于下面另外一种安装方式要快一点,国内服务器可使用这种方式安装。
# 安装epel和pip以及python-devel $ sudo yum -y install epel-release $ sudo yum -y install python-pip python-devel # 经过pip安装 docker-compose $ sudo pip install docker-compose --ignore-installed requests
国内用户访问 github.com
巨慢,能够用pip的方式安装
# 下载 docker-compose 工具,并指定下载路径 $ sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 赋予可执行权限 $ sudo chmod +x /usr/local/bin/docker-compose
安装完成后你可使用 docker-compose --help
命令来查看 docker-compose
命令的使用帮助,看不懂不要紧,后期使用此命令时天然会理解这些参数的意义。
$ sudo docker-compose --help Define and run multi-container applications with Docker. Usage: docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...] docker-compose -h|--help Options: -f, --file FILE Specify an alternate compose file (default: docker-compose.yml) -p, --project-name NAME Specify an alternate project name (default: directory name) --verbose Show more output --log-level LEVEL Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) --no-ansi Do not print ANSI control characters -v, --version Print version and exit -H, --host HOST Daemon socket to connect to --tls Use TLS; implied by --tlsverify --tlscacert CA_PATH Trust certs signed only by this CA --tlscert CLIENT_CERT_PATH Path to TLS certificate file --tlskey TLS_KEY_PATH Path to TLS key file --tlsverify Use TLS and verify the remote --skip-hostname-check Don't check the daemon's hostname against the name specified in the client certificate --project-directory PATH Specify an alternate working directory (default: the path of the Compose file) --compatibility If set, Compose will attempt to convert keys in v3 files to their non-Swarm equivalent --env-file PATH Specify an alternate environment file Commands: build Build or rebuild services bundle Generate a Docker bundle from the Compose file config Validate and view the Compose file create Create services down Stop and remove containers, networks, images, and volumes events Receive real time events from containers exec Execute a command in a running container help Get help on a command images List images kill Kill containers logs View output from containers pause Pause services port Print the public port for a port binding ps List containers pull Pull service images push Push service images restart Restart services rm Remove stopped containers run Run a one-off command scale Set number of containers for a service start Start services stop Stop services top Display the running processes unpause Unpause services up Create and start containers version Show the Docker-Compose version information
在存在 docker-compose.yml 的目录下使用 docker-compose up
命令,能够直接建立并启动配置文件中的容器;通常状况下,docker-compose.ylm 文件与项目文件放在同一个目录,此目录名称为默认的项目名称,固然你也能够在 docker-compose up
的时候加上 -p
参数来自定义项目名称。
如下示例来自 Wordpress,YAML 格式不了解的,建议花二分钟看一下 此连接。如下示例中你能够看到一些 ”key“ ,好比 version、services、wordpress、image、restart 等,你能够在 这里 找到这些 ”key“ 的具体意义,若是你对 docker 有必定的了解的话,下面这个示例文件内的 ”key“ 你应该是能够看得明白的。
version: "3.7" services: wordpress: image: wordpress:latest restart: always ports: - 8080:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: userwp WORDPRESS_DB_PASSWORD: pwdwp WORDPRESS_DB_NAME: wordpress volumes: - wordpress:/var/www/html networks: - db-net - web-net db: image: mysql:8.0.18 command: --default-authentication-plugin=mysql_native_password restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: wordpress MYSQL_USER: userwp MYSQL_PASSWORD: pwdwp volumes: - mysql8_db:/var/lib/mysql networks: - db-net volumes: mysql8_db: wordpress: networks: web-net: db-net:
解释一下上面这个配置文件,docker-compose.yml 配置文件内部结构由三部分组成:
你能够这样理解,Volumes 和 Networks 都属于容器(Services)的一部分,或者说容器(Services)调用 Volumes 和 Networks 标签声明的 volumes 和 networks,因此,调用的 volumes 和 networks 的名称须要与声明的名称相同,画了个简单的图,你能够对照代码看一下。
以上配置文件建立好之后,咱们即可以经过 docker-compose
命令来进行一番体验了。
$ sudo pwd /docker/myblog # Create and start containers, -d 后台运行 $ sudo docker-compose up -d Creating network "myblog_web-net" with the default driver Creating network "myblog_db-net" with the default driver Creating volume "myblog_mysql8_db" with default driver Creating volume "myblog_wordpress" with default driver Creating myblog_db_1 ... done Creating myblog_wordpress_1 ... done
实际上docker-compose create
已经不建议使用,若是你只想建立容器而不启动,官方建议使用docker-compose up --no-start
,而后再经过docker-compose start
来启动这些容器。另外注意,
docker-compose scale
这个命令已经废弃,不建议使用
执行 docker-compose --help 后能够看到 docker-compose 工具的详细用发,都是些基础的 IT 英文,我就不翻译了,请务必自行练习如下命令:
如下为官方 docker-compose.yml 示例文件
version: "3.7" services: redis: image: redis:alpine ports: - "6379" networks: - frontend deploy: replicas: 2 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure db: image: postgres:9.4 volumes: - db-data:/var/lib/postgresql/data networks: - backend deploy: placement: constraints: [node.role == manager] vote: image: dockersamples/examplevotingapp_vote:before ports: - "5000:80" networks: - frontend depends_on: - redis deploy: replicas: 2 update_config: parallelism: 2 restart_policy: condition: on-failure result: image: dockersamples/examplevotingapp_result:before ports: - "5001:80" networks: - backend depends_on: - db deploy: replicas: 1 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure worker: image: dockersamples/examplevotingapp_worker networks: - frontend - backend deploy: mode: replicated replicas: 1 labels: [APP=VOTING] restart_policy: condition: on-failure delay: 10s max_attempts: 3 window: 120s placement: constraints: [node.role == manager] visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" stop_grace_period: 1m30s volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: [node.role == manager] networks: frontend: backend: volumes: db-data:
这部分至关于 Google 翻译官方文档了,稍微整理了一下,感受不经常使用的参数我就没列出来,因此不是很全面,以为看着别扭的话你能够直接看官方文档。
容器的建立能够来自 Docker Hub 的镜像,也能够来自本地使用 Dockerfile 构建的镜像,build 即是指定容器为本地构建的 Dockerfile 文件的路径;
指定构建镜像的上下文路径:
例如 webapp 服务,指定为从上下文路径 ./dir/dockerfile 所构建的镜像:
version: "3.7" services: webapp: build: ./dir
或者,指定具体的 Dockerfile 文件:
version: "3.7" services: webapp: build: context: ./dir dockerfile: Dockerfile-alternate
构建镜像的上下文(Dockerfile 的目录),能够是相对路径(相对于 docker-compose.yml 文件的相对路径)和绝对路径。
build: context: ./dir
build: context: . dockerfile: Dockerfile-alternate
添加构建参数,这是只能在构建过程当中访问的环境变量。
前提是你须要在 Dockerfile 中指定参数,
ARG buildno ARG gitcommithash RUN echo "Build number: $buildno" RUN echo "Based on commit: $gitcommithash"
而后在 docker-compose 的 build 下指定参数,您能够传递映射或列表:
build: context: . args: buildno: 1 gitcommithash: cdc3b19
build: context: . args: - buildno=1 - gitcommithash=cdc3b19
注意:在Dockerfile中,若是在FROM指令以前指定ARG,则在FROM下的构建指令中ARG不可用。若是您须要一个参数在两个地方均可用,请在FROM指令下指定该参数。有关用法的详细信息,请参阅了解 ARGS和FROM的交互方式。
默认状况下,在构建 Docker 镜像时,Docker 使用它的构建缓存来检查它是否能够跳过Dockerfile 中的任何步骤,该 cache_from
参数告诉 docker,可用缓存的镜像是什么;若是提供的镜像和当前版本具备相同的层(以前提过层的概念),则能够得到与在同一台计算机上构建镜像时以相同层构建出更快的速度。
build: context: . cache_from: - alpine:latest - corp/web_app:3.14
格式有下面两种:
build: context: . labels: com.example.description: "Accounting webapp" com.example.department: "Finance" com.example.label-with-empty-value: ""
build: context: . labels: - "com.example.description=Accounting webapp" - "com.example.department=Finance" - "com.example.label-with-empty-value"
根据Dockerfile中的定义构建指定的阶段。 有关详细信息,请参见以前提过的多阶段构建。
build: context: . target: prod
覆盖容器启动时的默认命令
command: bundle exec thin -p 3000
command: ["bundle", "exec", "thin", "-p", "3000"]
指定自定义容器名称,而不是生成的默认名称。
container_name: my-web-container
因为Docker容器名称必须惟一,所以若是您指定了自定义名称,则不能将服务扩展到1个以上的容器。
指定与服务的部署和运行有关的配置,只在 swarm 模式下才会有用,会被 docker-compose up
和 docker-compose run
忽略.
version: "3.7" services: redis: image: redis:alpine deploy: replicas: 6 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure
两种模式:
endpoint_mode: vip
- Docker为服务分配了一个虚拟IP(VIP),该虚拟IP充当客户端访问网络上服务的前端。 Docker在客户端和服务的可用工做节点之间路由请求,而无需客户端知道有多少节点正在参与服务或其IP地址或端口。 (这是默认设置。)endpoint_mode: dnsrr
- DNS轮询(DNSRR)服务发现不使用单个虚拟IP。 Docker设置服务的DNS条目,以便对服务名称的DNS查询返回IP地址列表,而且客户端直接链接到其中之一。在想要使用本身的负载平衡器或混合Windows和Linux应用程序的状况下,DNS轮询颇有用。version: "3.7" services: wordpress: image: wordpress ports: - "8080:80" networks: - overlay deploy: mode: replicated replicas: 2 endpoint_mode: vip mysql: image: mysql volumes: - db-data:/var/lib/mysql/data networks: - overlay deploy: mode: replicated replicas: 2 endpoint_mode: dnsrr volumes: db-data: networks: overlay:
指定服务标签。这些标签仅在服务上设置,而不在服务的任何容器上设置。
version: "3.7" services: web: image: web deploy: labels: com.example.description: "This label will appear on the web service"
global
(每一个群集节点一个容器) orreplicated
(指定数量的容器). 默认为 replicated
.
version: "3.7" services: worker: image: dockersamples/examplevotingapp_worker deploy: mode: global
若是选择了 replicated 模式,replicas 用来指定运行的容器数量
version: "3.7" services: worker: image: dockersamples/examplevotingapp_worker networks: - frontend - backend deploy: mode: replicated replicas: 6
如下示例中,redis服务被限制为使用不超过50M的内存和0.50(单核的50%)的可用处理(CPU),并有最低20M的内存和0.25的CPU资源使用。
version: "3.7" services: redis: image: redis:alpine deploy: resources: limits: cpus: '0.50' memory: 50M reservations: cpus: '0.25' memory: 20M
配置如何在退出容器时从新启动容器。
version: "3.7" services: redis: image: redis:alpine deploy: restart_policy: condition: on-failure delay: 5s max_attempts: 3 window: 120s
配置在更新失败的状况下应如何回滚服务。
配置应如何更新服务,对于配置滚动更新颇有用。
version: "3.7" services: vote: image: dockersamples/examplevotingapp_vote:before depends_on: - redis deploy: replicas: 2 update_config: parallelism: 2 delay: 10s order: stop-first
指定设备映射列表。
devices: - "/dev/ttyUSB0:/dev/ttyUSB0"
自定义 DNS 服务器,能够是单个值或列表的多个值。
dns: 8.8.8.8
dns: - 8.8.8.8 - 9.9.9.9
自定义DNS搜索域,能够是单个值或列表。
dns_search: example.com
dns_search: - dc1.example.com - dc2.example.com
覆盖容器默认入口点。
entrypoint: /code/entrypoint.sh
entrypoint: - php - -d - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so - -d - memory_limit=-1 - vendor/bin/phpunit
注意:设置入口点会覆盖全部使用 Dockerfile ENTRYPOINT 指令在服务镜像上设置的默认入口点,并清除镜像上的任何默认 CMD ,这意味着若是Dockerfile中有CMD指令,则会将其忽略。
从文件添加环境变量。能够是单个值或列表的多个值。
env_file: .env
env_file: - ./common.env - ./apps/web.env - /opt/secrets.env
.env 文件格式为 VAR=VAL
# Set Rails/Rack environment RACK_ENV=development
添加环境变量。您可使用数组或字典、任何布尔值,布尔值须要用引号引发来,以确保 YML 解析器不会将其转换为 True 或 False。
environment: RACK_ENV: development SHOW: 'true' SESSION_SECRET:
environment: - RACK_ENV=development - SHOW=true - SESSION_SECRET
若是你使用了build
选项,则在构建过程当中不会自动显示environment
中定义的变量,可使用build
的args
子选项来定义构建时环境变量。
暴露端口,但不映射到宿主机,只被链接的服务访问,仅能够指定内部端口为参数:
expose: - "3000" - "8000"
连接到在docker-compose.yml以外甚至在Compose以外启动的容器,特别是对于提供共享或公共服务的容器。
external_links: - redis_1 - project_db_1:mysql - project_db_1:postgresql
添加主机名映射,相似 docker client --add-host
。
extra_hosts: - "somehost:162.242.195.82" - "otherhost:50.31.209.229"
实如今容器内修改host /etc/hosts
文件的效果
162.242.195.82 somehost 50.31.209.229 otherhost
配置运行检查,以肯定此服务的容器是否“健康”。
healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序 interval: 1m30s # 设置检测间隔 timeout: 10s # 设置检测超时时间 retries: 3 # 设置重试次数 start_period: 40s # 启动后,多少秒开始启动检测程序
指定要从中启动容器的镜像
image: redis image: ubuntu:14.04 image: tutum/influxdb image: example-registry.com:4000/postgresql image: a4bc65fd
Services 容器标签
labels: com.example.description: "Accounting webapp" com.example.department: "Finance" com.example.label-with-empty-value: ""
labels: - "com.example.description=Accounting webapp" - "com.example.department=Finance" - "com.example.label-with-empty-value"
服务的日志记录配置。
logging: driver: syslog options: syslog-address: "tcp://192.168.0.42:123"
这个 driver
名称为服务的容器指定了日志记录驱动程序,与docker run --log-driver
选项相同,默认值为 json-file,有如下三个选项:
driver: "json-file" driver: "syslog" driver: "none"
仅在 json-file 驱动程序下,可使用如下参数,限制日志得数量和大小;当达到文件限制上限,会自动删除旧得文件。
logging: driver: json-file options: max-size: "200k" # 单个文件大小为200k max-file: "10" # 最多10个文件
syslog 驱动程序下,可使用 syslog-address 指定日志接收地址。
logging: driver: syslog options: syslog-address: "tcp://192.168.0.42:123"
设置网络模式
network_mode: "bridge" network_mode: "host" network_mode: "none" network_mode: "service:[service name]" network_mode: "container:[container name/id]"
配置容器链接的网络,引用一级 networks
下的条目 。
services: some-service: networks: - some-network - other-network
网络别名,能够指定多个别名。
version: "3.7" services: web: image: "nginx:alpine" networks: - new worker: image: "my-worker-image:latest" networks: - legacy db: image: mysql networks: new: aliases: - database - dbnet legacy: aliases: - mysql networks: new: legacy:
加入网络后,为此服务的容器指定一个静态IP地址。
一级 networks
部分中的相应网络配置必须具备ipam
块,其子网配置覆盖每一个静态地址。
version: "3.7" services: app: image: nginx:alpine networks: app_net: ipv4_address: 172.16.238.10 ipv6_address: 2001:3984:3989::10 networks: app_net: ipam: driver: default config: - subnet: "172.16.238.0/24" - subnet: "2001:3984:3989::/64"
使用宿主port:容器port(HOST:CONTAINER)
格式或者仅仅指定容器的端口(宿主将会随机选择端口)均可以。
ports: - "3000" - "3000-3005" - "8000:8000" - "9090-9091:8080-8081" - "49100:22" - "127.0.0.1:8001:8001" - "127.0.0.1:5000-5010:5000-5010" - "6060:6060/udp"
长语法:长语法容许配置其余不能以短格式表示的字段。
target
: 容器内的端口published
: 公开暴露的端口protocol
: 端口协议 (tcp
orudp
)mode
:host
用于在每一个节点上发布主机端口, 或ingress
用于群模式端口以实现负载平衡ports: - target: 80 published: 8080 protocol: tcp mode: host
容器重启规则
no
:是默认的重启策略,在任何状况下都不会重启容器。always
:容器老是从新启动。on-failure
:在容器非正常退出时(退出状态非0),才会重启容器。unless-stopped
:在容器退出时老是重启容器,可是不考虑在Docker守护进程启动时就已经中止了的容器restart: "no" restart: always restart: on-failure restart: unless-stopped
用来存储敏感文件,如密码等。
短语法:如下示例使用短语法向redis
服务授予对my_secret
和my_other_secret
机密的访问权限。 将my_secret
的值设置为文件./my_secret.txt
的内容,并将my_other_secret
定义为外部资源,这意味着它已经在Docker中定义,能够经过运行docker secret create
命令或其余堆栈进行定义 部署。 若是外部secrets不存在,则堆栈部署将失败,并显示“未找到secrets”错误。
version: "3.7" services: redis: image: redis:latest deploy: replicas: 1 secrets: - my_secret - my_other_secret secrets: my_secret: file: ./my_secret.txt my_other_secret: external: true
修改容器的概要标签
security-opt: - label:user:USER # 设置容器的用户标签 - label:role:ROLE # 设置容器的角色标签 - label:type:TYPE # 设置容器的安全策略标签 - label:level:LEVEL # 设置容器的安全等级标签
在发送 SIGKILL 以前指定stop_signal
,若是试图中止容器(若是它没有处理 SIGTERM(或指定的任何中止信号)),则须要等待的时间,默认状况下,stop 在发送SIGKILL以前等待10秒钟容器退出
stop_grace_period: 1s # 等待 1 秒 stop_grace_period: 1m30s # 等待 1 分 30 秒
设置中止容器的替代信号,默认状况下使用 SIGTERM ;如下示例,使用 SIGUSR1 替代信号 SIGTERM 来中止容器。
stop_signal: SIGUSR1
要在容器中设置的内核参数
sysctls: net.core.somaxconn: 1024 net.ipv4.tcp_syncookies: 0
sysctls: - net.core.somaxconn=1024 - net.ipv4.tcp_syncookies=0
挂载临时文件目录到容器内部
tmpfs: /run
tmpfs: - /run - /tmp
覆盖容器默认的 ulimit
ulimits: nproc: 65535 nofile: soft: 20000 hard: 40000
将主机的数据卷或着文件挂载到容器里。
挂载一个目录或者一个已存在的数据卷容器,能够直接使用HOST:CONTAINER
这样的格式,或者使用HOST:CONTAINER:ro
这样的格式,后者对于容器来讲,数据卷是只读的,这样能够有效保护宿主机的文件系统
version: "3.7" services: web: image: nginx:alpine volumes: - type: volume source: mydata target: /data volume: nocopy: true - type: bind source: ./static target: /opt/app/static db: image: postgres:latest volumes: - "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock" - "dbdata:/var/lib/postgresql/data" volumes: mydata: dbdata:
数据卷的格式以下多种形式:
volumes: # 仅指定一个路径时,Docker 会自动建立一个数据卷(此路径是容器内部路径) - /var/lib/mysql # 使用绝对路径挂载数据卷 - /opt/data:/var/lib/mysql # 以 Compose 配置文件为中心的相对路径做为数据卷挂载到容器 - ./cache:/tmp/cache # 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/) - ~/configs:/etc/configs/:ro # 挂载数据卷。 - datavolume:/var/lib/mysql
每一个值都只对应一个值,相似于其docker run的参数选项
user: postgresql working_dir: /code domainname: foo.com hostname: foo ipc: host privileged: true read_only: true shm_size: 64M stdin_open: true tty: true
容许您建立命名卷(不依赖volumes_from
),这些卷能够在多个服务中重用,而且可使用docker命令行或API。
如下是两种服务设置的示例,其中 db
的数据目录做为卷与另外一服务共享,以即可以按期备份它:
version: "3.7" services: db: image: db volumes: - data-volume:/var/lib/db backup: image: backup-service volumes: - data-volume:/var/lib/backup/data volumes: data-volume:
一级volumes
下的条目能够为空,在这种状况下,它使用引擎配置的默认驱动程序(在大多数状况下,这是 local
驱动程序)。
volume 的标签
labels: com.example.description: "Database volume" com.example.department: "IT/Ops" com.example.label-with-empty-value: ""
labels: - "com.example.description=Database volume" - "com.example.department=IT/Ops" - "com.example.label-with-empty-value"
一级networks
,容许您指定要建立的网络。
指定该网络应使用哪一个驱动程序。
默认驱动程序取决于您使用的Docker引擎的配置方式,可是在大多数状况下,它bridge
位于单个主机和overlay
Swarm上。
Docker 默认的网络接入方式
该overlay
驱动程序建立一个跨多个节点命名的网络 群。
overlay
群体模式构建和使用带有服务的网络的有效示例 ,请参阅《覆盖网络和服务发现》的Docker Labs教程 。 使用主机的网络,或者不使用网络。等同于 docker run --network=host
或docker run --network=none
,仅在使用docker stack
命令时使用,若是使用docker-compose
命令,请改用network_mode。
IP地址管理,有几个属性,每个属性都是可选的:
driver
:自定义IPAM驱动程序,而不使用默认的config
:有零个或多个配置块的列表,每一个包含任何如下项:
subnet
:子网CIDR格式表示一个网段一个完整的例子:
ipam: driver: default config: - subnet: 172.28.0.0/16
网络标签
labels: com.example.description: "Financial transaction network" com.example.department: "Finance" com.example.label-with-empty-value: ""
labels: - "com.example.description=Financial transaction network" - "com.example.department=Finance" - "com.example.label-with-empty-value"
自定义网络名称
version: "3.7" networks: network1: name: my-app-net
它也能够与external
配合使用:
version: "3.7" networks: network1: external: true name: my-app-net
一级configs
声明定义或引用能够授予此项目中的服务的配置。配置的来源是file
或external
。
file
:使用指定路径中的文件内容建立配置external
:若是设置为true,则表示此配置已建立,Docker不会尝试建立它;若是它不存在,则会发生 config not found
错误name
:Docker中配置对象的名称,此字段可引用包含特殊字符的配置。 在如下示例中,部署项目时建立了 my_first_config
(as<stack_name> _my_first_config
),而且Docker中已经存在my_second_config
。
configs: my_first_config: file: ./config_data my_second_config: external: true
外部配置的另外一个方式是Docker中的config名称与服务中存在的名称不一样时,如下示例修改了前一个示例,以使用名为 redis_config
的外部配置。
configs: my_first_config: file: ./config_data my_second_config: external: name: redis_config
配置好一级 configs
后仍然须要 将配置访问权限授予 项目中的每一个服务。
顶级secrets
声明定义或引用的secrets,可在这个项目被授予服务。secrets 来源于file
或external
。
file
:使用指定路径中的文件内容external
:若是设置为true,则表示这个 secret 已经建立指定,Docker 不会尝试建立它;若是它不存在,将报错secret not found
name
:Docker中 secret 的名称 在下面例子中,my_first_secret
被建立为<stack_name>_my_first_secret
当堆栈被部署,并my_second_secret
在多克尔已经存在。
在此示例中部署项目时,将my_first_secret
建立为<stack_name> _my_first_secret
,而且Docker中已经存在my_second_secret
。
secrets: my_first_secret: file: ./secret_data my_second_secret: external: true
外部机密的另外一个方式是Docker中的secret名称与服务中存在的名称不一样时,如下示例修改了前一个示例,以使用名为redis_secret
的外部secret。
# V3.5及以上 secrets: my_first_secret: file: ./secret_data my_second_secret: external: true name: redis_secret
接下来咱们将使用 Docker Compose
构建一个简单Python Web应用程序,该应用程序使用Flask框架,并在Redis中维护一个计数器程序(每访问一次web应该,就给输出的访问次数+1)。尽管该示例使用Python,但并非说就须要你掌握 Python。
首先须要建立项目目录,以及准备 Python 程序代码,操做以下:
$ mkdir composetest $ cd composetest
程序 app.py
的代码以下:
import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) def get_hit_count(): retries = 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route('/') def hello(): count = get_hit_count() return 'Hello World! I have been seen {} times.\n'.format(count)
在 app.py
目录下建立名为 requirements.txt
的文件,文件内容以下
flask redis
须要编写一个构建 Docker镜像 的 Dockerfile
,该镜像包含 Python 应用程序以及此演示项目所需的全部依赖关系;具体的 Dockerfile
文件内容以下:
FROM python:3.7-alpine WORKDIR /code ENV FLASK_APP app.py ENV FLASK_RUN_HOST 0.0.0.0 RUN apk add --no-cache gcc musl-dev linux-headers COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . CMD ["flask", "run"]
以上操做内容说明:
/code
。flask
命令使用的环境变量。requirements.txt
并安装Python依赖项。flask run
。version: '3' services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"
使用命令 docker-compose up
启动这个项目,你将在执行命令后的输出内容的最后一行看到以下信息:
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
接下来,经过curl
命令来测试项目部署效果,此操做须要从新打开一个 shell 窗口,经过执行以下命令,来检查部署结果(你将在执行 docker-compose up
命令的窗口看到一些访问日志):
$ curl http://0.0.0.0:5000 Hello World! I have been seen 1 times. $ curl http://0.0.0.0:5000 Hello World! I have been seen 2 times. $ curl http://0.0.0.0:5000 Hello World! I have been seen 3 times.
你能够分别执行以下命令来查看此项目部署后产生了哪些镜像,启动了哪些容器,以及网络、数据卷的状况
$ docker image ls $ docker ps $ docker network ls $ docker volume ls
docker-compose.yaml 文件的编写须要多练习才能熟悉,熟悉不了也不要紧,但最起码得了解个大概,知道都能定义哪些标签就行,遇到问题能够快速查阅官方文档或者我的笔记。
若是须要进一步了解 Docker Compose 的更多内容,建议去官方看文档;说白了,它就是个用于配置和运行多个 Docker 容器的工具,可是若是后期业务拆分模块较多,或者说微服务拆分较多的模块,就须要部署更多的容器,并且还得考虑负载均衡、故障自愈、网络通讯、数据存储、容器管理等等问题,这时候 Docker Compose 就显得有点力不从心了;
因此,接下来的几个章节咱们要学习更专业的容器编排管理工具,如 Mesos
(Apache下的,诞生于2013年)、kubernetes
(Google家的,诞生于2014年6月)、Swarm
(Docker自家的,2016年的面世),后面咱们会介绍Swarm
、kubernetes
这两个工具,另一个本身去学习了解便可。
---
参考连接:
https://docs.docker.com/compose/