docker-compose教程(安裝,使用, 快速入門)

教程基於ubuntu下最新的compose版本3 
參考: https://docs.docker.com/compose/overview/css

1.Compose介紹

Docker Compose是一個用來定義和運行復雜應用的Docker工具。一個使用Docker容器的應用,一般由多個容器組成。使用Docker Compose再也不須要使用shell腳原本啓動容器。 
Compose 經過一個配置文件來管理多個Docker容器,在配置文件中,全部的容器經過services來定義,而後使用docker-compose腳原本啓動,中止和重啓應用,和應用中的服務以及全部依賴服務的容器,很是適合組合使用多個容器進行開發的場景。node

2.Compose和Docker兼容性

compose文件格式版本 docker版本
3.4 17.09.0+
3.3 17.06.0+
3.2 17.04.0+
3.1 1.13.1+
3.0 1.13.0+
2.3 17.06.0+
2.2 1.13.0+
2.1 1.12.0+
2.0 1.10.0+
1.0 1.9.1.+
 
Docker版本變化說明

Docker從1.13.x版本開始,版本分爲企業版EE和社區版CE,版本號也改成按照時間線來發布,好比17.03就是2017年3月。python

Docker的linux發行版的軟件倉庫從之前的https://apt.dockerproject.org和https://yum.dockerproject.org變動爲目前的https://download.docker.com, 軟件包名字改成docker-ce和docker-ee。mysql


3.安裝docker

Docker的社區版(Docker Community Edition)叫作docker-ce。老版本的Docker包叫作docker或者docker-engine,若是安裝了老版本的docker得先卸載而後再安裝新版本的docker。docker的發展很是迅速,apt源的更新每每比較滯後。因此docker官網推薦的安裝方式都是下載docker安裝腳本安裝。 
卸載老舊的版本(若未安裝過可省略此步):
linux

$ sudo apt-get remove docker docker-engine docker.io
  • 1

安裝最新的docker:git

  1. $ curl -fsSL get.docker.com -o get-docker.sh
  2. $ sudo sh get-docker.sh
  • 1
  • 2

shell會提示你輸入sudo的密碼,而後開始執行最新的docker過程 
或者
github

$ curl -sSL https://get.docker.com/ | sh 
  • 1

確認Docker成功最新的docker:web

$ sudo docker run hello-world
  • 1

4.安裝docker-compose

兩種最新的docker安裝方式redis

1.從github上下載docker-compose二進制文件安裝

  • 下載最新版的docker-compose文件 
    $ sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
  • 添加可執行權限 
    $ sudo chmod +x /usr/local/bin/docker-compose
  • 測試安裝結果 
    $ docker-compose --version 
    docker-compose version 1.16.1, build 1719ceb

2.pip安裝

$ sudo pip install docker-composesql


5.docker-compose文件結構和示例

docker-compose文件結構

docker-compose.yml:

  1.  
  2. version: "3"
  3. services:
  4.  
  5. redis:
  6. image: redis:alpine
  7. ports:
  8. - "6379"
  9. networks:
  10. - frontend
  11. deploy:
  12. replicas: 2
  13. update_config:
  14. parallelism: 2
  15. delay: 10s
  16. restart_policy:
  17. condition: on-failure
  18.  
  19. db:
  20. image: postgres: 9.4
  21. volumes:
  22. - db-data:/var/lib/postgresql/data
  23. networks:
  24. - backend
  25. deploy:
  26. placement:
  27. constraints: [node.role == manager]
  28.  
  29. vote:
  30. image: dockersamples/examplevotingapp_vote:before
  31. ports:
  32. - 5000:80
  33. networks:
  34. - frontend
  35. depends_on:
  36. - redis
  37. deploy:
  38. replicas: 2
  39. update_config:
  40. parallelism: 2
  41. restart_policy:
  42. condition: on-failure
  43.  
  44. result:
  45. image: dockersamples/examplevotingapp_result:before
  46. ports:
  47. - 5001:80
  48. networks:
  49. - backend
  50. depends_on:
  51. - db
  52. deploy:
  53. replicas: 1
  54. update_config:
  55. parallelism: 2
  56. delay: 10s
  57. restart_policy:
  58. condition: on-failure
  59.  
  60. worker:
  61. image: dockersamples/examplevotingapp_worker
  62. networks:
  63. - frontend
  64. - backend
  65. deploy:
  66. mode: replicated
  67. replicas: 1
  68. labels: [APP=VOTING]
  69. restart_policy:
  70. condition: on-failure
  71. delay: 10s
  72. max_attempts: 3
  73. window: 120s
  74. placement:
  75. constraints: [node.role == manager]
  76.  
  77. visualizer:
  78. image: dockersamples/visualizer:stable
  79. ports:
  80. - "8080:8080"
  81. stop_grace_period: 1m30s
  82. volumes:
  83. - "/var/run/docker.sock:/var/run/docker.sock"
  84. deploy:
  85. placement:
  86. constraints: [node.role == manager]
  87.  
  88. networks:
  89. frontend:
  90. backend:
  91.  
  92. volumes:
  93. db-data:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

docker-compose使用示例

經過docker-compose構建一個在docker中運行的基於python flask框架的web應用。

注意:確保你已經安裝了Docker Engine和Docker Compose。 您不須要安裝Python或Redis,由於這兩個都是由Docker鏡像提供的。

Step 1: 定義python應用

  • 1 .建立工程目錄
  1. $ mkdir compose_test
  2. $ cd compose_test
  3. $ mkdir src # 源碼文件夾
  4. $ mkdir docker # docker配置文件夾
  • 1
  • 2
  • 3
  • 4

目錄結構以下: 
這裏寫圖片描述

  • 2 .在compose_test/src/目錄下建立python flask應用 compose_test/src/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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 3 .建立python 需求文件 compose_test/docker/requirements.txt
  1. flask
  2. redis
  • 1
  • 2

Step 2: 建立容器的Dockerfile文件

一個容器一個Dockerfile文件 
爲了工程目錄更加清晰,在compose_test/docker/目錄下建立compose_test/docker/web目錄

  1. $ cd docker
  2. $ mkdir web
  • 1
  • 2

在compose_test/docker/web/目錄中建立Dockerfile文件:

FROM python:3.4
  1. ADD . /docker
  2. ADD ../../src /src # ADD的源路徑應該在Dockerfile文件的上下文環境中(即Dockerfile文件所在根目錄及其子目錄下,如ADD . /src是合法的,而ADD ../../src /src不合法),此處爲了清晰的項目結構,只是展現ADD指令,實際中應該用volumes掛載
  3. WORKDIR /src
  4. RUN pip install -r /docker/requirements .txt
  5. CMD ["python", "app.py"]
  • 1
  • 1
  • 2
  • 3
  • 4
  • 5

Dockerfile文件告訴docker了以下信息:

從Python 3.4鏡像開始構建一個容器鏡像。 

複雜當前 . (即compose_test/docker)目錄到容器的/docker目錄。

複製../../src目錄(即compose_test/src) 到容器中的/src目錄(此處../../src是不合法的路徑,ADD的源路徑必須在Dockerfile文件的上下文環境中,即Dockerfile文件所在根目錄或起子目錄中,實際應該使用volumes掛載項目源文件)。 

將容器的工做目錄設置爲/src。 
安裝Python依賴關係。
將容器的默認命令設置爲python app.py。

Step 3: 定義docker-compose腳本

在compose_test/docker/目錄下建立docker-compose.yml文件,並在裏面定義服務,內容以下:

  1. version: '3'
  2. services:
  3. web:
  4. build: ./web/
  5. ports:
  6. - "5000:5000"
  7. redis:
  8. image: "redis:3.0.7"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

這個compose文件定義了兩個服務,即定義了web和redis兩個容器。 
web容器: 
* 使用當前的web目錄(compose_test/docker/web/)中的Dockerfile構建映像。 
* 將容器上的暴露端口5000映射到主機上的端口5000。 咱們使用Flask Web服務器的默認端口5000。 
redis容器: 
* redis服務使用從Docker Hub提取的官方redis鏡像3.0.7版本。

Step 4: 使用Compose構建並運行您的應用程序

在compose_test/docker/目錄下執行docker-compose.yml文件:

  1. $ docker-compose up
  2. # 如果要後臺運行: $ docker-compose up -d
  3. # 若不使用默認的docker-compose.yml 文件名:
  4. $ docker-compose -f server.yml up -d
  • 1
  • 2
  • 3
  • 4

而後在瀏覽器中輸入http://0.0.0.0:5000/查看運行的應用程序。

Step 5: 編輯compose文件以添加文件綁定掛載

上面的代碼是在構建時靜態複製到容器中的,即經過Dockerfile文件中的ADD ./src /src命令實現物理主機中的源碼複製到容器中,這樣在後續物理主機src目錄中代碼的更改不會反應到容器中。 
能夠經過volumes 關鍵字實現物理主機目錄掛載到容器中的功能(同時刪除Dockerfile中的ADD指令,不須要建立鏡像時將代碼打包進鏡像,而是經過volums動態掛載,容器和物理host共享數據卷):

  1. version: '3'
  2. services:
  3. web:
  4. build: .
  5. ports:
  6. - "5000:5000"
  7. volumes:
  8. - ../src :/src
  9. redis:
  10. image: "redis:3.0.7"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

經過volumes(卷)將主機上的項目目錄(compose_test/src)掛載到容器中的/src目錄下,容許您即時修改代碼,而無需從新構建映像。

Step 6: 從新構建和運行應用程序

使用更新的compose文件構建應用程序,而後運行它。

$ docker-compose up -d
  • 1

6.compose經常使用服務配置參考

Compose文件是一個定義服務,網絡和卷的YAML文件。 Compose文件的默認文件名爲docker-compose.yml。

**提示:您能夠對此文件使用.yml或.yaml擴展名。 他們都工做。

與docker運行同樣,默認狀況下,Dockerfile中指定的選項(例如,CMD,EXPOSE,VOLUME,ENV)都被遵照,你不須要在docker-compose.yml中再次指定它們。

同時你可使用相似Bash的$ {VARIABLE} 語法在配置值中使用環境變量,有關詳細信息,請參閱變量替換

本節包含版本3中服務定義支持的全部配置選項。

build

build 能夠指定包含構建上下文的路徑:

  1. version: '2'
  2. services:
  3. webapp:
  4. build: ./dir
  • 1
  • 2
  • 3
  • 4

或者,做爲一個對象,該對象具備上下文路徑和指定的Dockerfile文件以及args參數值:

  1. version: '2'
  2. services:
  3. webapp:
  4. build:
  5. context: ./dir
  6. dockerfile: Dockerfile-alternate
  7. args:
  8. buildno: 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

webapp服務將會經過./dir目錄下的Dockerfile-alternate文件構建容器鏡像。 
若是你同時指定image和build,則compose會經過build指定的目錄構建容器鏡像,而構建的鏡像名爲image中指定的鏡像名和標籤。

  1. build: ./dir
  2. image: webapp:tag
  • 1
  • 2

這將由./dir構建的名爲webapp和標記爲tag的鏡像。

context

包含Dockerfile文件的目錄路徑,或者是git倉庫的URL。 
當提供的值是相對路徑時,它被解釋爲相對於當前compose文件的位置。 該目錄也是發送到Docker守護程序構建鏡像的上下文。

dockerfile

備用Docker文件。Compose將使用備用文件來構建。 還必須指定構建路徑。

args

添加構建鏡像的參數,環境變量只能在構建過程當中訪問。 
首先,在Dockerfile中指定要使用的參數:

  1. ARG buildno
  2. ARG password
  3.  
  4. RUN echo "Build number: $buildno"
  5. RUN script-requiring-password.sh "$password"
  • 1
  • 2
  • 3
  • 4
  • 5

而後在args鍵下指定參數。 你能夠傳遞映射或列表:

  1. build:
  2. context: .
  3. args:
  4. buildno: 1
  5. password: secret
  6.  
  7. build:
  8. context: .
  9. args:
  10. - buildno=1
  11. - password=secret
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

** 注意:YAML布爾值(true,false,yes,no,on,off)必須用引號括起來,以便解析器將它們解釋爲字符串。

image

指定啓動容器的鏡像,能夠是鏡像倉庫/標籤或者鏡像id(或者id的前一部分)

  1. image: redis
  2. image: ubuntu:14.04
  3. image: tutum/influxdb
  4. image: example-registry.com:4000/postgresql
  5. image: a4bc65fd
  • 1
  • 2
  • 3
  • 4
  • 5

若是鏡像不存在,Compose將嘗試從官方鏡像倉庫將其pull下來,若是你還指定了build,在這種狀況下,它將使用指定的build選項構建它,並使用image指定的名字和標記對其進行標記。

container_name

指定一個自定義容器名稱,而不是生成的默認名稱。

container_name: my-web-container
  • 1

因爲Docker容器名稱必須是惟一的,所以若是指定了自定義名稱,則沒法將服務擴展到多個容器。

volumes

卷掛載路徑設置。能夠設置宿主機路徑 (HOST:CONTAINER) 或加上訪問模式 (HOST:CONTAINER:ro),掛載數據卷的默認權限是讀寫(rw),能夠經過ro指定爲只讀。 
你能夠在主機上掛載相對路徑,該路徑將相對於當前正在使用的Compose配置文件的目錄進行擴展。 相對路徑應始終以 . 或者 .. 開始。

  1. volumes:
  2. # 只需指定一個路徑,讓引擎建立一個卷
  3. - /var/lib/mysql
  4. # 指定絕對路徑映射
  5. - /opt/data:/var/lib/mysql
  6. # 相對於當前compose文件的相對路徑
  7. - ./cache:/tmp/cache
  8. # 用戶家目錄相對路徑
  9. - ~/configs:/etc/configs/:ro
  10. # 命名卷
  11. - datavolume:/var/lib/mysql
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

可是,若是要跨多個服務並重用掛載卷,請在頂級volumes關鍵字中命名掛在卷,可是並不強制,以下的示例亦有重用掛載卷的功能,可是不提倡。

  1. version: "3"
  2.  
  3. services:
  4. web1:
  5. build: ./web/
  6. volumes:
  7. - ../code:/opt/web/code
  8. web2:
  9. build: ./web/
  10. volumes:
  11. - ../code:/opt/web/code
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

** 注意:經過頂級volumes定義一個掛載卷,並從每一個服務的卷列表中引用它, 這會替換早期版本的Compose文件格式中volumes_from。

  1. version: "3"
  2.  
  3. services:
  4. db:
  5. image: db
  6. volumes:
  7. - data-volume:/var/lib/db
  8. backup:
  9. image: backup -service
  10. volumes:
  11. - data-volume:/var/lib/backup/data
  12.  
  13. volumes:
  14. data-volume:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

command

覆蓋容器啓動後默認執行的命令。

command: bundle exec thin -p 3000 
  • 1
  • 2

該命令也能夠是一個相似於dockerfile的列表:

command: ["bundle", "exec", "thin", "-p", "3000"] 
  • 1
  • 2

links

連接到另外一個服務中的容器。 請指定服務名稱和連接別名(SERVICE:ALIAS),或者僅指定服務名稱。

  1. web:
  2. links:
  3. - db
  4. - db:database
  5. - redis
  • 1
  • 2
  • 3
  • 4
  • 5

在當前的web服務的容器中能夠經過連接的db服務的別名database訪問db容器中的數據庫應用,若是沒有指定別名,則可直接使用服務名訪問。

連接不須要啓用服務進行通訊 - 默認狀況下,任何服務均可以以該服務的名稱到達任何其餘服務。 (實際是經過設置/etc/hosts的域名解析,從而實現容器間的通訊。故能夠像在應用中使用localhost同樣使用服務的別名連接其餘容器的服務,前提是多個服務容器在一個網絡中可路由聯通)

links也能夠起到和depends_on類似的功能,即定義服務之間的依賴關係,從而肯定服務啓動的順序。

external_links

連接到docker-compose.yml 外部的容器,甚至並不是 Compose 管理的容器。參數格式跟 links 相似。

  1. external_links:
  2. - redis_1
  3. - project_db_1:mysql
  4. - project_db_1:postgresql
  • 1
  • 2
  • 3
  • 4

expose

暴露端口,但不映射到宿主機,只被鏈接的服務訪問。 
僅能夠指定內部端口爲參數

  1. expose:
  2. - "3000"
  3. - "8000"
  • 1
  • 2
  • 3

ports

暴露端口信息。 
經常使用的簡單格式:使用宿主:容器 (HOST:CONTAINER)格式或者僅僅指定容器的端口(宿主將會隨機選擇端口)均可以。

** 注意:當使用 HOST:CONTAINER 格式來映射端口時,若是你使用的容器端口小於 60 你可能會獲得錯誤得結果,由於 YAML 將會解析 xx:yy 這種數字格式爲 60 進制。因此建議採用字符串格式。

簡單的短格式:

  1. ports:
  2. - "3000"
  3. - "3000-3005"
  4. - "8000:8000"
  5. - "9090-9091:8080-8081"
  6. - "49100:22"
  7. - "127.0.0.1:8001:8001"
  8. - "127.0.0.1:5000-5010:5000-5010"
  9. - "6060:6060/udp"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在v3.2中ports的長格式的語法容許配置不能用短格式表示的附加字段。 
長格式:

  1. ports:
  2. - target: 80
  3. published: 8080
  4. protocol: tcp
  5. mode: host
  • 1
  • 2
  • 3
  • 4
  • 5

target:容器內的端口 
published:物理主機的端口 
protocol:端口協議(tcp或udp) 
mode:host 和ingress 兩總模式,host用於在每一個節點上發佈主機端口,ingress 用於被負載平衡的swarm模式端口。

restart

no是默認的重啓策略,在任何狀況下都不會重啓容器。 指定爲always時,容器老是從新啓動。 若是退出代碼指示出現故障錯誤,則on-failure將從新啓動容器。

  1. restart: "no"
  2. restart: always
  3. restart: on-failure
  4. restart: unless-stopped
  • 1
  • 2
  • 3
  • 4

environment

添加環境變量。 你可使用數組或字典兩種形式。 任何布爾值; true,false,yes,no須要用引號括起來,以確保它們不被YML解析器轉換爲True或False。 
只給定名稱的變量會自動獲取它在 Compose 主機上的值,能夠用來防止泄露沒必要要的數據。

  1. environment:
  2. RACK_ENV: development
  3. SHOW: 'true'
  4. SESSION_SECRET:
  5.  
  6. environment:
  7. - RACK_ENV=development
  8. - SHOW=true
  9. - SESSION_SECRET
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

** 注意:若是你的服務指定了build選項,那麼在構建過程當中經過environment定義的環境變量將不會起做用。 將使用build的args子選項來定義構建時的環境變量。

pid

將PID模式設置爲主機PID模式。 這就打開了容器與主機操做系統之間的共享PID地址空間。 使用此標誌啓動的容器將可以訪問和操做裸機的命名空間中的其餘容器,反之亦然。即打開該選項的容器能夠相互經過進程 ID 來訪問和操做。

pid: "host"
  • 1

dns

配置 DNS 服務器。能夠是一個值,也能夠是一個列表。

  1. dns: 8.8.8.8
  2. dns:
  3. - 8.8.8.8
  4. - 9.9.9.9
  • 1
  • 2
  • 3
  • 4
相關文章
相關標籤/搜索