构建Docker Android开发基础镜像

本文详细记录了在Docker环境下构建包含Java JRE和Node.js环境的基础镜像的过程,包括遇到的网络问题、离线安装Node.js的尝试以及最终选用Alpine为基础镜像的解决方案。在解决了一系列问题后,还添加了Android开发所需的完整JDK、Android SDK和Gradle,但这也导致镜像体积增大。同时,文中提到了构建过程中遇到的aapt2缺失、内网环境下Gradle下载和Maven依赖的问题及其解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

构建Docker Android开发基础镜像

一、需求

项目有功能需要调用 npm命令。

后端代码中使用的是 **java.lang.Runtime **类调用命令,但是默认Docker基础镜像是 openjdk:8-jre-slim,并不包含nodejs环境。

经过数次试错,最终决定更换基础镜像,更换为自己构建的包含jre和nodejs的基础镜像。

二、试错

下面是之前走过的一些弯路,也写出来让大家可以避免。

1. apt 安装 nodejs

直接在dockerfile中添加

RUN apt install nodejs npm

但是由于内网网络环境的关系,无法安装。

2. 离线安装 nodejs

大致的Dockerfile是这样的

# nodejs 环境变量
ENV NODEJS_HOME /usr/local/lib/nodejs/node-v16.13.1/bin
ENV PATH $NODEJS_HOME:$PATH

// 解压
ADD node-v16.13.1-linux-x64.tar.xz /usr/local/lib/nodejs/

WORKDIR /usr/local/lib/nodejs/
# 换源
RUN mv node-v16.13.1-linux-x64/ node-v16.13.1/ \
    && npm config set registry http://nexus.simulate.com:8081/repository/npm-group/ \
    && npm install -g hdec-mobile

一些尝试:

  • 从nodejs官网下载 Linux 二进制文件,默认下载的是 .tar.xz 格式的压缩包,无奈容器中没有 xz 包,所以无法解压。
  • 将 .tar.xz 在本地先解压为 .tar,再上传,构建报错 tar: Skipping to next header
  • 从nodejs官网下载 .tar.gz 格式的压缩包,报错 gzip: stdin: not in gzip format
  • 修改容器 apt 源为 nexus.simulate.com:8001 下的地址,但是宿主机和容器无法ping通,经过咨询蔡永健蔡哥,知道是由于docker默认网桥是172.17.x.x,nexus.simulate.com的ip也是172.17.x.x,有冲突,在ping nexus.simulate.com 的时候,会先经过网桥,不会到nexus.simulate.com,这个问题由黄艺文文姐解决之后,修改网桥为 172.19.x.x,宿主机可以ping通nexus,但是容器内使用cat命令修改/etc/apt/sources.list文件来更换apt源,报404,这个时候我的基础镜像也做好了,就没有再做深究。

三、最终方案

最终方案就是更换基础镜像,自己做一个符合需求的基础镜像。

经过查询一些资料,对比dockerhub上基础镜像的大小,决定使用 alpine 作为基础镜像,添加jre和nodejs环境,形成自己的基础镜像。

构建基础镜像的 Dockerfile 如下:

FROM alpine:latest

# 更换国内源
RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/latest-stable/main/" > /etc/apk/repositories
RUN echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories

RUN apk add wget
#dumb-init
RUN wget -O /usr/local/bin/dumb-init https://gitee.com/ji-yy/dumb-init/attach_files/928072/download/dumb-init_1.2.5_amd64
RUN chmod +x /usr/local/bin/dumb-init
#nodejs npm netstat 7zip jre
RUN apk add nodejs && apk add npm && apk add net-tools && apk add p7zip && apk add openjdk8-jre-base

ENV LANG en_US.UTF-8
ENV TZ=Asia/Shanghai

还是比较简短的,alpine 的 apk add 命令可以安装很多包,具体有哪些可以查看官方地址 Alpine Linux packages ,这里没有搜到openjdk,但是阿里和清华的国内镜像源是有的,可以查看 阿里源-alpine-community ,这里使用的也是 jdk8,与项目保持一致。

使用 docker build 命令构建后,生成基础镜像,上传到公司docker仓库,页面显示镜像大小为 76.52MB,大小还是可以接受的。

构建完基础镜像,其实项目的Dockerfile相较于凤翎默认的Dockerfile就不需要做多少改动,主要是修改 FROM 的基础镜像,改为自己的地址。

打完的项目docker镜像有 150.38MB ,可以接受。

四、补充

其实最终需求是可以在容器内执行 cordova build android 命令构建 apk,所以只是有jre和nodejs环境,还不满足android开发,需要安装完整的 jdk、android sdk、gradle等。

最终的基础镜像的Dockerfile如下。

FROM alpine:latest

# 更换国内源
RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/latest-stable/main/" > /etc/apk/repositories
RUN echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories

WORKDIR /usr/bin/
# android commandlinetools
COPY commandlinetools-linux-7583922_latest.zip androidsdk/
RUN unzip androidsdk/commandlinetools-linux-7583922_latest.zip -d androidsdk/ && rm androidsdk/commandlinetools-linux-7583922_latest.zip
ENV ANDROID_SDK_ROOT /usr/bin/androidsdk
ENV PATH ${ANDROID_SDK_ROOT}/cmdline-tools/bin:$PATH
ENV PATH ${ANDROID_SDK_ROOT}/platform-tools/bin:$PATH

WORKDIR /opt/gradle/
COPY glibc.apk /tmp/
COPY glibc-bin.apk /tmp/
#wget
RUN apk add wget && wget -O /usr/local/bin/dumb-init https://gitee.com/ji-yy/dumb-init/attach_files/928072/download/dumb-init_1.2.5_amd64 \
    && wget https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -O /etc/apk/keys/sgerrand.rsa.pub \
    && wget -P /opt/gradle/ https://services.gradle.org/distributions/gradle-6.5-all.zip \
    && mkdir -p wrapper/dists/gradle-6.5-all/2oz4ud9k3tuxjg84bbf55q0tn/ \
    && unzip gradle-6.5-all.zip -d wrapper/dists/ \
    && mv gradle-6.5-all.zip wrapper/dists/gradle-6.5-all/2oz4ud9k3tuxjg84bbf55q0tn/ \
    && chmod +x /usr/local/bin/dumb-init \
    && apk add --no-cache /tmp/glibc.apk /tmp/glibc-bin.apk

WORKDIR /home/jdk/
#nodejs npm net-tools jdk android-tools
RUN apk add vim && apk add nodejs && apk add npm && apk add net-tools && apk add openjdk8

ENV GRADLE_USER_HOME /opt/gradle
ENV PATH $PATH:/opt/gradle/wrapper/dists/gradle-6.5/bin

ENV JAVA_HOME /usr/lib/jvm/java-1.8-openjdk
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

ENV LANG en_US.UTF-8
ENV TZ=Asia/Shanghai

# 安装
RUN echo y | sdkmanager --sdk_root=/usr/bin/androidsdk/ "platform-tools" "platforms;android-29" "build-tools;30.0.2" && sdkmanager --sdk_root=/usr/bin/androidsdk/ --uninstall emulator

主要是以下几处修改:

  • jre 换成 完整 jdk

  • 下载 android commandlinetools,使用里面的 sdkmanager 安装 android所需的工具依赖等

  • 添加 gradle

做完这些,基础镜像的体积也来到了 1.33G,后面可以研究下是否有精简的空间。

五、问题

1. 执行build报错,没有找到aapt2

参考 https://www.codenong.com/cs109720136/ ,安装缺少的三个包即可。

2. 内网环境会重新下载 gradle

查看 gradle-wrapper.properties,内容如下:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-6.5-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

会去 $GRADLE_USER_HOME/wrapper/dists/ 下寻找对应的压缩包。
GRADLE_USER_HOME 在 linux 下默认为 ~/.gradle

将 下载好的 gradle-6.5-all.zip 放到 wrapper/dists/gradle-6.5-all/2oz4ud9k3tuxjg84bbf55q0tn/ 下即可。

2oz4ud9k3tuxjg84bbf55q0tn 每个版本是不同的,可以参考能访问外网的主机上对应版本的文件夹名称。

3. 内网环境下需要下载maven依赖

在 nexus 增加 google() jcenter() mavenCentral() 的代理
google(): https://dl.google.com/dl/android/maven2/
jcenter(): https://jcenter.bintray.com/
mavenCentral(): https://repo.maven.apache.org/maven2

需要在能访问外网并可以访问nexus的主机上,先执行一遍 cordova build android,将所需的依赖导入nexus,才能在内网环境的服务器下载依赖。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值