前言
通常,部署流程主要為下面幾個步驟:
提交代碼 ( SVN 或者 Git ) 。
在 構(gòu)建服務(wù)器 上拉取代碼進(jìn)行構(gòu)建打包。
將軟件包發(fā)送到 部署服務(wù)器,或者打包后上傳到倉庫,由 部署服務(wù)器 進(jìn)行下載。
部署服務(wù)器 停止現(xiàn)有服務(wù),使用新的軟件包進(jìn)行啟動。
上面的步驟很是繁瑣,而且全程需要人工盯著以進(jìn)行后續(xù)步驟,如果需要經(jīng)常部署的話無疑是很浪費時間的。有人會說可以用 Jenkins 這樣的 CI 工具啊,這也是一種方法,但不是本文的目標(biāo)。
項目 Docker 化改造
既然要用 Docker 進(jìn)行部署,那就要對現(xiàn)有項目做一些簡單的改造,如果項目結(jié)構(gòu)之前已經(jīng)比較規(guī)范了,那么改造起來也會比較簡單。
先在項目 根目錄 ( 也可以放在一個 docker 文件夾下統(tǒng)一維護(hù) ) 下添加幾個文件:
| 文件 | 說明 |
|---|---|
| Dockerfile | 鏡像配置文件,用于配置程序運行時依賴的環(huán)境,比如 Java 、 Tomcat |
| .dockerignore | 使用 Docker 構(gòu)建鏡像的時候會將 上下文目錄 中的文件復(fù)制到 Docker Engine 中,如果每次都要復(fù)制一遍 源碼 和 構(gòu)建中間產(chǎn)物 就會很浪費時間,.dockerignore 的作用就是用于忽略指定的文件,加快鏡像構(gòu)建速度。 |
| docker-compose.yml | 用于多個服務(wù)的編排。項目如果依賴了 數(shù)據(jù)庫 、緩存 、消息隊列 等,可以在這里配置依賴關(guān)系,還可以進(jìn)行動態(tài) 擴(kuò)縮容 。 |
| .env | docker-compose.yml 中可以使用 環(huán)境變量 進(jìn)行參數(shù)化配置,一些默認(rèn)的 環(huán)境變量 可以保存在這個文件中,實際構(gòu)建時可以配置 環(huán)境變量 對其進(jìn)行覆蓋。 |
之后將項目中一些 寫死 的 配置 改為通過 環(huán)境變量 讀取,這樣就可以通過 docker-compose.yml 導(dǎo)入 環(huán)境變量 ,在不同環(huán)境下 ( 開發(fā) 、 測試 、 線上 等 ) 不用改文件就可以部署了。具體配置參考下面的測試項目。
準(zhǔn)備工作
安裝 IntelliJ IDEA ( 目前最新版本是
2019.1) 。-
安裝 Docker Desktop for Windows 。
不推薦安裝 Docker Desktop for Windows ,本文只是用于測試。
最好在其他的 Linux 主機(jī)上運行 Docker 。 -
下載最新版的 Docker Compose - docker-compose-Windows-x86_64.exe 。
Docker Desktop for Windows 已經(jīng)集成了 Docker Compose ,一般不需要單獨下載。
下載 測試項目 。
先閱讀完本文。
使用方法
打開測試項目 JetBrains-Docker-Example/Springboot-Example 。
設(shè)置 Project JDK 。
導(dǎo)入 pom.xml ( 右鍵 Add as Maven Project 或者直接拖拽到 Maven 工具欄 中 ) 。
-
添加 Docker Daemon 。
File -> Settings -> Build, Execution, Deployment -> Docker -> Add -> 輸入 Docker Daemon 的 URL
Docker Daemon 的配置參考 這里 。
添加 Docker Daemon注意:如果要啟用 TLS 安全連接,協(xié)議名需要填寫 https 而不是命令行中使用的 tcp 。
-
Add Run Configuration -> New -> Docker -> Docker-compose
添加 Run Configuration -
修改配置。
配置 Run Configuration當(dāng)然,也可以直接打開 docker-compose.yml ,點擊左側(cè)顯示的 三角形按鈕 自動生成運行配置。
通過 docker-compose.yml 運行 -
運行配置,可以看到容器已經(jīng)啟動了,訪問看下效果:127.0.0.1:3000 。
docker 部署通過 Docker 插件 還可以可視化查看 容器 的 日志 、 環(huán)境變量 、 端口映射 、 數(shù)據(jù)卷 等配置信息,并且可以動態(tài) 修改配置 和 進(jìn)入容器 ,比起 敲命令 方便的不要太多。
docker 插件
上面的步驟就是 Docker 插件 的常規(guī)用法,已經(jīng)實現(xiàn)了 一鍵部署 效果,只是需要自己配置 Run Configuration 。
下面看下另一種使用方式:
打開另一個測試項目 JetBrains-Docker-Example/Node-Example 。
-
先使用命令
npm install安裝依賴。最好先在命令行執(zhí)行再打開 IDEA ,不然可能把 IDEA 卡死。
-
打開 package.json ,部署命令已經(jīng)在 Docker 寫好了,點擊命令左側(cè)顯示的 三角形按鈕 直接執(zhí)行就行了。
通過 package.json 運行如果需要部署到其他 遠(yuǎn)程 Docker Daemon ,可以修改 環(huán)境變量
DOCKER_HOST。 訪問看下效果:127.0.0.1:8000 。
這種方式也是 一鍵式 的,也比較適合在命令行中執(zhí)行。
Docker Desktop for Windows 的坑
依賴于 Hyper-V 虛擬機(jī),但是 Hyper-V 的兼容性不太好,容易出一些莫名其妙的問題,所以 不推薦安裝 。
-
使用它 (
2.0.0.3 (31259)) 自帶的 docker-compose ( 1.23.2 ) 在執(zhí)行某些鏡像構(gòu)建操作的時候可能會出現(xiàn)下面的錯誤:Building api [18576] Failed to execute script docker-compose Traceback (most recent call last): File "docker-compose", line 6, in <module> File "compose\cli\main.py", line 71, in main File "compose\cli\main.py", line 127, in perform_command File "compose\cli\main.py", line 1080, in up File "compose\cli\main.py", line 1076, in up File "compose\project.py", line 475, in up File "compose\service.py", line 342, in ensure_image_exists File "compose\service.py", line 1082, in build File "site-packages\docker\api\build.py", line 150, in build UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 10: illegal multibyte sequence查看 源碼 發(fā)現(xiàn)是因為 .dockerignore 文件中包含了中文導(dǎo)致亂碼,
1.19.0及之前的版本沒有這個問題。( 同樣的版本,Linux 下沒有這個問題 ) -
在 Windows 下使用舊版 docker-compose ( 比如
1.19.0) 部署到 遠(yuǎn)程 Linux Docker Daemon 時,如果使用了 數(shù)據(jù)卷 會出現(xiàn)下面的錯誤:Creating api ... Creating api ... error ERROR: for api Cannot create container for service api: create \etc\localtime: "\\etc\\localtime" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path ERROR: for api Cannot create container for service api: create \etc\localtime: "\\etc\\localtime" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path Encountered errors while bringing up the project.使用
docker-compose config命令可以看到 數(shù)據(jù)卷 源路徑被改成了 Windows 下的 反斜杠 類型的路徑格式\etc\localtime。services: api: build: context: D:\github\test\JetBrains-Docker-Example\Springboot-Example command: java -jar -Djava.security.egd=file:/dev/./urandom -server -XX:+DisableExplicitGC -Xms256m -Xmx256m -Dspring.profiles.active=docker /app.jar container_name: api hostname: api ports: - 3000:8080/tcp privileged: false restart: always volumes: - \etc\localtime:/etc/localtime:rw version: '3.0'通過閱讀 源碼 找到了方法:使用 docker-compose 的 內(nèi)置環(huán)境變量 -
COMPOSE_CONVERT_WINDOWS_PATHS=1
其他方案
上面提到了 Docker Desktop for Windows 的一些問題,所以我不推薦去安裝它,單獨下載 docker-compose 就好了??紤]到 Windows 到 Linux 之間交互可能會存在的問題,我還有一種方案:
安裝 WSL 。
-
在 WSL 中安裝 Docker,但是只具備 客戶端 功能而無法運行 Docker Daemon 。
2019-07-12 追加: 目前 WSL 已經(jīng)能夠運行 Docker Daemon 了,參考我另一篇 文章 。
在 WSL 中安裝 docker-compose 。
-
在 Windows 下編寫腳本
docker-compose.bat。@echo off echo current dir: %cd% :: 使用延遲變量 setlocal enabledelayedexpansion :: 遍歷所有參數(shù),如果是 compose 文件則轉(zhuǎn)換路徑格式 :: 使用 wslpath 將 Windows 路徑轉(zhuǎn)為 wsl 中的路徑 for %%i in ( %* ) do ( :: 當(dāng)前參數(shù) set arg=%%i :: 使用下面這種方式中文路徑不會亂碼 if !last_arg!==-f if !arg! neq -f set "arg=`wslpath '!arg!'`" :: 追加到新的參數(shù)列表中 set "args=!args! !arg!" :: 作為上一個參數(shù)保存 set last_arg=%%i ) :: IDEA 部署到指定 Docker Daemon 的時候會設(shè)置下面的環(huán)境變量 :: 設(shè)置環(huán)境變量 DOCKER_HOST 來指定 Docker Daemon 的 URL if defined DOCKER_HOST set "envs=export DOCKER_HOST=%DOCKER_HOST%;" :: 設(shè)置環(huán)境變量 DOCKER_TLS_VERIFY 和 DOCKER_CERT_PATH 指定 TLS 配置 :: DOCKER_CERT_PATH 為空時,wslpath 命令的結(jié)果是 '.',要做處理 if defined DOCKER_CERT_PATH set "envs=%envs%export DOCKER_CERT_PATH=`wslpath '%DOCKER_CERT_PATH%'`;" set "envs=%envs%export DOCKER_TLS_VERIFY=%DOCKER_TLS_VERIFY%;" :: 通過 WSL 調(diào)用 docker-compose :: 如果 bash -c 命令參數(shù)中包含$則要轉(zhuǎn)義,否則在解析 bash -c 命令的時候就會對 shell 變量進(jìn)行替換 :: 注意:.env 文件需要在當(dāng)前命令的執(zhí)行目錄下 bash -c "%envs%env|grep DOCKER;set -x;docker-compose %args%;"IDEA 通過設(shè)置 環(huán)境變量 : DOCKER_HOST 、DOCKER_TLS_VERIFY 、DOCKER_CERT_PATH 起到連接 遠(yuǎn)程 Docker Daemon 的目的。
-
修改 Docker Compose 的 可執(zhí)行程序 為上面的腳本。
修改 docker 可執(zhí)行程序
結(jié)語
上面其實只是介紹一個很簡單但又實用的功能,更多的是分享我在使用過程中遇到的一些問題,尤其是在寫這篇文章的時候才發(fā)現(xiàn)自己之前有些認(rèn)知是錯誤的,也是一種收獲。







