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/