通过github action完成自动多平台编译和docker推送

简介

因为一个小项目,之前一直是手动制作镜像,现在需要用docker部署,然后还要基于arm64编译,想着不如实践一下,学习一下github action和Dockerfile的编写。

Dockerfile篇

Dockerfile是可以通过docker提供的最小系统镜像,通过编写指令可以自动配置运行/编译环境,避免之前每次发布一个版本就得手动pull系统自己安装环境和导入项目程序的无意义劳动。
在Dockerfile中配置主要以COPY 和RUN指令为主,COPY可以复制工作目录的文件到容器下,而RUN就是在容器里执行指令。注意每一行RUN都会为增加镜像的深度,所以不必要的步骤可以尽可能的写在一个RUN中。
为了让最终运行的镜像尽可能小,在Dockerfile中可以指定两个独立容器,一个编译用,一个是运行环境。代码如下,对应的解释都放在了注释里了

#编译用镜像,起名为builder
FROM alpine:3.16 as builder
#指定工作目录,容器下只有该目录的文件会保留
WORKDIR /networkmanager/
#复制项目文件到容器内
COPY ./ /networkmanager/
#为编译环境安装完整的编译包支持
RUN apk update && apk add openssl gcc g++ make libffi-dev openssl-dev libtool cmake
#编译目标程序
RUN cmake . && make
#至此该容器下已经得到了可执行程序

#主镜像
FROM alpine:3.16
LABEL org.opencontainers.image.authors="[email protected]"

#设置环境变量
ENV username=enteryournumber
ENV interval=30
#设定工作目录
WORKDIR /networkmanager/
#为运行环境安装运行必须的库即可
RUN apk update && apk add openssl libgcc libstdc++ binutils
#只需要从builder镜像中获取二进制文件而不需要源代码
COPY --from=builder /networkmanager/network .
#声明一个卷,声明后卷文件独立于容器本身,即便容器崩了数据也还在
VOLUME /etc/networkmanager/
#设置容器入口程序
ENTRYPOINT ["/networkmanager/network"]

这种编写方式就分离了编译镜像和执行镜像,同时linux发行版选择最小的alpine可以尽可能的压缩镜像大小,可以看到最终镜像才几兆。
通过github action完成自动多平台编译和docker推送_第1张图片
Dockerfile编写完后可以测试一下是否可以正常build,完事后就进到了下一个环节

Github Action 篇

github action 可以利用特定的触发器,来让github设置当代码更新时,自动生成对应的docker image。github提供了很多模块化的自动任务,我们只需要将这些任务拼接起来。
这里我们使用的模块有:导入仓库,多平台image生成用的QEMU和buildx,dockerhub的自动登录,自动build和push,这些模块都只需要简单看一下描述,给出关键参数即可。实际上就是拼积木
我的action源码如下,对应部分给出了注释:

name: Docker Image CI
#触发器设置
on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

#项目任务,任务之间可以并行调度
jobs:

  build:
  #选择云端运行的环境
    runs-on: ubuntu-latest
    steps:
    #uses代表使用一个模块,此处使用的是checkout模块,将github项目文件导入到当前环境中
    - uses: actions/checkout@v3
    #使用with跟在后面来为前面的模块输入参数
      with:
        submodules: 'true'
    - name: Set up QEMU
      uses: docker/setup-qemu-action@v2
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2
    - name: Login to DockerHub
      uses: docker/login-action@v2
      with:
     #这里用到了github的secrets功能,避免账户和密码随仓库泄露
       username: ${{ secrets.DOCKERHUB_USERNAME }}
       password: ${{ secrets.DOCKERHUB_TOKEN }}
    - name: Build and push
      #导入这个模块来完成自动编译和推送
      uses: docker/build-push-action@v3
      with:
          context: .
          push: true
          #在这里通过加入需要编译的平台和前面配好的QEMU,buildx来达到多平台编译
          platforms: linux/amd64,linux/arm64,linux/arm
          #指定用户/仓库名
          tags: wmdscjhdpy/test:latest
    - name: Docker Hub Description
      #这里是通过md文件自动生成dockerhub描述的模块,也可以不需要
      uses: peter-evans/dockerhub-description@v3
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_PASSWORD }}
        repository: wmdscjhdpy/autologin
        readme-filepath: ./doc/docker-readme.md

通过这样一个搭积木,传参数的方式,就达到了每次提交时就完成这样一系列的任务。但这其中还存在着secrets的秘密参数,可以通过在github项目的settings->Security->Secrets->Actions,通过创建Repository secrets来完成输入秘密参数,其中dockerhub的token需要在dockerhub网站上自己生成。
这样一来,就大功告成了!只要仓库有新的提交,dockerhub上也会随之生成可用的最小image!

你可能感兴趣的:(操作系统杂项技巧,linux,docker,github,容器)