1. 程式人生 > 其它 >Docker 構建 nginxWebUI 容器實戰

Docker 構建 nginxWebUI 容器實戰

前言

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 來進行過濾打包。

jre https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html

解壓 https://blog.csdn.net/laobai1015/article/details/89405905

簡化過濾壓縮

  1. 對下載得到的 jdk-8u291-linux-aarch64.tar.gz 進行解壓。

    tar -zxvf jdk-8u291-linux-aarch64.tar.gz
    
  2. 提取出要用的兩部分,複製 ./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
    
  3. 重新壓縮打包為 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 環境 來進行編譯打包。

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 -cbash 將一個字串作為完整的命令來執行,/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 上初始化執行時,從建立容器到正式提供服務至少需要大約一分鐘的時間,還請耐心等待。