0%

在Github Action里构建大型Docker镜像

GitHub 提供了非常好用的 Action 功能,最常见的是可以在里面做一些 CI 工作,比如单元测试、Lint等。

在国内,受一堵墙的影响,不少开发事项需要特殊的技巧方能正常进行,以至于中国程序员人均拥有比外国程序员更好的网络基础知识。

这堵墙在 Docker 镜像构建方面影响尤其大,虽然通过配置代理可以解决,但如果我们想在构建里再装一些 Python 的包之类的行为,很困难。

如果能利用 Github Action 来进行 Docker 镜像的构建,将会极大提升便利性和幸福感。

在 Github Action 的 marketplace 里能找到一些相关的工具,同时也可以直接在 workflow.yaml 里写 docker build 。

在一般的小型镜像构建任务里,这样就足够了,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
name: Docker Image CI

on:
push:
branches: [ "main" ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: ${{ env.docker_namespace }}/${{ env.image_name }}:${{ version }} # 注意替换,直接写死也行

这样就实现了当向 main 分支提交代码时,就在 Ubuntu 环境下进行 docker 构建和推送。

但现在随着大模型的兴起,一些 AI 应用开始变得流行,比如 AI 绘图使用的开源软件 Stable Diffusion ,如果想把 SD 放在 Docker 镜像里,那一堆庞大的 Python 依赖(pytorch、cuda等),会导致 Github Action 执行时报错,提示磁盘已用尽。

这个解决方法很简单,但也有极限,自测经验是 13GB 左右的镜像是可以构建成功的。只需要在开始执行 Docker 镜像构建前执行这一段脚本进行磁盘清理即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
name: Docker Image CI

on:
push:
branches: [ "main" ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Free Disk Space (Ubuntu) # 就是通过这一步进行释放空间
uses: jlumbroso/free-disk-space@main
with:
# 这个可能会删除一些你实际需要的工具,所以建议还是 false 让它保留
# 如果你打算尝试移除它,可以再腾出大约6GB的空间
tool-cache: false

# 如果有你需要使用的,将其设置为 false ,比如这里我们要构建Docker,Docker相关的工具是不能删的
android: true
dotnet: true
haskell: true
large-packages: true
docker-images: false
swap-storage: true
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: ${{ env.docker_namespace }}/${{ env.image_name }}:${{ version }} # 注意替换,直接写死也行

具体案例可以参考 https://github.com/sky-admin/serverless-pod-a1111-upload ,这是一个允许 A1111/Stable-Diffusion-WebUI 在 RunPod 的 serverless 服务上运行模型执行AI绘图的镜像。未来也许会详细介绍如何在 Runpod 上部署 SD 绘图服务。

那如果想构建更大的镜像呢?就需要自行提供 Action 执行所在的 Runner 了,这个目前还没有尝试,但有基本的思路和方案,未来尝试后再来分享。