docker-compose教程(安裝,使用, 快速入門)
1.Compose介紹
Docker Compose是一個用來定義和運行復雜應用的Docker工具。一個使用Docker容器的應用,通常由多個容器組成。使用Docker Compose不再需要使用shell指令碼來啟動容器。
Compose 通過一個配置檔案來管理多個Docker容器,在配置檔案中,所有的容器通過services來定義,然後使用docker-compose指令碼來啟動,停止和重啟應用,和應用中的服務以及所有依賴服務的容器,非常適合組合使用多個容器進行開發的場景。
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月。
Docker的linux發行版的軟體倉庫從以前的https://apt.dockerproject.org和https://yum.dockerproject.org變更為目前的https://download.docker.com, 軟體包名字改為docker-ce和docker-ee。
3.安裝docker
Docker的社群版(Docker Community Edition)叫做docker-ce。老版本的Docker包叫做docker或者docker-engine,如果安裝了老版本的docker得先解除安裝然後再安裝新版本的docker。docker的發展非常迅速,apt源的更新往往比較滯後。所以docker官網推薦的安裝方式都是下載docker安裝指令碼安裝。
解除安裝老舊的版本(若未安裝過可省略此步):
$ sudo apt-get remove docker docker-engine docker.io
安裝最新的docker:
-
$ curl -fsSL get.docker.com -o get-docker.sh
- $ sudo sh get-docker.sh
shell會提示你輸入sudo的密碼,然後開始執行最新的docker過程
或者
$ curl -sSL https://get.docker.com/ | sh
確認Docker成功最新的docker:
$ sudo docker run hello-world
4.安裝docker-compose
兩種最新的docker安裝方式
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
若是github訪問太慢,可以用daocloud下載
sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.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-compose
5.docker-compose檔案結構和示例
docker-compose檔案結構
docker-compose.yml:
- version: "3"
- 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:
docker-compose使用示例
通過docker-compose構建一個在docker中執行的基於python flask框架的web應用。
注意:確保你已經安裝了Docker Engine和Docker Compose。 您不需要安裝Python或Redis,因為這兩個都是由Docker映象提供的。
Step 1: 定義python應用
- 1 .建立工程目錄
目錄結構如下:
- └── compose_test
- ├── docker
- │ └── docker-compose.yml
- ├── Dockerfile
- └── src
- ├── app.py
- └── requirements.txt
- 2 .在compose_test/src/目錄下建立python flask應用 compose_test/src/app.py檔案。
- from flask import Flask
- from redis import Redis
- app = Flask(__name__)
- redis = Redis(host='redis', port=6379)
- def hello():
- count = redis.incr('hits')
- return 'Hello World! I have been seen {} times.\n'.format(count)
- if __name__ == "__main__":
- app.run(host="0.0.0.0", debug=True)
- 3 .建立python 需求檔案 compose_test/src/requirements.txt
- flask
- redis
Step 2: 建立容器的Dockerfile檔案
一個容器一個Dockerfile檔案,在compose_test/目錄中建立Dockerfile檔案:
- FROM python:3.7
- COPY src/ /opt/src
- WORKDIR /opt/src
- RUN pip install -r requirements.txt
- CMD ["python", "app.py"]
Dockerfile檔案告訴docker瞭如下資訊:
從Python 3.6映象開始構建一個容器映象。
複製src(即compose_test/src)目錄到容器的/opt/src目錄。
將容器的工作目錄設定為/opt/src(通過docker exec -it your_docker_container_id_or_name bash 進入容器後的預設目錄)。
安裝Python依賴關係。
將容器的預設命令設定為python app.py。
Step 3: 定義docker-compose指令碼
在compose_test/docker/目錄下建立docker-compose.yml檔案,並在裡面定義服務,內容如下:
- version: '3'
- services:
- web:
- build: ../
- ports:
- - "5000:5000"
- redis:
- image: "redis:3.0.7"
這個compose檔案定義了兩個服務,即定義了web和redis兩個容器。
web容器:
* 使用當前docker-compose.yml檔案所在目錄的上級目錄(compose_test/Dockerfile)中的Dockerfile構建映像。
* 將容器上的暴露埠5000對映到主機上的埠5000。 我們使用Flask Web伺服器的預設埠5000。
redis容器:
* redis服務使用從Docker Hub提取的官方redis映象3.0.7版本。
Step 4: 使用Compose構建並執行您的應用程式
在compose_test/docker/目錄下執行docker-compose.yml檔案:
- $ docker-compose up
- # 若是要後臺執行: $ docker-compose up -d
- # 若不使用預設的docker-compose.yml 檔名:
- $ docker-compose -f server.yml up -d
然後在瀏覽器中輸入http://0.0.0.0:5000/檢視執行的應用程式。
Step 5: 編輯compose檔案以新增檔案繫結掛載
上面的程式碼是在構建時靜態複製到容器中的,即通過Dockerfile檔案中的COPY src /opt/src命令實現物理主機中的原始碼複製到容器中,這樣在後續物理主機src目錄中程式碼的更改不會反應到容器中。
可以通過volumes 關鍵字實現物理主機目錄掛載到容器中的功能(同時刪除Dockerfile中的COPY指令,不需要建立映象時將程式碼打包進映象,而是通過volums動態掛載,容器和物理host共享資料卷):
- version: '3'
- services:
- web:
- build: ../
- ports:
- - "5000:5000"
- volumes:
- - ../src:/opt/src
- redis:
- image: "redis:3.0.7"
通過volumes(卷)將主機上的專案目錄(compose_test/src)掛載到容器中的/opt/src目錄下,允許您即時修改程式碼,而無需重新構建映像。
Step 6: 重新構建和執行應用程式
使用更新的compose檔案構建應用程式,然後執行它。
$ docker-compose up -d
6.compose常用服務配置參考
Compose檔案是一個定義服務,網路和卷的YAML檔案。 Compose檔案的預設檔名為docker-compose.yml。
**提示:您可以對此檔案使用.yml或.yaml副檔名。 他們都工作。
與docker執行一樣,預設情況下,Dockerfile中指定的選項(例如,CMD,EXPOSE,VOLUME,ENV)都被遵守,你不需要在docker-compose.yml中再次指定它們。
同時你可以使用類似Bash的$ {VARIABLE} 語法在配置值中使用環境變數,有關詳細資訊,請參閱變數替換。
本節包含版本3中服務定義支援的所有配置選項。
build
build 可以指定包含構建上下文的路徑:
- version: '2'
- services:
- webapp:
- build: ./dir
或者,作為一個物件,該物件具有上下文路徑和指定的Dockerfile檔案以及args引數值:
- version: '2'
- services:
- webapp:
- build:
- context: ./dir
- dockerfile: Dockerfile-alternate
- args:
- buildno: 1
webapp服務將會通過./dir目錄下的Dockerfile-alternate檔案構建容器映象。
如果你同時指定image和build,則compose會通過build指定的目錄構建容器映象,而構建的映象名為image中指定的映象名和標籤。
- build: ./dir
- image: webapp:tag
這將由./dir構建的名為webapp和標記為tag的映象。
context
包含Dockerfile檔案的目錄路徑,或者是git倉庫的URL。
當提供的值是相對路徑時,它被解釋為相對於當前compose檔案的位置。 該目錄也是傳送到Docker守護程式構建映象的上下文。
dockerfile
備用Docker檔案。Compose將使用備用檔案來構建。 還必須指定構建路徑。
args
新增構建映象的引數,環境變數只能在構建過程中訪問。
首先,在Dockerfile中指定要使用的引數:
- ARG buildno
- ARG password
- RUN echo "Build number: $buildno"
- RUN script-requiring-password.sh "$password"
然後在args鍵下指定引數。 你可以傳遞對映或列表:
- build:
- context: .
- args:
- buildno: 1
- password: secret
- build:
- context: .
- args:
- - buildno=1
- - password=secret
** 注意:YAML布林值(true,false,yes,no,on,off)必須用引號括起來,以便解析器將它們解釋為字串。
image
指定啟動容器的映象,可以是映象倉庫/標籤或者映象id(或者id的前一部分)
- image: redis
- image: ubuntu:14.04
- image: tutum/influxdb
- image: example-registry.com:4000/postgresql
- image: a4bc65fd
如果映象不存在,Compose將嘗試從官方映象倉庫將其pull下來,如果你還指定了build,在這種情況下,它將使用指定的build選項構建它,並使用image指定的名字和標記對其進行標記。
container_name
指定一個自定義容器名稱,而不是生成的預設名稱。
container_name: my-web-container
由於Docker容器名稱必須是唯一的,因此如果指定了自定義名稱,則無法將服務擴充套件到多個容器。
volumes
卷掛載路徑設定。可以設定宿主機路徑 (HOST:CONTAINER) 或加上訪問模式 (HOST:CONTAINER:ro),掛載資料卷的預設許可權是讀寫(rw),可以通過ro指定為只讀。
你可以在主機上掛載相對路徑,該路徑將相對於當前正在使用的Compose配置檔案的目錄進行擴充套件。 相對路徑應始終以 . 或者 .. 開始。
- volumes:
- # 只需指定一個路徑,讓引擎建立一個卷
- - /var/lib/mysql
- # 指定絕對路徑對映
- - /opt/data:/var/lib/mysql
- # 相對於當前compose檔案的相對路徑
- - ./cache:/tmp/cache
- # 使用者家目錄相對路徑
- - ~/configs:/etc/configs/:ro
- # 命名卷
- - datavolume:/var/lib/mysql
但是,如果要跨多個服務並重用掛載卷,請在頂級volumes關鍵字中命名掛在卷,但是並不強制,如下的示例亦有重用掛載卷的功能,但是不提倡。
- version: "3"
- services:
- web1:
- build: ./web/
- volumes:
- - ../code:/opt/web/code
- web2:
- build: ./web/
- volumes:
- - ../code:/opt/web/code
** 注意:通過頂級volumes定義一個掛載卷,並從每個服務的卷列表中引用它, 這會替換早期版本的Compose檔案格式中volumes_from。
- version: "3"
- services:
- db:
- image: db
- volumes:
- - data-volume:/var/lib/db
- backup:
- image: backup-service
- volumes:
- - data-volume:/var/lib/backup/data
- volumes:
- data-volume:
command
覆蓋容器啟動後預設執行的命令。
command: bundle exec thin -p 3000
該命令也可以是一個類似於dockerfile的列表:
command: ["bundle", "exec", "thin", "-p", "3000"]
links
連結到另一個服務中的容器。 請指定服務名稱和連結別名(SERVICE:ALIAS),或者僅指定服務名稱。
- web:
- links:
- - db
- - db:database
- - redis
在當前的web服務的容器中可以通過連結的db服務的別名database訪問db容器中的資料庫應用,如果沒有指定別名,則可直接使用服務名訪問。
連結不需要啟用服務進行通訊 - 預設情況下,任何服務都可以以該服務的名稱到達任何其他服務。 (實際是通過設定/etc/hosts的域名解析,從而實現容器間的通訊。故可以像在應用中使用localhost一樣使用服務的別名連結其他容器的服務,前提是多個服務容器在一個網路中可路由聯通)
links也可以起到和depends_on相似的功能,即定義服務之間的依賴關係,從而確定服務啟動的順序。
external_links
連結到docker-compose.yml 外部的容器,甚至並非 Compose 管理的容器。引數格式跟 links 類似。
- external_links:
- - redis_1
- - project_db_1:mysql
- - project_db_1:postgresql
expose
暴露埠,但不對映到宿主機,只被連線的服務訪問。
僅可以指定內部埠為引數
- expose:
- - "3000"
- - "8000"
ports
暴露埠資訊。
常用的簡單格式:使用宿主:容器 (HOST:CONTAINER)格式或者僅僅指定容器的埠(宿主將會隨機選擇埠)都可以。
** 注意:當使用 HOST:CONTAINER 格式來對映埠時,如果你使用的容器埠小於 60 你可能會得到錯誤得結果,因為 YAML 將會解析 xx:yy 這種數字格式為 60 進位制。所以建議採用字串格式。
簡單的短格式:
- 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"
在v3.2中ports的長格式的語法允許配置不能用短格式表示的附加欄位。
長格式:
- ports:
- - target: 80
- published: 8080
- protocol: tcp
- mode: host
target:容器內的埠
published:物理主機的埠
protocol:埠協議(tcp或udp)
mode:host 和ingress 兩總模式,host用於在每個節點上釋出主機埠,ingress 用於被負載平衡的swarm模式埠。
restart
no是預設的重啟策略,在任何情況下都不會重啟容器。 指定為always時,容器總是重新啟動。 如果退出程式碼指示出現故障錯誤,則on-failure將重新啟動容器。
- restart: "no"
- restart: always
- restart: on-failure
- restart: unless-stopped
environment
新增環境變數。 你可以使用陣列或字典兩種形式。 任何布林值; true,false,yes,no需要用引號括起來,以確保它們不被YML解析器轉換為True或False。
只給定名稱的變數會自動獲取它在 Compose 主機上的值,可以用來防止洩露不必要的資料。
- environment:
- RACK_ENV: development
- SHOW: 'true'
- SESSION_SECRET:
- environment:
** 注意:如果你的服務指定了build選項,那麼在構建過程中通過environment定義的環境變數將不會起作用。 將使用build的args子選項來定義構建時的環境變數。
pid
將PID模式設定為主機PID模式。 這就打開了容器與主機作業系統之間的共享PID地址空間。 使用此標誌啟動的容器將能夠訪問和操作裸機的名稱空間中的其他容器,反之亦然。即開啟該選項的容器可以相互通過程序 ID 來訪問和操作。
pid: "host"
dns
配置 DNS 伺服器。可以是一個值,也可以是一個列表。
- dns: 8.8.8.8
- dns:
- - 8.8.8.8
- - 9.9.9.9