前言

最近一年多以来,我开展了一些与鸿蒙相关的开发工作。

在开发过程中,我做了一些自用的效率工具,其中一个就是容器化的鸿蒙环境。

现在我把这个自用的工具开源了:https://github.com/hqzing/dockerharmony

这个鸿蒙容器使我们能够使用 Linux 服务器来运行和测试我们的命令行程序,而不用依赖 OpenHarmony 物理设备。

环境准备

要使用这个鸿蒙容器,你首先要有一个 Docker 运行环境,最好是 arm64 的硬件,例如 arm 服务器、Mac 电脑、鸿蒙 PC 等。如果没有 arm64 硬件,则需要通过 QEMU 进行指令集翻译,性能极差。

推荐使用 arm 服务器,并且买在香港或国外的区域(阿里云、华为云等云厂商有卖)。因为后续你可能会需要从 GitHub 下载各种开源软件,如果你的服务器位于中国大陆区域,可能很多软件会下载不下来。

鸿蒙 PC 原生环境不支持 Docker 和 Podman 等容器技术,但可以在“融合开发引擎”(官方虚拟机)中使用 Podman 来运行容器。具体配置步骤请参见文末的附录。

基础用法

这个镜像同时上传到了 Docker Hub 和 GitHub Container Registry,你可以任选其一,从上面下载这个镜像使用。

从 Docker Hub 拉取镜像并运行

docker pull hqzing/dockerharmony:latest
docker run -itd --name=ohos hqzing/dockerharmony:latest
docker exec -it ohos sh

从 GitHub Container Registry 拉取镜像并运行

docker pull ghcr.io/hqzing/dockerharmony:latest
docker run -itd --name=ohos ghcr.io/hqzing/dockerharmony:latest
docker exec -it ohos sh

工具获取

为了保持轻量,这个容器内默认只包含了一个最小化系统(除 toybox 提供的少量基础命令和我内置的 curl 外,不含其他开发工具)。

为了支撑实际的开发工作,我们需要根据需求往里面安装工具。

1. 快捷安装:使用 Harmonybrew 包管理器

目前,Harmonybrew 项目已经可用。你可以在容器中直接安装此包管理器,像在普通 Linux 或 Mac 上一样,一键下载、更新和管理你需要的软件包。

项目主页:https://atomgit.com/Harmonybrew

2. 手动获取:已移植的常用工具链

如果你想手动集成,或者参考相关工具的编译方法,也可以直接使用我已经针对 OpenHarmony 平台移植并验证好的核心包。

工具 项目地址
coreutils https://github.com/Harmonybrew/ohos-coreutils
busybox https://github.com/Harmonybrew/ohos-busybox
grep https://github.com/Harmonybrew/ohos-grep
gawk https://github.com/Harmonybrew/ohos-gawk
make https://github.com/Harmonybrew/ohos-make
tar https://github.com/Harmonybrew/ohos-tar
gzip https://github.com/Harmonybrew/ohos-gzip
patch https://github.com/Harmonybrew/ohos-patch
diffutils https://github.com/Harmonybrew/ohos-diffutils
perl https://github.com/Harmonybrew/ohos-perl
m4 https://github.com/Harmonybrew/ohos-m4
autoconf https://github.com/Harmonybrew/ohos-autoconf
texinfo https://github.com/Harmonybrew/ohos-texinfo
git https://github.com/Harmonybrew/ohos-git
ruby https://github.com/Harmonybrew/ohos-ruby
zsh https://github.com/Harmonybrew/ohos-zsh
bash https://github.com/Harmonybrew/ohos-bash
vim https://github.com/Harmonybrew/ohos-vim
openssh https://github.com/Harmonybrew/ohos-openssh
python https://github.com/Harmonybrew/ohos-python

当然,你也可以根据 DockerHarmony 项目 README 中的操作指南,直接去 Alpine Linux 的软件仓库获取,或者寻找其他社区开发者移植好的产物。

实践案例

这个鸿蒙容器,搭配上面给出的这些工具一起使用,再加上 ohos-sdk,就可以胜任很多开发工作了。

上面贴出来的各种 ohos-xxx 工具里面,除少量是在 Ubuntu 上面交叉编译出来以外,大部分都是在鸿蒙容器中原生编译出来的。你可以尝试模仿这些项目里面的做法,把鸿蒙容器作为编译环境或测试环境使用。

迭代过程

这个鸿蒙容器截止到现在已经经历了 3 个版本迭代,现在开源出来的是最后一个最成熟的版本。

第 1 个版本:早期最简版本

最开始做的时候,OpenHarmony 还是 4.0 版本。当时只要编一份 arm64 架构的 rk3568 镜像,把里面的 ramdisk.img 解压、打成 tar 包、导入到 Docker 中就能直接用。

因为当时我找到的官方 rk3568 镜像只有 32 位的,而我编的软件要在 64 位系统上进行测试,所以需要自己编 64 位的系统。

第 2 个版本:事情逐渐变得复杂

到了 OpenHarmony 5.1 版本的时候,我对环境进行了一次升级。这时候发现 OpenHarmony 官方社区的日构建流水线里面就有提供 dayu200-arm64_5.1.0-Release 的产物,不用我自己去编 64 位系统了。

但是这个新版本带来了一个新问题:单把 ramdisk.img 里面的内容导到 Docker 里面是跑不起来的,因为这里面的 toybox 被改造了,它依赖了一个 system.img 里面的 so。我不得不分别从两个镜像各取一部分内容,放在一起,导入到 Docker 中。

第 3 个版本:需要改造系统源码

升级完版本之后,发现它时不时会在各进程的 stderr 里面输出一些类似于 HiLogAdapter: Can't connect to server. 这样的报错。

定位之后发现是 OpenHarmony 社区把 musl libc 进行了改造,做了很多日志输出,而且日志是对接到 HiLog 里面的。我在容器里面没有启动 init 进程,也没把 HiLog 相关的东西带进来,容器中自然就不会有 HiLog 服务,于是 musl libc 没法通过 socket 跟 HiLog 服务进行通信,因此就时不时会有错误日志从各个进程的 stderr 里面冒出来,这会在一些情况下会导致业务异常。

为了处理这个问题,我只好放弃使用 OpenHarmony 官方编好的包,又换回了自己编包的方案。只有这样做,我才能通过改源码的方式去处理这个 musl libc 对 HiLog 的依赖问题。

附录:在鸿蒙 PC 中使用鸿蒙容器

鸿蒙 PC 原生环境无法使用 Docker 和 Podman 等工具,在“融合开发引擎”中也因为缺少内核选项而无法使用 Docker,但 Podman 是可用的。我们可以在“融合开发引擎”中使用 Podman 来运行鸿蒙容器。

操作步骤如下:

# 创建 Podman 配置文件
sudo mkdir -p /etc/containers

sudo tee /etc/containers/storage.conf << 'EOF' > /dev/null
[storage]
# 1. 驱动设置为 vfs
driver = "vfs"
# 2. 设置 runroot
runroot = "/run/containers/storage"
# 3. 设置数据持久化目录
graphroot = "/var/lib/containers/storage"

[storage.options]
# 4. 【关键】确保这一行被注释掉(前面加 #),或者是空的
# mount_program = "/usr/bin/fuse-overlayfs"
EOF

# 安装 Podman
sudo dnf update -y
sudo dnf install podman -y

# 创建并挂载 cgroup
sudo mkdir -p /sys/fs/cgroup
sudo mount -t cgroup2 cgroup2 /sys/fs/cgroup

# 运行鸿蒙容器(注意网络模式必须是 host)
sudo podman pull ghcr.io/hqzing/dockerharmony:latest
sudo podman run \
  -itd \
  --name=ohos \
  --network=host \
  --cgroup-manager=cgroupfs \
  --pids-limit=-1 \
  ghcr.io/hqzing/dockerharmony:latest
sudo podman exec -it ohos sh

此配置方法参考了 B 站用户 @零炻 分享的笔记:https://my.feishu.cn/wiki/FnmSwU70jihXLtkJ1zKcICeenVc

Logo

赋能鸿蒙PC开发者,共建全场景原生生态,共享一次开发多端部署创新价值。

更多推荐