Docker 構建 nginxWebUI 容器實戰
前言
nginxWebUI 專案並非本人所寫,其國內國內專案地址: Gitee nginxWebUI ,官網:nginxWebUI.cn。
由於源專案並未提供 ARM 平臺的適配,但是該專案提供了 Dockerfile 檔案,我們可以根據 Dockerfile 的說明和專案的原始碼,進行 ARM 平臺下的重編譯和 Docker 容器構建。
非 ARM 平臺的,也可以按照本文進行本平臺的實戰測試。
Java
對於源專案的原始碼來說,已經打包好了 x86_64 平臺的 jar.tar.gz 包,該包內包含的 java 可執行程式是無法被用於 ARM 平臺下執行。所以,雖然 arm64 系統的 Docker 可以下載源專案的映象並保持容器的執行,但是實際上, ADD
我們需要重新將 AArch64 的 jre 重新打包並用於容器構建。
下載
可以通過訪問甲骨文(Oracle)的 jdk 下載官網,下載 AArch64 的 jdk 進行過濾打包: Oracle Java 8 。
實際上,Oracle 提供了 Java 8 和 Java 11 兩個穩定版本的 AArch64 的 rpm 和 tar.gz (Compressed Archive)。但是為了使容器儘量的精簡,推薦使用 Java 8 來進行過濾打包。
jre https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html
解壓 https://blog.csdn.net/laobai1015/article/details/89405905
簡化過濾壓縮
-
對下載得到的 jdk-8u291-linux-aarch64.tar.gz 進行解壓。
tar -zxvf jdk-8u291-linux-aarch64.tar.gz
-
提取出要用的兩部分,複製
./jdk1.8.0_291/jre/
資料夾到新建目錄./jre1.8.0_291/
下,並刪除無用的、全是.md
檔案legal
目錄。mkdir jre1.8.0_291 cp -r ./jdk1.8.0_291/jre/ ./jre1.8.0_291/ rm -r legal
-
重新壓縮打包為
jre1.8.0_291.tar.gz
tar -zcvf jre1.8.0_291.tar.gz jre1.8.0_291
這時打包好的檔案 40.13 MB ,解壓後文件大小 106 MB 。注意這個數字,方便後面理解。
重新編譯打包
由於源專案是基於 SpringBoot 的,對於 ARM 環境下的 jar 要重新進行編譯。這是使用 Docker 搭建 ARM 下 Maven 環境 來進行編譯打包。
- 請參考: Docker 搭建 ARM 下 Maven 環境 。
Dockerfile
原 Dockerfile 分析
FROM ubuntu:20.04
LABEL maintainer="[email protected]"
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
RUN apt-get clean && apt-get update &&\
apt-get install -y nginx &&\
#apt-get install -y openjdk-11-jre &&\
apt-get install -y net-tools &&\
apt-get install -y curl &&\
apt-get install -y wget &&\
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone &&\
apt-get install tzdata
ENV LANG C.UTF-8
ADD jre.tar.gz /home/
RUN chmod 777 /home/jre/bin/java
ADD nginxWebUI.sh /home/
RUN chmod 777 /home/nginxWebUI.sh
COPY target/nginxWebUI-*.jar /home/nginxWebUI.jar
ENTRYPOINT ["sh","-c", "/home/nginxWebUI.sh ${BOOT_OPTIONS} && tail -f /dev/null"]
-
初始映象為 ubuntu:20.04
-
維護者為 [email protected]
-
DEBIAN_FRONTEND
:環境變數,告知作業系統應該從哪兒獲得使用者輸入。設為
noninteractive
可以直接執行命令,而無需向用戶請求輸入(所有操作都是非互動式的)。這在執行apt-get命令的時候格外有用,因為它會不停的提示使用者進行到了哪步並且需要不斷確認。非互動模式會選擇預設的選項並以最快的速度完成構建。但是在源 Dockerfile 中,是使用
ENV
命令進行全域性的設定,這會使該環境變數在整個容器執行過程中都會生效。本應確保只在 Dockerfile 中呼叫的RUN
命令中設定該選項,以避免通過/bin/bash
和容器進行互動時出問題。# 示例 RUN DEBIAN_FRONTEND="noninteractive" apt-get -y install nginx
-
通過
RUN
安裝環境。注意,源 Dockerfile 中將 openjdk-11-jre 的下載安裝註釋掉了,這裡將安裝情況展示出來就能明白了:root@c26b3f28d05f:/# apt install openjdk-11-jre Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: alsa-topology-conf ...... Suggested packages: default-dbus-session-bus ...... fonts-wqy-microhei | fonts-wqy-zenhei fonts-indic mesa-utils The following NEW packages will be installed: alsa-topology-conf ...... 0 upgraded, 111 newly installed, 0 to remove and 11 not upgraded. Need to get 80.8 MB of archives. After this operation, 964 MB of additional disk space will be used. Do you want to continue? [Y/n]
看到 964 MB 的時候,去和之前的解壓後 106 MB 相比,就知道這是多麼愚蠢的一件事了。
-
ADD
命令將源作者打包好的 jre.tar.gz 壓縮包,新增到/home
目錄下解壓,並對/home/jre/bin/java
新增777
許可權。ADD
命令將源作者的 nginxWebUI.sh 指令碼,新增到/home
目錄下,並對其新增777
許可權。 -
COPY
將我們通過 Maven 容器編譯好 jar 包複製到/home/nginxWebUI.jar
。 -
ENTRYPOINT
作為預設入口命令,以["",......]
的形式由exec
呼叫執行。ls -c
讓bash
將一個字串作為完整的命令來執行,/home/nginxWebUI.sh ${BOOT_OPTIONS}
將引數傳入指令碼執行,利用tail -f /dev/null
命令防止容器啟動後退出。
修改 Dockerfile
回顧下在本小節之前,本文中做了哪些工作:簡化壓縮了 的 jre 包;重編譯了 AArch64 的 jar 包。
接下來需要就修改了的檔案對 Dockerfile 進行修改。
FROM ubuntu:20.04
LABEL author="[email protected]" date="2021-7-11" maintainer="[email protected]"
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
RUN apt-get clean && apt-get update &&\
apt-get install -y nginx &&\
apt-get install -y net-tools &&\
apt-get install -y curl &&\
apt-get install -y wget &&\
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone &&\
apt-get install tzdata
ENV LANG C.UTF-8
ADD jre1.8.0_291.tar.gz /home/
RUN chmod 777 /home/jre1.8.0_291/bin/java
ADD nginxWebUI.sh /home/
RUN chmod 777 /home/nginxWebUI.sh
COPY target/nginxWebUI-*.jar /home/nginxWebUI.jar
ENTRYPOINT ["sh","-c", "/home/nginxWebUI.sh ${BOOT_OPTIONS} && tail -f /dev/null"]
- 修改了
LABEL
的內容,由於要生成的新的映象由本人構建,所以維護者(maintainer)是更改為本人郵箱,時間是2021-7-11
,作者保留為源專案作者[email protected]
。 RUN
中刪除了已註釋的安裝 openjdk-11-jre 的命令。- 修改了匯入 jre.tar.gz 的壓縮包為 jre1.8.0_291.tar.gz ,並對對應的
java
可執行程式的路徑進行修改。
指令碼
若檢視 nginxWebUI.sh 指令碼的內容,會發現指令碼中呼叫了匯入的 java
可執行程式,所以也必須對指令碼的內容進行修改。
-
源指令碼內容:
#啟動jar nohup /home/jre/bin/java -jar -Xmx64m /home/nginxWebUI.jar $* > /dev/null &
-
修改
java
可執行程式對應路徑即可:#啟動jar nohup /home/jre1.8.0_291/bin/java -jar -Xmx64m /home/nginxWebUI.jar $* > /dev/null &
構建映象
docker build -t [ACCOUNT]/nginxwebui:2.6.4 .
容器測試
啟動容器
Docker 啟動:
docker run -itd -v /home/nginxWebUI:/home/nginxWebUI -e BOOT_OPTIONS="--server.port=8080" --privileged=true --net=host --name nginxwebui-aarch64 yogile/nginxwebui-aarch64:latest /bin/bash
docker-compose 啟動:
version: "3.2"
services:
nginxWebUi-server:
image: yogile/nginxwebui-aarch64:2.6.4
volumes:
- type: bind
source: "/home/nginxWebUI"
target: "/home/nginxWebUI"
environment:
BOOT_OPTIONS: "--server.port=8080"
privileged: true
network_mode: "host"
注意
由於目前市場上主流的大部分 ARM 平臺處理器的效能並比不上 x86_64 的主流處理器效能,容器內 SpringBoot 專案的執行啟動需要時間。
在本人的樹莓派 4B 上初始化執行時,從建立容器到正式提供服務至少需要大約一分鐘的時間,還請耐心等待。