前言
nginxWebUI 項目並非本人所寫,其國內國內項目地址: Gitee nginxWebUI ,官網:nginxWebUI.cn。
由於源項目並未提供 ARM 平台的適配,但是該項目提供了 Dockerfile 文件,我們可以根據 Dockerfile 的說明和項目的源碼,進行 ARM 平台下的重編譯和 Docker 容器構建。
非 ARM 平台的,也可以按照本文進行本平台的實戰測試。
Java
對於源項目的源碼來說,已經打包好了 x86_64 平台的 jar.tar.gz 包,該包內包含的 java 可執行程序是無法被用於 ARM 平台下運行。所以,雖然 arm64 系統的 Docker 可以下載源項目的鏡像並保持容器的運行,但是實際上, ADD
到鏡像內部的 jre 和 jar 包都是不能順利執行的。
我們需要重新將 AArch64 的 jre 重新打包並用於容器構建。
下載
可以通過訪問甲骨文(Oracle)的 jdk 下載官網,下載 AArch64 的 jdk 進行過濾打包: Oracle Java 8 。
實際上,Oracle 提供了 Java 8 和 Java 11 兩個穩定版本的 AArch64 的 rpm 和 tar.gz (Compressed Archive)。但是為了使容器盡量的精簡,這里使用 Java 8 來進行過濾打包。
簡化過濾壓縮
-
對下載得到的 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 ./jre1.8.0_291/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="cym1102@qq.com"
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
-
維護者為 cym1102@qq.com
-
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
命令防止容器啟動后退出(利用tail -f /dev/null命令防止container啟動后退出)。
修改 Dockerfile
回顧下在本小節之前,本文中做了哪些工作:簡化壓縮了 的 jre 包;重編譯了 AArch64 的 jar 包。
接下來需要就修改了的文件對 Dockerfile 進行修改。
FROM ubuntu:20.04
LABEL author="cym1102@qq.com" date="2021-7-11" maintainer="xxxxxxxs@qq.com"
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
,作者保留為源項目作者cym1102@qq.com
。 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 上初始化運行時,從創建容器到正式提供服務至少需要大約一分鍾的時間,還請耐心等待。