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

簡化過濾壓縮

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


免責聲明!

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



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