type
Post
status
Published
slug
2021/01/05/1609812943066
summary
使用 Github Action 构建多平台 nginx-proxy
tags
Docker
Github
category
Docker
icon
password
new update day
URL
Property
Dec 9, 2022 02:09 AM
created days
Last edited time
Dec 9, 2022 02:09 AM

使用 Github Action 构建多平台 nginx-proxy

一直都在使用 nginx-proxy letsencrypt-nginx-proxy-companion 作为自动化的反向代理(可以自动续签证书、以及拥有服务发现的功能),但是比较烦恼的就是官方只提供了 amd64 平台的镜像,这让我这个想在树莓派上运行它的人可给苦恼坏了。所以想到了使用 Github Action 完成多平台的构建。

分析项目

下面是 nginx-proxy 的 Dockerfile,我们可以看到它依赖于 foregodocker-gen 很遗憾这两个软件也只有 amd64 的版本,而且 docker-gen 还依赖于另一个第三方依赖管理软件、巧了这个也只有 amd64 版本(我觉得我现在的头非常大),不过还好都开源,而且都是使用Go写的,这也就说我能够再次编译它实现多平台。
FROM nginx:1.19.3-alpine LABEL maintainer="Jason Wilder [email protected]" # Install wget and install/updates certificates RUN apk add --no-cache --virtual .run-deps \\ ca-certificates bash wget openssl \\ && update-ca-certificates # Configure Nginx and apply fix for very long server names RUN echo "daemon off;" >> /etc/nginx/nginx.conf \\ && sed -i 's/worker_processes 1/worker_processes auto/' /etc/nginx/nginx.conf # Install Forego ADD <https://github.com/jwilder/forego/releases/download/v0.16.1/forego> /usr/local/bin/forego RUN chmod u+x /usr/local/bin/forego ENV DOCKER_GEN_VERSION 0.7.4 RUN wget --quiet <https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-alpine-linux-amd64-$DOCKER_GEN_VERSION.tar.gz> \\ && tar -C /usr/local/bin -xvzf docker-gen-alpine-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \\ && rm /docker-gen-alpine-linux-amd64-$DOCKER_GEN_VERSION.tar.gz COPY network_internal.conf /etc/nginx/ COPY . /app/ WORKDIR /app/ ENV DOCKER_HOST unix:///tmp/docker.sock VOLUME ["/etc/nginx/certs", "/etc/nginx/dhparam"] ENTRYPOINT ["/app/docker-entrypoint.sh"] CMD ["forego", "start", "-r"]

编写 Dockerfile

因为这次需要编译的是四个Go程序,而且还是需要协同工作的,docker-gen 依赖于 glock,nginx-proxy 依赖于 docker-genforego.一开始想出了两种解决方案

第一种解决方案

即在 Github Action 的运行镜像中直接获取相应依赖的源码进行编译,然后再根据 nginx-proxyDckerfile 进行修改后编译,想法可行,然而在进行实施的时候却遇到了问题,即无法找到相应的依赖文件,它总是去根目录下去寻找,多此更改路径也无用,最终放弃该方案。
failed to solve: rpc error: code = Unknown desc = failed to compute cache key: "/docker-gen" not found: not found

第二种方案

第二种方案就是,不使用原项目的 Dockerfile 新建一个构建使用的 Dockerfile ,前后分为两个构建阶段:第一阶段使用 golang 镜像构建所需依赖,第二阶段从第一阶段的产物中获取所需依赖,完成第二阶段的构建。golang 镜像构建完成的二进制文件默认在 /go/bin 下(当时找了挺久一直以为在 ~/go/bin)。
# as go builder FROM golang:latest as GO_BUILD # don't use CGO RUN export CGO_ENABLED=0 \\ && echo "GOPATH" # docker_gen depend RUN go get -v github.com/robfig/glock \\ && go get github.com/ddollar/forego \\ && pwd \\ && ls -al # get docker-gen source code RUN go get github.com/jwilder/docker-gen RUN cd /go/src/github.com/jwilder/docker-gen \\ && make get-deps \\ && make # Get the docker-gen RUN mv /go/src/github.com/jwilder/docker-gen/docker-gen /go/bin/docker-gen # build the nginx-proxy image FROM nginx:1.19.3 LABEL maintainer="Cuyu Tang [email protected]" # copy files from the builder COPY --from=GO_BUILD /go/bin/* /usr/local/bin/ # Install wget and install/updates certificates RUN apt-get update \\ && apt-get install -y -q --no-install-recommends \\ ca-certificates \\ wget \\ && apt-get clean \\ && rm -r /var/lib/apt/lists/* # Configure Nginx and apply fix for very long server names RUN echo "daemon off;" >> /etc/nginx/nginx.conf \\ && sed -i 's/worker_processes 1/worker_processes auto/' /etc/nginx/nginx.conf # Install Forego # COPY forego /usr/local/bin/forego RUN chmod u+x /usr/local/bin/forego \\ && chmod u+x /usr/local/bin/docker-gen COPY network_internal.conf /etc/nginx/ COPY . /app/ WORKDIR /app/ ENV DOCKER_HOST unix:///tmp/docker.sock VOLUME ["/etc/nginx/certs", "/etc/nginx/dhparam"] ENTRYPOINT ["/app/docker-entrypoint.sh"] CMD ["forego", "start", "-r"]

编写 Github Action

Github Action 为了获取最新代码,对相应的项目进行了 clone 操作,此方式可操作性极大。😉😉😉
# This is a basic workflow to help you get started with Actions name: CI # Controls when the action will run. on: # Triggers the workflow on push or pull request events but only for the main branch push: branches: pull_request: branches: schedule: - cron: "0 0 * * *" # Allows you to run this workflow manually from the Actions tab workflow_dispatch: inputs: logLevel: description: 'Log level' required: true default: 'warning' tags: description: 'Test scenario tags' # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" build: # The type of runner that the job will run on runs-on: ubuntu-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: - name: Checkout uses: actions/[email protected] - name: Get current date id: date run: echo "::set-output name=today::$(date +'%Y-%m-%d')" - name: Set up QEMU uses: docker/[email protected] - name: Set up Docker Buildx id: buildx uses: docker/[email protected] - name: Available platforms run: echo ${{ steps.buildx.outputs.platforms }} - name: Login to DockerHub uses: docker/[email protected] with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get all things run: git clone <https://github.com/nginx-proxy/nginx-proxy.git> && cp -r ./nginx-proxy/* . && ls -al - name: Build and push uses: docker/[email protected] with: context: . file: ./Dockerfile_action platforms: linux/amd64,linux/arm64/v8,linux/arm/v7,linux/arm/v6 push: ${{ github.event_name != 'pull_request' }} tags: | tangcuyu/nginx-proxy:latest tangcuyu/nginx-proxy:${{ steps.date.outputs.today }}

最终成果

notion image
 
欢迎加入喵星计算机技术研究院,原创技术文章第一时间推送。
notion image
 
Github Action 获取当前时间并给 docker 镜像打标签巧用 Github Action 编译跨平台 docker 镜像