The story of pushing a Docker container to GitHub Package Registry and Docker Hub with GitHub Actions

This article is a trial and has posted the same content as My Blog.

I'm going to talk about pushing a Docker container to the GitHub Package Registry with GitHub Actions.

Assumed reader

background

Now I can use it as a base image for the company

https://github.com/fagai/docker-php

I set automated build for Docker Hub in the github repository and built from Docker Hub. The build timeline for Docker Hub was very slow, and I managed to keep it a little stressful.

However, recently I thought that I would like to do something about Docker Hub's pull limit or GitHub's Container Registry becoming a public beta, so I decided to Build + Push with GitHub Actions.

GitHub Container Registry (GCR) and GitHub Package Registry (GPR) are different

From here, we'll abbreviate GitHub Container Registry as GCR, please note that it's not Google Container Registry. (I'm having trouble getting the abbreviation)

The former was released as a public beta the other day, and the latter has been around for some time. The difference between the two

It is a place like that.

Regarding the part to be linked, the URL path is also different as follows.

It is different whether it is tied to the user or the repository like this. Well, the contents written below can be written in the same way in either case, so I think it's good to see it even if it's a Package Registry.

Originally I was trying to use GitHub Container Registry, but I wonder if the domain is ghcr.io This ... isn't it GitHub ...? I started using the GitHub Package Registry. At present, I think that GCR is better for use because the version of manifest is newer. Use GPR when you want to link it to a package.

When I first did it

Initially I used docker publish in starter-workflow.

https://github.com/actions/starter-workflows/blob/master/ci/docker-publish.yml

The guy at that time https://github.com/fagai/docker-php/blob/32988eacf16e697e5376ee0af778079fa1e0fb62/.github/workflows/docker-publish.yml

Compared to Docker Hub, I don't have time to put it in the Queue, so it was really good.

gradually

I was wondering if I could push it to Docker Hub gradually, and found the result https://github.com/docker/build-push-action. To rewrite here.

https://github.com/docker/build-push-action

At that time: https://github.com/fagai/docker-php/blob/12d060efd0b91924f0edf85f3b127e19d47cd18a/.github/workflows/docker-publish.yml

- name: Push to GitHub Packages
  uses: docker/build-push-action@v1
  with:
    dockerfile: ${{ matrix.images }}/Dockerfile
    username: ${{ github.actor }}
    password: ${{ secrets.CR_PAT }}
    registry: docker.pkg.github.com
    repository: fagai/docker-php/${{ env.IMAGE_NAME }}
    tags: ${{ env.IMAGE_VERSION }}

Slim ~~. Regarding CR_PAT, it's an abbreviation for Container Registry Personal Access Token. Actually, it was written at the time of starter-workflow, so I set the token of github with that name. (Github.token is fine, but it seems better to narrow down the access token as much as possible, so I gave permissions only to the access repository and write repository)

Later, I also added the push settings for Docker Hub.

- name: Push to Docker Hub
  uses: docker/build-push-action@v1
  with:
    dockerfile: ${{ matrix.images }}/Dockerfile
    username: ${{ github.actor }}
    password: ${{ secrets.DOCKER_HUB_TOKEN }}
    repository: fagai/${{ env.IMAGE_NAME }}
    tags: ${{ env.IMAGE_VERSION }}

In the example of build-push-action, password was set, but Docker Hub also has an access token, so use that. I put it on after setting it.

https://docs.docker.com/docker-hub/access-tokens/

I want to do various things such as cash

As it is, it does not refer to the cache. (However, the second build-push-action is based on cache, so if you build + push one, you can push the other immediately)

build-push-action has a parameter called cache_froms, so I want to use it well.

After trying various things, I found that I need to use Buildkit in order to use cache_froms. It also turned out that you had to set build_args: BUILDKIT_INLINE_CACHE = 1. Apparently, cache_froms had a bad atmosphere unless the domain part was also specified. ← I was worried here

So it looks like this.

- name: Push to GitHub Packages
  uses: docker/build-push-action@v1
  env:
    DOCKER_BUILDKIT: 1
  with:
    dockerfile: ${{ matrix.images }}/Dockerfile
    username: ${{ github.actor }}
    password: ${{ secrets.CR_PAT }}
    registry: docker.pkg.github.com
    repository: fagai/docker-php/${{ env.IMAGE_NAME }}
    tags: ${{ env.IMAGE_VERSION }}
    build_args: BUILDKIT_INLINE_CACHE=1
    cache_froms: docker.pkg.github.com/fagai/docker-php/${{ env.IMAGE_NAME }}:${{ env.IMAGE_VERSION }}

You can go with this! I thought

It's not cached ... so if you look at Actions

#4 importing cache manifest from docker.pkg.github.com/fagai/docker-php/php...
#4 ERROR: httpReaderSeeker: failed open: could not fetch content descriptor sha256:65d9f276544048f140bb1a1cceea52f86e7e704b351c56b8d6b9f18c5e9c0e4d (application/vnd.docker.distribution.manifest.v2+json) from remote: not found

An error occurred like this and the cache could not be acquired and the build ran as it was. Apparently the GitHub Package Registry doesn't yet support docker's new manifest. (GitHub Container Registry seems to support it)

https://github.community/t/handle-multi-arch-docker-images-on-github-package-registry/14314

So, I decided to build from docker Hub first. cache_froms must be written from docker.io.

- name: Push to Docker Hub
  uses: docker/build-push-action@v1
  env:
    DOCKER_BUILDKIT: 1
  with:
    dockerfile: ${{ matrix.images }}/Dockerfile
    username: ${{ github.actor }}
    password: ${{ secrets.DOCKER_HUB_TOKEN }}
    repository: fagai/${{ env.IMAGE_NAME }}
    tags: ${{ env.IMAGE_VERSION }}
    build_args: BUILDKIT_INLINE_CACHE=1
    cache_froms: docker.io/fagai/${{ env.IMAGE_NAME }}:${{ env.IMAGE_VERSION }}

So it looks like this.

#4 importing cache manifest from docker.io/fagai/php:7.2-alpine-fpm
#4 DONE 0.2s

Subsequent processing will also be displayed as CACHED, indicating that the build is not working and is cache-based.

Subsequent retrofit

- name: cancel old workflow
  uses: styfle/[email protected]
  with:
    access_token: ${{ github.token }}

I've done this in the past. It is an Action that cancels the past Action. It solves the problem that past Actions remain and move when you commit many times.

I also set a schedule so that Action works every Monday.

on:
  push:
    branches:
      - master
  pull_request:
  #Do regular updates(every Monday)
  schedule:
    - cron:  '0 0 * * 1'

Finally

As a result of building and pushing to GitHub Actions, the problem that Docker Hub waits in Queue all the time has been solved, and above all, it can be built in parallel, so it can be pushed in a short time.

build-push-action is v2 and buildx It seems that the newly added build in Docker 19.03 will be used. BuildKit seems to be semi-official, and Buildx seems to be an official multi-CPU build compatible function. On mac, by typing docker buildx install, an alias to docker build will be pasted and buildx will be used without permission. How nice.

Recommended Posts

The story of pushing a Docker container to GitHub Package Registry and Docker Hub with GitHub Actions
Getting Started with GitHub Container Registry instead of Docker Hub
Minimal Workflow to push Docker image to Github Container Registry with Github Actions
Test, build, and push your Docker image to GitHub Container Registry using GitHub Actions
Push Docker images from GitHub Actions to GitHub Container Registry
[Docker] How to see the contents of Volumes. Start a container with root privileges.
How to build a Jenkins server with a Docker container on CentOS 7 of VirtualBox and access the Jenkins server from a local PC
Docker push to GitHub Container Registry (ghcr.io)
The story of updating SonarQube's Docker Container
Make a daily build of the TOPPERS kernel with Gitlab and Docker
Push the Docker Image distributed by Docker Hub to Google Container Registry and start the VM based on that Image
Up to the point of launching a Docker container built using RedHat Quarkus
Steps to push Docker image to GitHub Container Registry (ghcr.io)
The story of making a reverse proxy with ProxyServlet
[Docker] How to update using a container on Heroku and how to deal with Migrate Error
Create a container image for arm64 of Kibana and register it in GitHub Container Registry. Start Elastic Stack with Docker Compose on Raspberry Pi 4 (64bit)
Wait for the container service to start with docker healthcheck
The story of migrating a stray batch without an owner from EC2 to a Docker environment
A story packed with the basics of Spring Boot (solved)
Solution for the error "no basic auth credentials" when pushing a Docker container to Heroku
A story addicted to toString () of Interface proxied with JdkDynamicAopProxy
The story of building a Java version of Minecraft server with GCP (and also set a whitelist)
[Docker] Delete only the volume associated with a specific container
Build a Node-RED environment with Docker to move and understand
The story of pushing Java to Heroku using the BitBucket pipeline
Build a NAS with DLNA function at the speed of a second with Raspberry Pi and Docker Compose
I tried to express the result of before and after of Date class with a number line
Let's create a Docker container that can connect to CentOS 8 with the minimum configuration by SSH
A story about using the CoreImage framework to erase stains with Swift and implement a blur erase function
The story of fighting ubuntu errors 0x80370114, 0x80000000 to enable docker desktop with wsl2 on windows10 home
The story of the first Rails app refactored with a self-made helper
Try to imitate the idea of a two-dimensional array with a one-dimensional array
When requested access to the resource is denied when pushing with Docker
I tried to build the environment of PlantUML Server with Docker
A story of connecting to a CentOS 8 server with an old Ansible
The story of toString () starting with passing an array to System.out.println
A story about hitting the League Of Legends API with JAVA
A story that struggled with the introduction of Web Apple Pay
[GCP] Until you push the local Docker image to the Container Registry
It's almost the end of the year, so it's a story of cleaning up to use Docker comfortably at the beginning of the year
A story that I was addicted to twice with the automatic startup setting of Tomcat 8 on CentOS 8
A story that I wanted to write a process equivalent to a while statement with the Stream API of Java8
How to operate IGV using socket communication, and the story of making a Ruby Gem using that method
How to download and run a Jar package directly from the Maven repository with just the command line
Wait for PostgreSQL to start with Docker and then start the WEB service
The story of making a game launcher with automatic loading function [Java]
Starting with installing Docker on EC2 and running Yellowfin in a container
Create a program to post to Slack with GO and make it a container
I tried to measure and compare the speed of GraalVM with JMH
How to start a Docker container with a volume mounted in a batch file
After all I wanted to preview the contents of mysql with Docker ...
Publish Docker Image on GitHub Package Registry
Migrate Dockerhub images to Github Container Registry
Introduction of Docker Hub and commands Self-learning ①
I want to control the start / stop of servers and databases with Alexa
How to mount the batch file location via WSL2 and start the Docker container
How to get the ID of a user authenticated with Firebase in Swift
How to display the amount of disk used by Docker container for each container
Monitor the Docker container and SystemD process on the same host with Zabbix on Ubuntu.
Introduce Docker to the development environment and test environment of existing Rails and MySQL applications
Send a notification to slack with the free version of sentry (using lambda)