Docker從入門到精通(八)—— Docker Compose
恭喜大家,學(xué)到這里,對于 docker 的基礎(chǔ)玩法大家應(yīng)該都會了,下面會介紹 docker的一些編排工具。
1、為什么需要 Docker Compose?
官網(wǎng)鎮(zhèn)樓:https://www.runoob.com/docker/docker-compose.html
一句話概括:
幫助我們批量有規(guī)則的管理容器。
前面基礎(chǔ)教程,我們介紹了 Dockerfile ,啟動服務(wù)都是通過 Dockerfile 構(gòu)建鏡像,啟動容器,對于幾個服務(wù),我們一個一個的build,run 還能接收,但是實際生產(chǎn)環(huán)境是有幾百上千個的,這個時候難道我們還有手動一個一個啟動嗎?
另外,服務(wù)與服務(wù)之間是有依賴關(guān)系的,比如一個 Tomcat 部署的服務(wù)依賴MySQL,依賴Redis,我們啟動 Tomcat 服務(wù)時,需要先啟動MySQL和Redis,這個順序也是很重要的。

有了 Docker Compose ,那我們就可以告別手動繁瑣的步驟,提前定義好規(guī)則,統(tǒng)一管理即可。
2、Docker Compose 局限性
首先說明,Docker Compose 雖然是官方提供的容器編排工具,但是實際生產(chǎn)環(huán)境是不用的(用什么?比如Swarm、K8S,后面會介紹),因為其局限性很大,這里介紹大家了解即可。
只支持單機多容器,不支持集群環(huán)境管理。
3、安裝
參考官方文檔即可:https://docs.docker.com/compose/install/
Mac/Windows 安裝docker默認(rèn)提供了 Docker Compose,所以不需要我們安裝,但是Linux環(huán)境需要手動安裝。
3.1 下載
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
上面是官方提供的,但是下載會比較慢,可以使用國內(nèi)的下載地址:
sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

3.2 授權(quán)
sudo chmod +x /usr/local/bin/docker-compose
3.3 驗證安裝
docker-compose version

3.4 卸載
sudo rm /usr/local/bin/docker-compose
4、用法
根據(jù)官方提示,使用 Docker Compose 分為三個步驟:
第一步:使用 Dockerfile 定義應(yīng)用程序的環(huán)境。 第二步:使用 docker-compose.yml 定義構(gòu)成應(yīng)用程序的服務(wù),這樣它們可以在隔離環(huán)境中一起運行。 第三步:執(zhí)行 docker-compose up 命令來啟動并運行整個應(yīng)用程序。
具體如何用,下面我通過兩個小例子來演示說明。
5、部署WP博客
這也是官方提供的實例:https://docs.docker.com/samples/wordpress/
WordPress是一款個人博客系統(tǒng),并逐步演化成一款內(nèi)容管理系統(tǒng)軟件,它是使用PHP語言和MySQL數(shù)據(jù)庫開發(fā)的,用戶可以在支持 PHP 和 MySQL數(shù)據(jù)庫的服務(wù)器上使用自己的博客。
5.1 創(chuàng)建項目目錄
名稱任意,用來存放 docker-compose.yml 文件
mkdir my_wordpress
我們按照官方創(chuàng)建一個名為 my_wordpress 目錄。
5.2 創(chuàng)建 docker-compose.yml
新建一個 docker-compose.yml 文件,內(nèi)容如下:
version: "3.9"
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
wordpress_data: {}
5.3 構(gòu)建項目
docker-compose up -d
注意要切換到my_wordpress 目錄,否則要增加 -f 參數(shù)指定 docker-compose.yml 文件。

看到上面截圖即表示啟動成功。
5.4 訪問頁面
http://宿主機IP:8000

另外,我們通過 docker ps 命令,也能看到啟動了兩個容器。

6、docker-compose.yml 規(guī)則
上面的例子很簡單,但是里面有一個核心就是 docker-compsoe.yml 文件的編寫,下面我們就來詳細(xì)介紹這個文件的編寫規(guī)則。
官方規(guī)則介紹:
https://docs.docker.com/compose/compose-file/
# 第一層:版本
version: "3.9"
# 第二層:服務(wù)
services:
# 服務(wù)名稱
db:
# 鏡像名稱
image: mysql:5.7
# 掛載的容器卷
volumes:
- db_data:/var/lib/mysql
# 服務(wù)掛掉是否自動重啟
restart: always
# 環(huán)境變量設(shè)置
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
# 服務(wù)名稱
wordpress:
# 依賴的服務(wù)
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
# 第三層:其他配置,包括網(wǎng)絡(luò),容器卷等等
volumes:
db_data: {}
wordpress_data: {}
其實主要就是三層配置,具體的每個配置項,大家可以看名知意,然后不懂的官網(wǎng)其實也有很詳細(xì)的說明。
7、Docker Comopose 部署自定義服務(wù)
下面我們自己寫一個服務(wù),不用官方服務(wù),帶著大家手動玩一遍。
每次訪問 Tomcat的服務(wù),Redis計數(shù)器加1

7.1 編寫 Tomcat服務(wù)
新建一個springboot項目,然后新建一個controller類:
package com.itcoke.counter.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class CounterController {
@Autowired
StringRedisTemplate redisTemplate;
@GetMapping("/visit")
public String count(HttpServletRequest request){
String remoteHost = request.getRemoteHost();
Long increment = redisTemplate.opsForValue().increment(remoteHost);
return remoteHost +"訪問次數(shù)"+increment.toString();
}
}
Springboot 服務(wù)的配置文件 application.yml:
server:
port: 8080
servlet:
context-path: /counter
spring:
redis:
host: counterRedis
7.2 Dockerfile
FROM openjdk:8-jdk
COPY *.jar /counter.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","/counter.jar"]
7.3 docker-compose.yml
version: "3.8"
services:
itcokecounter:
build: .
image: itcokecounter
depends_on:
- counterRedis
ports:
- "8080:8080"
counterRedis:
image: "redis:6.0-alpine"
7.4 測試
在Linux服務(wù)器新建 counter 文件夾,把下面三個文件拷貝到其中。

然后執(zhí)行如下命令構(gòu)建:
docker-compose up
執(zhí)行完成便會出現(xiàn)如下啟動成功界面:

然后,我們在瀏覽器輸入網(wǎng)址:
http://{ip}:8080/counter/visit

每刷新一次,還會增加一次。
關(guān)于我
Java程序猿,公眾號「IT可樂」定期分享有趣有料的精品原創(chuàng)文章!
