最近又开始写qqbot,因为OPQBot针对linux/amd64平台做出了限制,很多东西无法实现,而我手上除了一台vps以外又没有其他平台的机子用来24h跑bot,所以想到在Docker的跨平台容器里跑opq
About Buildx
BuildKit是下一代的Docker镜像构建工具,来源于Moby/BuildKit。在最新的Docker Desktop和Docker CE中,官方以Buildx形式集成到Docker CLI中,不再需要额外构建添加。
使用Buildx,开发者可以轻松构建不同平台镜像
在本地安装使用Buildx构建多平台镜像
在最新的Docker Desktop以及Docker CE中已经集成了Buildx,但是并未启用多平台构建,为了启用此特性,需要做以下操作:
1. 安装qemu多平台支持
运行以下容器:
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
该容器会为你的设备安装qemu多平台支持,如果你需要运行跨平台容器,也会用到它。
2. 创建新的builder实例并设为默认
docker buildx create --use --name mybuilder
看到输出mybuilder
即表示创建成功,使用--use
指令将在builder实例创建完成时自动将其设为默认,否则需要手动使用docker buildx use mybuilder
将创建的实例设为默认。
3. 使用Buildx构建多平台镜像
Buildx的使用与docker build十分相似,基本上只需要将命令中的docker build
替换成docker buildx build
即可。如果使用docker buildx install
将默认的docker build替换为Buildx,那么直接使用docker build
即可。
例如,将当前目录下的Dockerfile文件打包成镜像,需要使用以下命令:
docker buildx build -t xxx/xxx:tag . --push
如果替换了默认docker build,将是这样的:
docker build -t xxx/xxx:tag . --push
--push
指令会自动把构建好的镜像推送到远端仓库,否则只会在存放在cache中。
如果要构建多平台镜像,在指令中加入--platform=
即可,等号后填写需要构建的平台,如linux/arm
,linux/arm64
,linux/amd64
等,用,
隔开。Dockerfile本身并不需要做出更改,除非你需要做的操作在不同平台下有所区别,比如根据平台下载不同文件等。
docker buildx build --platform=linux/arm,linux/arm64,linux/amd64 -t xxx/xxx:tag . --push
Buildx将根据以上指令自动构建三个平台的镜像并推送到远端,这三个镜像会使用命令中指定的同一个tag。
需要注意的是,指定的平台必须是底层镜像所支持的。
在Docker Documents查看更多详细的说明。
使用GitHub Action自动构建多平台镜像
由于DockerHub的自动构建工具对多平台支持并不友好,推荐使用GitHub Action来构建。具体流程如下:
1. 创建GitHub Action流程
在GitHub仓库中点击Actions进入GitHub Action页面,点击set up a workflow yourself创建新的Action流程。
2. 编辑GitHub Action流程
这实际上就是编辑位于仓库.github/workflows/
文件夹下的一个yml文件。
使用docker官方在GitHub创建的几个流程组合起来可以快速完成我们需要的任务。可以参考以下内容:
name: docker build and push
on:
release:
branches: [ main ]
types: released
# 将在main分支的release发布时自动运行该流程
workflow_dispatch:
# 将在GitHub Action界面创建一个run workflow按钮,点击后执行该流程
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Get the tag name
run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
# 获取release tag,在创建镜像时会用到
- name: Setup QEMU
uses: docker/setup-qemu-action@v1
- name: Docker Setup Buildx
uses: docker/[email protected]
# 启用Buildx
- name: Login
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 登陆DockerHub账号,供推送镜像使用,这里的secrets需要在仓库设置页面添加
- name: Build and Push with Version Tag
uses: docker/build-push-action@v2
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm
push: true
tags: xxx/abc:${{ env.TAG }}
# 使用仓库根目录中的Dockerfile构建三个平台的镜像,并推送到xxx/abc仓库,使用之前获取的tag
提交编辑好的GitHub Action流程
点击右上角的Start commit,编辑好信息后点击Commit changes提交,该流程就创建好了。系统将在该仓库的release发布时自动运行流程,构建镜像并推送到DockerHub仓库中。
在这里查看更多详细的GitHub Action用法。
跨平台运行容器
运行跨平台的docker容器需要qemu支持,在前面查看具体指令。
默认使用docker pull指令只会拉取和当前平台一致的镜像,要拉取其他平台的镜像,使用–platform指定对应的平台。
同样,在使用docker run运行容器时也需要使用–platform指定平台。
如果使用docker-compose来管理容器,需要在image的同级添加类似platform: linux/arm
的指令来指定平台。如果本地已有相同tag的其他平台镜像,需要使用docker-compose pull
来拉取需要平台的镜像
总结
总的来说,Docker这套跨平台镜像创建运行机制还是蛮方便的,对于我这种缺少设备的人来说简直是福音。
第一次用GitHub Action,感觉也是非常强,虽然需要编写配置文件这点比不上DockerHub直接指定仓库构建方便,但是相对复杂的配置带来了十分强大的功能,借助GitHub Action几乎可以做到任何想要做的事。