# 構建以及運行Springboot Docker鏡像時的變量傳遞


Docker可以把我們的運行環境打包,然后我們只要run就可以了。大部分hello world都是這么寫的。但都缺少了實際應用環節。以springboot為例,hello world的Dockerfile是這樣的:

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

我們實際使用的時候通常是

java -jar app.jar --spring.profiles.active=prod

也就是說,需要分環境。那直接

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar", "--spring.profiles.active=prod"]

這樣確實可以直接打出prod的運行包。直接run就可以了。

當同時需要打test環境的時候,我重新寫一個新的Dockerfile,改成test, 然后構建,就可以了。

docker build -t demo -f Dockerfile.test  .

寫兩個Dockerfile看起來太傻逼了,構建時替換好了。

暴力替換 -- shell替換

准備好我們的Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar", "--spring.profiles.active=<active-profile>"]

然后我們的構建腳本:

function build(){
    local env=$1
    sed -i 's/<active-profile>/${env}/g' Dockerfile
    docker build -t demo --build-arg JAR_FILE=demo.jar .
}

# 構建測試環境的包
build test
# 構建生產環境的包
build prod

# 運行
docker run -d demo

使用運行時指定參數

我們可以打一份鏡像,在運行的時候傳遞profile來確定激活哪個配置文件,就和springboot原生一樣。

ENTRYPOINT里是Docker容器的運行命令, CMD則是追加的參數,也就是說可以在后面加參數的。

docker run -d demo --spring.profiles.active=prod

運行時還可以傳遞環境變量,就是系統的環境變量。

$ docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t springio/gs-spring-boot-docker

按照Springboot屬性覆蓋優先級,命令行優先級超過系統環境變量的,所以還是選擇其中一種方式就好了。

構建時傳遞參數

如果我們開發模式是master模式,即所有的分發部署都是同一個分支master, 先將master部署到test環境,沒問題后直接發布到prod。同樣的鏡像,只是運行時指定配置文件。那么,我們是可以走運行時配置的。這樣,不同環境的K8s配置文件要修改對應的cmd命令。

我現在開發模式類似gitflow. dev分支開發結束后,merge到test分支,test分支發布到測試環境,測試環境ready后,再merge到master分支,master分支發布到生產環境。即,test環境和prod環境是不同的分支打出的鏡像。這就使得在打鏡像的時候就指定配置文件。可以選擇上文的暴力方式,文本替換。

也可以使用Docker參數。

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
ARG profile=prod

ENV SPRING_PROFILES_ACTIVE ${profile}

COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

構建

docker build -t demo --build-arg  JAR_FILE=demo.jar --build-arg profile=test .
  • ARG允許通過--build-arg傳遞參數
  • ENV等同於docker run -e來設置系統環境變量,但優先級弱於-e

上述幾種方案差不多解決了我的springboot容器化部署方式。在構建其他docker鏡像也可以通過類似的方案去傳遞參數。

大部分Dockerfile都是有docker-entrypoint.sh, 將啟動邏輯都放在一個腳本里,然后

ENTRYPOINT ["/docker-entrypoint.sh"]

這樣,我們也可以在啟動的時候傳遞參數到腳本里,腳本按照shell接受參數就可以了。

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM