最近需要将某docker项目从centos系统迁移到alpine中,因此需要重新编译项目;参考国外某些案例已写好Dockerfile和build.sh中,这里对其主要过程分解并记录一下。

1. 构建发布压缩包

  该步骤主要同项目构建过程相关,需要根据不同情况进行编译;

# 1.make distribution tar.gz
./bootstrap.sh
./configure --with-pkg-extra-version=-r1
make dist
#会发现目录中生成XXX-MyVersion.tar.gz的源码压缩包

  这一步主要是构建代码编译采用的压缩包,确认版本号等过程;读者可以在宿主机上编译出压缩包或编写到Dockerfile和脚本,FROM alpine:edge as source-builder,并在其中安装所需依赖.

2. 编写APKBUILD等文件

  构建.apk包的时候,需要编写自己的APKBUILD文件和其他文件,如下图所示,其中frr为本文需要构建安装包的项目;.pre-install和pre-deinstall等文件,是安装和卸载apk包时所执行脚本;APKBUILD.in为生成APKBUILD文件的模板文件;编写APKBUILD文件时,检查项目中dep依赖库包可以通过alpinelinux官方地址查询。

alpine_abuild_deps

  读者也可以参考abuild官方gitlab地址某标准案例:https://gitlab.alpinelinux.org/alpine/abuild/-/blob/master/sample.APKBUILD
  根据项目实际情况,编写shell脚本以及其中必须的函数prepare(),build(),package(),check();具体可以索引到参考文章alpinelinux的abuild中APKBUILD设置

3. 创建alpine编译容器

#拉取镜像
docker pull alpine:edge
docker run -itd --name alpine-builder alpine:edge
#登录容器
docker exec -it alpine-builder sh
#配置源,如果源慢,可根据依赖库更换国内源;
echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories
#安装构建依赖包,使用本地缓存,升级资源库缓存
apk add --update-cache abuild alpine-conf alpine-sdk py-pip
pip install pytest

  因网速问题,这里容器拉取到上述编译工具包后,已做成容器镜像并上传DockerHub,便于用户拉取使用,读者可自行构造镜像或拉取该容器。

#turbock/alpine-builder:V2镜像已经添加各种编译依赖
docker pull turbock/alpine-builder:V2
#拉取到本地创建容器
docker run -itd --name=alpine-builder turbock/alpine-builder:V2

  在容器中创建编译apk包所需目录和相关配置

docker exec -it alpine-builder sh
setup-apkcache /var/cache/apk
#创建编译安装包目录
mkdir -p /dist/
#创建安装包输出目录
mkdir -p /pkgs/apk
echo 'builder ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

4. 准备alpine构建环境并编译打包

  拷贝源码tarball和apk编译文件到alpine容器相同目录下,此时该目录中应包含上述的XXX.pre-install,XXX.pre-deinstall,APKBUILD以及XXX.tar.gz文件;

#拷贝发布压缩包.tar.gz
docker cp ./*-*.tar.gz  alpine-builder:/dist/
#拷贝alpine目录下APKBUILD等文件到alpine docker中同一路径下,例如/dist/
docker cp ./alpine/. alpine-builder:/dist/
docker exec -it alpine-builder sh

#创建builer用户,并以该用户构建apk包;否则会报错>>> ERROR: : Do not run abuild as root
adduser -D -G abuild builder && chown -R builder /dist /pkgs
su builder
cd /dist
#更新依赖,如需要检验校验码,进行如下操作(可选操作)
abuild deps && abuild-keygen -a -n && abuild checksum && git init
#abuild默认不许用root用户构建,可添加-F参数强制;
#abuild -F deps && abuild-keygen -a -n && abuild -F checksum && git init
#构建APK
abuild -r -P /pkgs/apk
#abuild -F -r -P /pkgs/apk

最后可以在/pkgs/apk目录中查到apk包

  • 问题1:报错 Checking sanity of /dist/APKBUILD...ERROR: 7.3.1-2.6.1 is not a valid version
    解决方法:abuild对版本号格式有约束,通过下图可知对应版本号格式,例如1.0.0-r0,参考文章:APKBUILD_Reference
    abuild-version

  • 问题2:报错cc1plus: all warnings being treated as errors
    解决方法:设置环境变量;c工程设置export CFLAGS="-Wno-error";c++工程设置export CXXFLAGS="-Wno-error";

  • 问题3:报错Tracing dependencies... ERROR: /usr/lib/libprotobuf-c.so.1.0.0: Could not find owner package
    解决方法:依赖项可能为用户自定义依赖库,或第三方库。编译安装包最后步骤,会默认会检查依赖库关系;这个需要注意几个地方,需要在编译Makefile文件中添加-lprotobuf-c,安装该apk模块apk add protobuf-c,并写入APKBUILD文件的依赖项检查中。

5. Abuild范式了解(类似rpmbuild)

Abuild官方wiki文档,这里将abuild范式罗列如下

$ abuild -h
usage: abuild [options] [-P REPODEST] [-s SRCDEST] [-D DESCRIPTION] [cmd] ...
       abuild [-c] -n PKGNAME[-PKGVER]
Options:
 -A  Print CARCH and exit
 -c  Enable colored output
 -d  Disable dependency checking
 -D  Set APKINDEX description (default: $repo $(git describe))
 -f  Force specified cmd (skip checks: apk up to date, arch, libc)
 -F  Force run as root
 -h  Show this help
 -k  Keep built packages, even if APKBUILD or sources are newer
 -K  Keep buildtime temp dirs and files (srcdir/pkgdir/deps)
 -m  Disable colors (monochrome)
 -P  Set REPODEST as the repository location for created packages
 -q  Quiet
 -r  Install missing dependencies from system repository (using sudo)
 -s  Set source package destination directory
 -v  Verbose: show every command as it is run (very noisy)

Commands:
  build       Compile and install package into $pkgdir
  check       Run any defined tests concerning the package
  checksum    Generate checksum to be included in APKBUILD
  clean       Remove temp build and install dirs
  cleancache  Remove downloaded files from $SRCDEST
  cleanoldpkg Remove binary packages except current version
  cleanpkg    Remove already built binary and source package
  deps        Install packages listed in makedepends and depends
  fetch       Fetch sources to $SRCDEST (consider: 'abuild fetch verify')
  index       Regenerate indexes in $REPODEST
  listpkg     List target packages
  package     Install project into
  prepare     Apply patches
  rootbld     Build package in clean chroot
  rootpkg     Run 'package', the split functions and create apks as fakeroot
  sanitycheck Basic sanity check of APKBUILD
  snapshot    Create a $giturl or $svnurl snapshot and upload to $disturl
  sourcecheck Check if remote source package exists upstream
  srcpkg      Make a source package
  undeps      Uninstall packages listed in makedepends and depends
  unpack      Unpack sources to $srcdir
  up2date     Compare target and sources dates
  verify      Verify checksums

To activate cross compilation specify in environment:
  CHOST       Arch or hostspec of machine to generate packages for
  CTARGET     Arch or hostspec of machine to generate compiler for

本文源站链接:Alpine编译.apk安装包

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐