很多時候我想用一個工具只是做一個嘗試,於是希望它可以:
可快速啟動,不要安裝一堆系統級依賴
可快速清除,不留痕跡
docker 就完美符合這些要求,而且操作方便。再配合docker-compose,幾乎一鍵完成了。
下面我們來快速啟動一個 wordpress 和它配套的 mysql
步驟創建docker-compose.yml:
version: '2.1'
services:
wordpress:
depends_on:
- db
image: wordpress
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
db:
image: mysql
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: admin
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
ports:
- "3306:3306"
volumes:
db_data:
註:由於電腦限制,我只能使用 docker toolbox ,支持的 docker-compose.yml 最高版本只能到 2.1 。
接下來一鍵啟動:
$ docker-compose up
如果遇到 mysql 死活連不上的情況(Access denied for user),那很有可能是因為提供的密碼不對。上面設置的環境變量只在第一次啟動容器時有效,後面啟動時,如果容器已經存在了,docker 會嘗試保留上一次的數據,造成的結果就是,新設置的密碼沒有生效。這時,我們需要先刪除已有容器:
$ docker-compose rm -v
1. 概述問題:如果要使用 Docker 運行 LNMP 架構,那麼 Nginx、MySQL、PHP、 Linux三個服務運行在一個容器裡,還是運行在多個容器裡呢?
答案是都可以。
如果實現一個容器架構(微服務架構),一個個的 docker run 啟動很麻煩,更麻煩的是容器之間的連接與交互。所以我們需要用到容器編排。
2. 使用步驟Docker Compose 將所管理的容器分為三層:
工程(project)
服務(service)
容器(contaienr)
Docker Compose 運行的目錄下的所有文件(docker-compose.yml、extends 文件或環境變量文件等)組成一個工程,若無特殊指定工程名即為當前目錄名。
一個工程當中可包含多個服務,每個服務中定義了容器運行的鏡像、參數、關係,一個服務當中可包括多個容器實例。
使用 Compose 基本上分為三步:
Dockerfile 定義應用的運行環境(鏡像)
docker-compose.yml 定義組成應用的各服務
docker-compose up -d 構建並啟動整個應用
Docker Compose 是一個由 Python 編寫的軟體,在擁有 Python 運行環境的機器上,我們可以直接運行它,不需要其它的操作。
3. 安裝$ sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$
$ sudo docker-compose version
docker-compose version 1.21.2, build a133471
docker-py version: 3.3.0
CPython version: 3.6.5
OpenSSL version: OpenSSL 1.0.1t 3 May 2016
我們也能夠通過 Python 的包管理工具 pip 來安裝 Docker Compose。
$ sudo pip install docker-compose
Docker Compose 使用 Yaml 格式文件來編排。
參考:https://docs.docker.com/compose/compose-file/
與 Dockerfile 採用 Dockerfile 這個名字作為鏡像構建定義的默認文件名一樣,Docker Compose 的配置文件也有一個預設的文件名,也就是 docker-compose.yml,如非必要,我建議大家直接使用這個文件名來做 Docker Compose 項目的定義。
4.1 build指定鏡像構建時的 dockerfile 目錄,格式一般為絕對路徑目錄或相對路徑目錄(dockerfile需要命名為 Dockerfile):
build: /path/to/build/dir
或者
build: ./dir
指定要啟動容器的鏡像:
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
如果鏡像不存在,Compose 嘗試拉它。
如果指定了構建,可以使用指定的選項構建它,並使用指定的 tag 進行標記。
4.3 environment設置鏡像變量,它可以保存變量到鏡像裡面,也就是說啟動的容器也會包含這些變量設置。
environment 和 Dockerfile 中的 ENV 指令一樣,會把變量一直保存在鏡像、容器中。
格式
environment:
RACK_ENV: development
SHOW: 'true'
或
environment:
- RACK_ENV=development
- SHOW=true
這個標籤與 Dockerfile 中的 EXPOSE 指令一樣,用於指定暴露的埠,但只將埠暴露給連接的服務,而不暴露給主機。
expose:
- "3000"
- "8000"
映射埠,可以使用 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"
指定 Docker 容器的重啟策略。
默認值為 no,即在任何情況下都不會重新啟動容器
當值為 always 時,容器退出時總是重新啟動(會隨著 Docker 服務啟動而啟動容器)
當值為 on-failure 時,當出現 on-failure 報錯(非正常退出,退出狀態非 0),才會重啟容器
當值為 unless-stopped 時,在容器退出時總是重啟容器,但是不考慮在 Docker 守護進程啟動時就已經停止了的容器
restart: "no"
restart: always
restart: on-failure
restart: on-failure:3
restart: unless-stopped
數據卷掛載,可以直接使用 HOST:CONTAINER 這樣的格式,或者使用 HOST:CONTAINER:ro 這樣的格式,ro 代表數據卷是只讀的。
volumes:
### 只是指定一個路徑,Docker 會自動在創建一個數據卷(這個路徑是容器內部的)。
- /var/lib/mysql
### 使用絕對路徑掛載數據卷
- /opt/data:/var/lib/mysql
### 以 Compose 配置文件為中心的相對路徑作為數據卷掛載到容器。
- ./cache:/tmp/cache
### 使用用戶的相對路徑(~/ 表示的目錄是 /home/<用戶目錄>/ 或者 /root/)。
- ~/configs:/etc/configs/:ro
### 已經存在的命名的數據卷。
- datavolume:/var/lib/mysqlvolumes:
### 只是指定一個路徑,Docker 會自動在創建一個數據卷(這個路徑是容器內部的)。
- /var/lib/mysql
### 使用絕對路徑掛載數據卷
- /opt/data:/var/lib/mysql
### 以 Compose 配置文件為中心的相對路徑作為數據卷掛載到容器。
- ./cache:/tmp/cache
### 使用用戶的相對路徑(~/ 表示的目錄是 /home/<用戶目錄>/ 或者 /root/)。
- ~/configs:/etc/configs/:ro
### 已經存在的命名的數據卷。
- datavolume:/var/lib/mysql
此標籤解決了容器的依賴、啟動先後的問題。
version: '3'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: mysql
使用 docker-compose up web 啟動,會先啟動 Redis 和 DB,再啟動 Web。
4.9 links連結到其它服務的中的容器,與 link 連接一樣效果,會連接到其它服務中的容器。
web:
links:
- db
- db:database
- redis
在宿主機上打開 ip_forward,為我們下面要映射容器的埠到宿主機,只有打開 ip_forward 才能映射成功。
### vim /etc/sysctl.conf
net.ipv4.ip_forward=1
### sysctl -p
創建一個名為 wordpress 的 project(工程):
[root@daniel ~]### mkdir -p /docker-compose/wordpress
[root@daniel ~]### cd /docker-compose/wordpress
創建 docker-compose.yml:
[root@daniel wordpress]### vim docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
volumes:
- "./data:/var/lib/mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
expose:
- "3306"
wordpress:
depends_on:
- db
image: wordpress:latest
links:
- db
ports:
- "8010:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_PASSWORD: wordpress
說明:這個應用定義了兩個容器服務:db、wordpress。
db 容器通 mysql:5.7 鏡像啟動:
wordpress 容器通過 wordpress:latest 啟動:
需要 db 容器先啟動再啟動 wordpress 容器
wordpress 容器要 link 連接 db 容器
wordpress 容器將 80 埠映射到宿主機的 8010 埠
容器重啟策略為 always
設置連接資料庫的變量
啟動:
對於開發來說,最常使用的 Docker Compose 命令就是 docker-compose up 和 docker-compose down 了。
docker-compose up 命令類似於 Docker Engine 中的 docker run,它會根據 docker-compose.yml 中配置的內容,創建所有的容器、網絡、數據卷等等內容,並將它們啟動。與 docker run 一樣,默認情況下 docker-compose up 會在「前臺」運行,我們可以用 -d 選項使其「後臺」運行。事實上,我們大多數情況都會加上 -d 選項。
[root@daniel wordpress]### docker-compose up -d
如果本地沒有鏡像,下載的兩個鏡像比較大。
[root@daniel wordpress]### docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 e9c354083de7 3 days ago 373MB
wordpress latest 4ba1e63bd20c 8 days ago 501MB
需要注意的是,docker-compose 命令默認會識別當前控制臺所在目錄內的 docker-compose.yml 文件,而會以這個目錄的名字作為組裝的應用項目的名稱。如果我們需要改變它們,可以通過選項 -f 來修改識別的 Docker Compose 配置文件,通過 -p 選項來定義項目名。
docker-compose -f ./compose/docker-compose.yml -p myapp up -d
與 docker-compose up 相反,docker-compose down 命令用於停止所有的容器,並將它們刪除,同時消除網絡等配置內容,也就是幾乎將這個 Docker Compose 項目的所有影響從 Docker 中清除。
docker-compose down
安裝與訪問
在瀏覽器端,訪問容器主機的 8010 埠,安裝訪問,最終效果如下:
在 Docker Engine 中,如果我們想要查看容器中主進程的輸出內容,可以使用 docker logs 命令。而由於在 Docker Compose 下運行的服務,其命名都是由 Docker Compose 自動完成的,如果我們直接使用 docker logs 就需要先找到容器的名字,這顯然有些麻煩了。我們可以直接使用 docker-compose logs 命令來完成這項工作。
$ sudo docker-compose logs nginx
在 docker-compose logs 銜接的是 Docker Compose 中所定義的服務的名稱。
同理,在 Docker Compose 還有幾個類似的命令可以單獨控制某個或某些服務。
通過 docker-compose create,docker-compose start 和 docker-compose stop 我們可以實現與 docker create,docker start 和 docker stop 相似的效果,只不過操作的對象由 Docker Engine 中的容器變為了 Docker Compose 中的服務。
$ sudo docker-compose create webapp
$ sudo docker-compose start webapp
$ sudo docker-compose stop webapp