JonasAlfredsson / docker-nginx-certbot

Automatically create and renew website certificates for free using the Let's Encrypt certificate authority.

Home Page:https://hub.docker.com/r/jonasal/nginx-certbot

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Build for multiple architectures

JonasAlfredsson opened this issue · comments

Our parent container is build for multiple architectures (OS/ARCH), and in issue #24 I was made aware that this container does not successfully build on all arches. So it would be very nice if we could expand this to build for the same set of arches.

In order to do this locally, we can use Docker Buildx.

If you have Docker >= 19.03 this should already be included, otherwise the install instructions are found here. One thing that is easy to miss is the part where they mention that you will need to use this image in order to install all the QEMU dependencies used.

So my setup process went something like this:

1 - Install emulators

docker run --privileged --rm tonistiigi/binfmt --install all

2 - Initialize a builder

docker buildx create --name multiarch
docker buildx use multiarch
docker buildx inspect --bootstrap 

3 - Check that it picks up all the emulators

docker buildx ls                                                                                                                                                                                                                                                                                                                                                                                                         

NAME/NODE    DRIVER/ENDPOINT             STATUS  PLATFORMS
multiarch *  docker-container                    
  multiarch0 unix:///var/run/docker.sock running linux/amd64, linux/arm64, linux/386, linux/arm/v7, linux/arm/v6, linux/riscv64, linux/ppc64le, linux/s390x
default      docker                              
  default    default                     running linux/amd64, linux/386

After the installation is should be as easy as just specifying which platforms you want to build for [1]:

docker buildx build --platform linux/arm64/v8,linux/amd64 --tag jonasal/nginx-certbot-arches .

A problem with this is that DockerHub does not support multiarch builds (at least what I can find), which means that we need to find another solution. After researching this a bit I landed on GitHub Actions, and managed to create something that I think will work.

I found that this guide was good to get started with: https://docs.docker.com/ci-cd/github-actions/

I also used these two guides to get a better grip of how Workflows function:


After a lot of experimenting I came to the conclusion that I will have two different "action" files in my .github/workflows/ folder. The biggest difference between them is how they are triggered.

In the build_latest.yml file I will have the following on the top:

on:
  push:
    branches:
      - "main"
      - "master"
    paths:
      - "src/**"

which means that this job will only be triggered when something is changed inside the src/ folder on either the "main" or "master" branch, all other changes will be ignored. This should be fine since an edit to the README would not affect the Docker container being built.

In the build_tag.yml file I will have the following on the top:

on:
  push:
    branches-ignore:
      - "**"
    tags:
      - "v[1-9].[0-9]+.[0-9]+-nginx[1-9].[0-9]+.[0-9]+"

This will first ignore any pushes to all branches, while then triggering on any tags being pushed. The semi-regex (it is not normal regex, since "." is treated as a normal period here) will make sure that we only trigger on a very specific set of tags, and in this case it has the form of my release tags.

An important thing to understand with the tag filter is that it will trigger on a valid tag on whichever branch you place it. So if you add a valid tag on the dev branch, the action will checkout that reference and build it. However, the action script being used is the one that is in "main/master", oo changes to the wokflows will only take affect when they are pushed there.

One really annoying thing I ran into while building all the architectures is that there exist a really specific problem for some low level libraries when they try to read the filesytem while running inside a 32-bit environment that is emulated by QEMU running on a 64-bit host. More info about this exist in issue #30.

It seems I have been successful in this, closing for now :)