制作JavaCV应用依赖的基础Docker镜像(CentOS7+JDK8+OpenCV4)

欢迎访问我的GitHub

https://github.com/zq2599/blog_demos

内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;

本篇概览

在这里插入图片描述

实战内容

  • 为了减少环境和软件差异的影响,让程序的运行调试更简单,也为了让应用可以在容器环境运行,最终整个应用会被制作成docker镜像,所以咱们的目标被设定为下面三项:
  1. 开发出java版的物体识别应用
  2. 将此应用制作成docker镜像
  3. 在docker环境运行这个应用
  • 基于上述目标,我们可以确定以下操作步骤:
  1. 准备好docker基础镜像
  2. 开发java应用
  3. 将java应用打包成package文件,集成到基础镜像中,得到最终的java应用镜像
  • 整个流程如下图所示:
在这里插入图片描述
  • 本篇的目标就是上述第一步:准备好docker基础镜像

制作基础镜像

  • 如果您有过制作java应用镜像的经历,一定会产生疑问:如下图红框所示,一般不都是把OpenJDK的官方镜像作为基础镜像吗?为啥要用一篇文章来讲基础镜像的事情?
在这里插入图片描述
  • 对于物体检测的应用来说,OpenJDK的官方镜像是不够用的,因为用java实现检测需要一个关键技术:javacv,在javacv运行过程中需要用到opencv的一些本地库,因此需要在运行环境中安装opencv

  • 如下图所示,一个应用自下而上由六部分构成,如果将底部的操作系统、JDK、OpenCV做成基础镜像就方便多了,咱们开发应用的时候只要需关注上面三层即可,而上面三层不就是个普通的maven工程吗?

在这里插入图片描述
  • 至此,聪明的您对接下来要做的事情应该很清楚了:编写Dockerfile文件用来制作镜像,这个镜像中要有CentOS7 + JDK1.8 + OpenCV4

分两步走

  • 我打算先做一个CentOS7 + JDK8的镜像,在此基础上再做一个集成了OpenCV的镜像,这样在一些不需要OpenCV的场景中,我还能单独使用CentOS7 + JDK1.8的镜像
  • 分析完成,开始动手吧

CentOS7 + JDK8的镜像

  • 之所以选择CentOS作为操作系统,是因为平时工作中最常用的就是它了

  • 纵观OpenJDK官方的各种镜像,并没有发现CentOS作为操作系统的,因此自己动手做一个吧,思路很简单:找到OpenJDK的Dockerfile文件,把它的基础镜像换成CentOS7.6即可

  • 以下是Dockerfile的所有内容,可见核心是根据不同的操作系统下载文件然后安装,逻辑简单清晰就不多说了:

FROM centos:7.6.1810

RUN set -eux; \
    yum install -y \
        gzip \
        tar \
        binutils \
        freetype fontconfig \
    ;

ENV JAVA_HOME /usr/java/openjdk-8
ENV PATH $JAVA_HOME/bin:$PATH

# Default to UTF-8 file.encoding
ENV LANG C.UTF-8

RUN set -eux; \
    \
    arch="$(objdump="$(command -v objdump)" && objdump --file-headers "$objdump" | awk -F '[:,]+[[:space:]]+' '$1 == "architecture" { print $2 }')"; \
    case "$arch" in \
        'i386:x86-64') \
            downloadUrl='https://github.com/AdoptOpenJDK/openjdk8-upstream-binaries/releases/download/jdk8u292-b10/OpenJDK8U-jdk_x64_linux_8u292b10.tar.gz'; \
            ;; \
        'aarch64') \
            downloadUrl='https://github.com/AdoptOpenJDK/openjdk8-upstream-binaries/releases/download/jdk8u292-b10/OpenJDK8U-jdk_aarch64_linux_8u292b10.tar.gz'; \
            ;; \
        *) echo >&2 "error: unsupported architecture: '$arch'"; exit 1 ;; \
    esac; \
    \
    curl -fL -o openjdk.tgz "$downloadUrl"; \
    curl -fL -o openjdk.tgz.asc "$downloadUrl.sign"; \
    \
    export GNUPGHOME="$(mktemp -d)"; \
# pre-fetch Andrew Haley's (the OpenJDK 8 and 11 Updates OpenJDK project lead) key so we can verify that the OpenJDK key was signed by it
# (https://github.com/docker-library/openjdk/pull/322#discussion_r286839190)
# we pre-fetch this so that the signature it makes on the OpenJDK key can survive "import-clean" in gpg
    gpg --batch --keyserver keyserver.ubuntu.com --recv-keys EAC843EBD3EFDB98CC772FADA5CD6035332FA671; \
# TODO find a good link for users to verify this key is right (https://mail.openjdk.java.net/pipermail/jdk-updates-dev/2019-April/000951.html is one of the only mentions of it I can find); perhaps a note added to https://adoptopenjdk.net/upstream.html would make sense?
# no-self-sigs-only: https://salsa.debian.org/debian/gnupg2/commit/c93ca04a53569916308b369c8b218dad5ae8fe07
    gpg --batch --keyserver keyserver.ubuntu.com --keyserver-options no-self-sigs-only --recv-keys CA5F11C6CE22644D42C6AC4492EF8D39DC13168F; \
    gpg --batch --list-sigs --keyid-format 0xLONG CA5F11C6CE22644D42C6AC4492EF8D39DC13168F \
        | tee /dev/stderr \
        | grep '0xA5CD6035332FA671' \
        | grep 'Andrew Haley'; \
    gpg --batch --verify openjdk.tgz.asc openjdk.tgz; \
    rm -rf "$GNUPGHOME"; \
    \
    mkdir -p "$JAVA_HOME"; \
    tar --extract \
        --file openjdk.tgz \
        --directory "$JAVA_HOME" \
        --strip-components 1 \
        --no-same-owner \
    ; \
    rm openjdk.tgz*; \
    \
    rm -rf "$JAVA_HOME/jre/lib/security/cacerts"; \
# see "update-ca-trust" script which creates/maintains this cacerts bundle
    ln -sT /etc/pki/ca-trust/extracted/java/cacerts "$JAVA_HOME/jre/lib/security/cacerts"; \
    \
# https://github.com/oracle/docker-images/blob/a56e0d1ed968ff669d2e2ba8a1483d0f3acc80c0/OracleJava/java-8/Dockerfile#L17-L19
    ln -sfT "$JAVA_HOME" /usr/java/default; \
    ln -sfT "$JAVA_HOME" /usr/java/latest; \
    for bin in "$JAVA_HOME/bin/"*; do \
        base="$(basename "$bin")"; \
        [ ! -e "/usr/bin/$base" ]; \
        alternatives --install "/usr/bin/$base" "$base" "$bin" 20000; \
    done; \
    \
# basic smoke test
    javac -version; \
    java -version
  • 写完之后执行<font color="blue">docker build -t bolingcavalry/centos7.6-jdk8:0.0.1 .</font>即可生成镜像,如果您有hub.docker.com的账号,还可以将其推送到中央仓库,给更多人使用

  • 用history命令看看镜像内容,详情如下,合计五百多兆,已经不小了:

will@Mac-mini$ docker history bolingcavalry/centos7.6-jdk8:0.0.1
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
a5dead4a6505   2 days ago    /bin/sh -c set -eux;         arch="$(objdump…   209MB     
<missing>      2 days ago    /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B        
<missing>      2 days ago    /bin/sh -c #(nop)  ENV PATH=/usr/java/openjd…   0B        
<missing>      2 days ago    /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/java/o…   0B        
<missing>      2 days ago    /bin/sh -c set -eux;     yum install -y     …   144MB     
<missing>      2 years ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      2 years ago   /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
<missing>      2 years ago   /bin/sh -c #(nop) ADD file:54b004357379717df…   202MB
  • 我这里已经推送到hub.docker.com上去了,执行以下命令即可下载到本地:
docker pull bolingcavalry/centos7.6-jdk8:0.0.3

CentOS7+JDK8+OpenCV4镜像

  • 接下来可以集成OpenCV4了,这里有两个关键点需要注意:
  1. 受到JavaCV依赖的约束,OpenCV的版本要用<font color="red">4.5.3</font>
  2. OpenCV编译的时候要求cmake版本是3.x,因此需要下载cmake对应版本
  • 最终,Dockerfile内容如下,基础镜像是前面做好的<font color="blue">bolingcavalry/centos7.6-jdk8:0.0.1</font>,先是安装一大堆编译所需的应用,然后下载cmake并安装,再下载OpenCV-4.5.3版本的源码然后编译,就这么简单(但其间的调试工作还是不少的,不说了,说多了都是泪):
FROM bolingcavalry/centos7.6-jdk8:0.0.1

RUN echo "export LC_ALL=en_US.UTF-8"  >>  /etc/profile \
    && source /etc/profile

RUN set -eux; \
    yum install -y \
        make \
        gcc \
        gcc-c++ \
        gtk+-devel \
        gimp-devel \
        gimp-devel-tools \
        gimp-help-browser \
        zlib-devel \
        libtiff-devel \
        libjpeg-devel \
        libpng-devel \
        gstreamer-devel \
        libavc1394-devel \
        libraw1394-devel \
        libdc1394-devel \
        jasper-devel \
        jasper-utils \
        swig \
        python \
        libtool \
        nasm \
        build-essential \
        ant \
        unzip \
    ;

RUN set -eux; \
    curl -fL -o cmake-3.12.2-Linux-x86_64.tar.gz https://cmake.org/files/v3.12/cmake-3.12.2-Linux-x86_64.tar.gz \
    && tar -zxvf cmake-3.12.2-Linux-x86_64.tar.gz \
    && mv cmake-3.12.2-Linux-x86_64 cmake-3.12.2 \
    && ln -sf /cmake-3.12.2/bin/* /usr/bin; \
    curl -fL -o opencv-4.5.3.zip https://codeload.github.com/opencv/opencv/zip/4.5.3; \
    unzip opencv-4.5.3.zip; \
    rm -rf opencv-4.5.3.zip; \
    cd opencv-4.5.3; \
    mkdir build; \
    cd build; \
    cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..; \
    make; \
    make install; \
    cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTS=OFF ..;\
    make -j8; \
    make install
  • 执行命令<font color="blue">docker build -t bolingcavalry/opencv4.5.3:0.0.1 .</font>即可生成镜像,如果您有hub.docker.com的账号,还可以将其推送到中央仓库,给更多人使用

  • 用history命令看看镜像内容,详情如下,倒吸一口凉气,这么大的体积,亲爱的读者们会不会打死我...:

will@Mac-mini centos7-jdk8 % docker history bolingcavalry/opencv4.5.3:0.0.1
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
d1518ffa4699   5 days ago     RUN /bin/sh -c set -eux;     curl -fL -o cma…   819MB     buildkit.dockerfile.v0
<missing>      5 days ago     RUN /bin/sh -c set -eux;     yum install -y …   637MB     buildkit.dockerfile.v0
<missing>      5 days ago     RUN /bin/sh -c echo "export LC_ALL=en_US.UTF…   1.84kB    buildkit.dockerfile.v0
<missing>      3 months ago   /bin/sh -c set -eux;         arch="$(objdump…   209MB     
<missing>      3 months ago   /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B        
<missing>      3 months ago   /bin/sh -c #(nop)  ENV PATH=/usr/java/openjd…   0B        
<missing>      3 months ago   /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/java/o…   0B        
<missing>      3 months ago   /bin/sh -c set -eux;     yum install -y     …   144MB     
<missing>      2 years ago    /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      2 years ago    /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
<missing>      2 years ago    /bin/sh -c #(nop) ADD file:54b004357379717df…   202MB
  • 我这里已经推送到hub.docker.com上去了,执行以下命令即可下载到本地:
docker pull bolingcavalry/opencv4.5.3:0.0.1
  • 这里要提醒一下,opencv的编译是非常耗时的,请确保docker宿主机的性能不要太差,也请您耐心等待编译过程

  • 至此,符合咱们要求的基础镜像<font color="blue">opencv4.5.3:0.0.1</font>已制作完成,有了它,咱们的Java应用所需的jdk和opencv就凑齐了,在开发javacv相关的应用时,以它为基础镜像就无需再为环境和依赖库操心,终于可以聚焦java开发了

你不孤单,欣宸原创一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列

欢迎关注公众号:程序员欣宸

微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界...

https://github.com/zq2599/blog_demos

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容