Java程式製作Docker Image推薦方案
要求
這裡先給出一些Docker Image製作的要求,之後我們再看怎麼做。
- 製作過程要融合在專案構建過程中
- 使用官方Image作為基礎Image
- 設定正確的時區
- Container內的程式以非root使用者啟動
- 指定Web程式的介面
- 能夠傳遞JVM引數、Java System Properties、程式自定義的引數
下面具體講一下具體怎麼做到以上幾點:
製作過程要融合在專案構建過程中
這裡推薦使用Spotify的dockerfile-maven-plugin,理由是這個plugin用起來最簡單且容易掌握。
該plugin的本質上是你寫一個Dockerfile(關於Dockerfile的具體寫法請參照
因此只要你會寫Dockerfile,就會使用這個plugin,它沒有加入任何額外的概念。
使用官方Image作為基礎Image
openjdk repository提供了各種各樣的image tags看起來眼花繚亂,但是本質上來說就這麼幾個:
- openjdk:<version>
- openjdk:<version>-slim
- openjdk:<version>-alpine
關於<version>
一般來說指定大版本號就行了,比如你可以在Dockerfile這樣寫:
FROM openjdk:8-alpine
從尺寸上來講,alpine最小、slim稍大、預設的最大。所以應該儘可能的使用alpine版本的,如果發現程式的執行環境缺少某些東西,那麼嘗試用slim版本或者預設版本。就目前的經驗來講:
- 如果需要作業系統字型庫,那麼就得使用slim版本或者預設版本。需要作業系統字型庫的程式例如:圖片驗證碼、PDF匯出。
- 如果需要某些Linux標準的動態/靜態連線庫,那麼在alpine版本不行的情況下,嘗試slim版本或預設版本。因為alpine版本是一個及其精簡的Linux,它刪除了很多東西。
設定正確的時區
幾乎所有的Docker Image的時區都是UTC,我們需要給我們自己製作的Docker Image設定時區:
ENV TZ=Asia/Shanghai
RUN set -eux; \
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime; \
echo $TZ > /etc/timezone
關於資料庫時區的相關內容可以見:
Container內的程式以非root使用者啟動
在Docker Image內部,我們應該使用非root使用者啟動程式,這需要使用到gosu。
gosu的Dockerfile指南在這裡。
記得要根據不同的基礎Image選擇適合的安裝方式。
指定Web程式的介面
對於聯網應用而言,必須在Dockerfile中指定暴露的埠,否則該埠無法對映。
EXPOSE 8080
能夠傳遞JVM引數、Java System Properties、程式自定義的引數
我們需要能夠在啟動Docker Image的時候將一些引數傳遞進去:
- JVM引數
- Java System Properties
- 程式啟動引數
樣例專案
目錄結構
所有與程式相關的東西都存放在/home/java-app/
下:
/home/java-app
├── docker-entrypoint.sh
├── lib
│ └── java-app.jar
├── etc
├── logs
└── tmp
-
docker-entrypoint.sh
,啟動指令碼 -
lib
,存放JAR包 -
lib/java-app.jar
,程式JAR包 -
etc
,存放配置檔案 -
logs
,存放日誌檔案 -
tmp
,存放臨時檔案
構建Image的方法
mvn clean package dockerfile:build
執行
普通啟動,然後訪問http://localhost:8080
:
docker run -p 8080:8080 chanjarster/dockerfile-java-examples-1:1.0-SNAPSHOT
設定JVM引數,使用JVM_OPTS
環境變數:
docker run -p 8080:8080 -e JVM_OPTS='-Xmx128M -Xms128M' chanjarster/dockerfile-java-examples-1:1.0-SNAPSHOT
設定System Properties,使用JAVA_ARGS
環境變數:
docker run -p 8080:8080 -e JAVA_ARGS='-Dabc=xyz -Ddef=uvw' chanjarster/dockerfile-java-examples-1:1.0-SNAPSHOT
提供程式執行引數,在後面直接新增即可:
docker run -p 8080:8080 chanjarster/dockerfile-java-examples-1:1.0-SNAPSHOT --debug