如果不能正常显示,请查看原文 , 或返回

Ionic 项目 APK 打包容器化部署实践 | 程是非sky

有了问题

基于 Ionic 技术开发的 App,经常有需要构建打包 apk 文件提供给相关人员(产品或测试人员)使用的需求,打包 apk 的过程并不麻烦,只要安装了必要的开发环境,仅需一个打包命令ionic cordova build android --prod --release即可,但是目前这个过程是在开发环境完成的,在这个环境进行操作会造成两个问题:

  • 每次测试人员需要最新的 apk 文件时,需要找前端人员进行打包,增加沟通成本
  • 开发人员每次在本地进行打包和上传时,这个执行 build 命令的动作重复并且耗费时间和精力

作为一个有追求的开发者肯定不能容忍这样的情况,于是有了进一步改进的工作。

关于 Docker

2020 年,Docker 发布至今已经 7 个年头,它也早已不再是一门新的技术,在 2015 年时,开始接触 Docker,中间学习和练习了一段时间,作为前端开发,使用 Docker 的机会并不多,一直没机会在项目实践中使用,正好以此为锲机实践一下。

市面上有很多介绍 Docker 的教程都讲的很好,相关的基础概念就不在这里进行赘述了。

不过,还是要说明一下,因为 Docker 提供了一个虚拟的运行环境,将这个环境迁移到任何一个安装了 Docker 的操作系统中,能够保证环境的一致性,也解决了重新配置环境的问题,这在本项目中是尤其适用的。因为将 Ionic 项目换个环境进行打包时,需要在新环境中安装一系列环境配置和依赖安装,如 ioniccordovaandroidjavanode 等等,这个过程是繁琐的,如果新增一个环境进行项目构建打包,不同的系统环境、环境安装的模块不同版本都有可能带来很多意外的问题。如果通过 Docker 来保证环境的一致性,那么可以实现环境的一次配置,处处使用,便不存在上述问题,多么美好的事情就这样被 Docker 实现了,这也是 Docker 为软件开发行业带来的巨大价值。

本项目的实践背景是在 GitLab 仓库中已经安装集成了 GitLab Runner 基础上进行的,而且很多项目都已经基于 Docker 进行了构建和部署,这些为本次的实践避免了很多基础工作,也提供了很多可以借鉴经验。基于这个情况进行项目的容器化,只需要编写好 Dockerfile 然后配置好 gitlab-ci.yml 文件即可。

如何编写 Docker file

Docker 有三个核心概念: 容器、镜像、仓库。我们知道,程序是运行在系统环境中的,在 Docker 中,它的运行环境就是容器,而且容器环境和容器的宿主机环境基本不会相互影响,而容器是通过 image(镜像) 产生的,也就是说,image 文件可以看作是容器的模板,Docker 把应用程序及其依赖,打包在 image 文件里面,并根据 image 文件生成容器的实例,Docker 中,应用程序就是在拥有程序运行环境的 Docker 容器实例中启动和运行。

Docker 基于镜像文件产生容器,程序在容器中运行,接下来的问题是镜像文件怎么产生呢,这就需要用到 Dockerfile 文件,它是一个文本文件,内容中包含了构建镜像所需的指令和说明,用来配置 image (镜像)。Docker 根据 Dockerfile 文件生成二进制的 image 文件,这个过程中会执行 Dockerfile 中的项目构建命令,同时基于 image 文件启动容器,完成 apk 文件的 build 输出。

手持设备项目中已经存在了一个 Dockerfile,这个 Dockerfile 是针对 web 环境的构建指令,不满足 build apk 的需求,所以需要针对 build apk 的目的重新写一个 Dockerfile。

1
2
3
4
5
6
7
8
9
10
11
12

FROM node:10.11-alpine as builder

WORKDIR /home/node/gtp-pda
COPY . /home/node/gtp-pda
RUN npm config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g
RUN npm set fse_binary_host_mirror https://npm.taobao.org/mirrors/fsevents -g
RUN npm i --verbose --registry=http://xx.xxx.x.xx:4873/
RUN npm run build:web

FROM nginx:latest
COPY --from=builder /home/node/gtp-pda/www/ /usr/share/nginx/html

以上是当前项目中存在的 Dockerfile,可以看出来,此文件中主要包含了两个部分:

  • 基础镜像部分:FROM ...
  • 操作命令部分:WORKDIR ... RUN ...

根据这个思路,对于将要实现的 Dockerfile 文件,我能想到的是,要有一个合适的基础镜像,然后在这个基础镜像中执行 apk build 构建命令。但是我不确定能不能找到合适的适用于 Ionic 项目的基础镜像,如果找不到的话,只能自己去实现这个镜像。

在寻找合适的镜像的过程中,需要用到前面提到了的 Docker 三个核心概念之一 Docker 仓库,Docker 仓库是开发者用来共享自己制作好的 image 文件的地方,Docker Hub 是官方的最常用的 Docker 仓库。在这个仓库中搜索 “Ionic” 关键字,可以找到相关的镜像,在尝试了几个镜像中执行构建命令 ionic cordova build android --prod --release,成功的找到了一个合适的镜像文件 angelvlc/ionic-build

后续的工作便基于 angelvlc/ionic-build 这个镜像环境执行操作命令即可,完整的 Dockerfile 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13

FROM angelvlc/ionic-build as builder

ENV APP=/usr/src/app/gtp-pda

WORKDIR $APP
COPY . $APP

RUN npm install --no-optional --registry=http://xx.xxx.x.xx:4873

RUN ionic cordova build android --prod --release

RUN cp platforms/android/app/build/outputs/apk/release/app-release.apk ./gtp-pda.apk

如何配置 .gitlab-ci.yml

Gitlab CI/CD 是 GitLab 的持续集成工具,为了使用它,需要在项目的根目录中创建 .gitlab-ci.yml 文件,并在文件中定义项目的构建任务脚本,运行的脚本可以包含任务运行的顺序、定义任务触发方式(手动、自动)等操作, 每当开发者提交一个 commit 或者 MR到代码仓库,可以自动或手动触发 GitLab CI/CD 读取该文件开始运行构建任务完成一次持续集成。

.gitlab-ci.yml 配置文件中可以通过 stages 定义构建配置的多个阶段(测试、编译、构建、部署等),因为本次是新增了一个”将项目打包部署至前端服务器”的操作,所以,在 .gitlab-ci.yml 文件中定义了一个新的构建阶段 deploy-upload,这个阶段的构建任务是执行上个步骤编写完成的 Dockerfile 进行项目构建命令 build apk,并将这个 apk 文件部署至前端服务器,下面是这个构建阶段的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
stages:
- build
- test
- deploy
- deploy-upload



deploy-upload:
stage: deploy-upload
script:
- docker image build -t gtp:$CI_COMMIT_SHORT_SHA -f Dockerfile.build -m 4g .
- docker container run --detach --name gtp$CI_COMMIT_SHORT_SHA gtp:$CI_COMMIT_SHORT_SHA
- docker cp gtp$CI_COMMIT_SHORT_SHA:/usr/src/app/gtp-pda/gtp-pda.apk ./
- mv gtp-pda.apk gtp-pda-$CI_COMMIT_SHORT_SHA.apk
- curl -F gtp-pda=@./gtp-pda-$CI_COMMIT_SHORT_SHA.apk http://xx.xxx.x.xx:9000/upload
- echo "访问 http://xx.xxx.x.xx:9000 下载 gtp-pda-$CI_COMMIT_SHORT_SHA.apk"
when: manual
only:
- master
- web
tags:
- node

GiaLab-CI 环境执行 Dockerfile 的过程中相对顺利,很快完成了项目构建产出 apk 的过程,但是在将 apk 文件上传至前端服务器的过程中,遇到了令人头疼的问题,由于 GitLab-CI 环境中禁止使用高级 shell 命令,所以最初通过使用 scpsshpassssh 等方式进行文件上传均没有成功,最后不得不开发一个文件上传服务(如命令所示: curl -F gtp-pda=@./gtp-pda-$CI_COMMIT_SHORT_SHA.apk http://xx.xxx.x.xx:9000/upload ),完成文件上传的操作。

文件上传服务

由于公司的 GitLab CI/CD 环境为了安全对一些高级脚本指令进行了限制,文件上传服务就是为了解决 GitLab CI/CD 环境无法通过高级的 shell 命令进行跨服务器文件上传的问题而开发的项目,原本希望借助开源的力量找到现有的文件上传项目进行使用,但是发现开源的项目中大多数的文件上传项目是基于图片格式的文件上传,还有一些项目要么功能太多或者不符合项目需求,于是决定自研实现这项功能。

项目的实现比较简单,主要分为三部分(两个后端接口一个前端页面):

  • 文件上传的服务接口
  • 文件的目录文件信息扫描接口
  • 上传的文件信息列表(查看和下载)

具体代码和使用详情可查看代码仓库:file-upload

文件上传服务一方面提供了文件上传功能,另一方面将上传的 apk 文件信息进行了遍历和在前端展示和下载,产品测试人员可以通过访问部署的文件服务地址非常方便的按需按CI_COMMIT_SHA下载使用。

返回