• 通过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="wmdscjhdpy@gmail.com"
    
    #设置环境变量
    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"]
    
    • 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

    这种编写方式就分离了编译镜像和执行镜像,同时linux发行版选择最小的alpine可以尽可能的压缩镜像大小,可以看到最终镜像才几兆。
    镜像大小
    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/uestc-autologin
            readme-filepath: ./doc/docker-readme.md
    
    • 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
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

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

  • 相关阅读:
    【Stable Diffusion XL】huggingface diffusers 官方教程解读
    Linux高性能服务器编程——ch2笔记
    云原生基础知识:容器技术的历史
    《统计学习方法》 第九章 EM算法(原理+代码)
    OpenGL 透视投影编程
    SpringBoot+Vue项目在线学习网站
    详细介绍如何使用YOLOV8和KerasCV进行高效物体检测
    MySQL的复制
    06 分频器设计
    uni-app:通过ECharts实现数据可视化-如何引入项目
  • 原文地址:https://blog.csdn.net/wmdscjhdpy/article/details/125454672