6bf6bc4a.jpg

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

一直都在使用 nginx-proxyletsencrypt-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 mail@jasonwilder.com"

# 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 me@expoli.tech"

# 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/checkout@v2
      - name: Get current date
        id: date
        run: echo "::set-output name=today::$(date +'%Y-%m-%d')"
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      -
        name: Set up Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@v1
      -
        name: Available platforms
        run: echo ${{ steps.buildx.outputs.platforms }}
      -
        name: Login to DockerHub
        uses: docker/login-action@v1
        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/build-push-action@v2
        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 }}

最终成果

image.png


标题:使用 Github Action 构建多平台 nginx-proxy
作者:糖醋鱼
地址:https://expoli.tech/articles/2021/01/05/1609812943066.html