diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 0a9f112..3749bd7 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -7,16 +7,65 @@ on:
 
 jobs:
   push:
-    name: Publish
+    strategy:
+      fail-fast: false
+      matrix:
+        entry:
+          - { os: 'focal',  baseruby: '2.7', tag: 'gcc-11',  extras: 'g++-11' }
+          - { os: 'focal',  baseruby: '2.7', tag: 'gcc-10',  extras: 'g++-10' }
+          - { os: 'focal',  baseruby: '2.7', tag: 'gcc-9',   extras: 'g++-9' }
+          - { os: 'focal',  baseruby: '2.7', tag: 'gcc-8',   extras: 'g++-8' }
+          - { os: 'focal',  baseruby: '2.7', tag: 'gcc-7',   extras: 'g++-7' }
+          - { os: 'bionic', baseruby: '2.5', tag: 'gcc-6',   extras: 'g++-6' }
+          - { os: 'bionic', baseruby: '2.5', tag: 'gcc-5',   extras: 'g++-5' }
+          - { os: 'bionic', baseruby: '2.5', tag: 'gcc-4.8', extras: 'g++-4.8' }
+
+          - { os: 'focal',  baseruby: '2.7', tag: 'clang-13',  extras: 'llvm-13' }
+          - { os: 'focal',  baseruby: '2.7', tag: 'clang-12',  extras: 'llvm-12' }
+          - { os: 'focal',  baseruby: '2.7', tag: 'clang-11',  extras: 'llvm-11' }
+          - { os: 'focal',  baseruby: '2.7', tag: 'clang-10',  extras: 'llvm-10' }
+          - { os: 'focal',  baseruby: '2.7', tag: 'clang-9',   extras: 'llvm-9' }
+          - { os: 'bionic', baseruby: '2.5', tag: 'clang-8',   extras: 'llvm-8' }
+          - { os: 'bionic', baseruby: '2.5', tag: 'clang-7',   extras: 'llvm-7' }
+          - { os: 'bionic', baseruby: '2.5', tag: 'clang-6.0', extras: 'llvm-6.0' }
+          - { os: 'bionic', baseruby: '2.5', tag: 'clang-5.0', extras: 'llvm-5.0' }
+          - { os: 'bionic', baseruby: '2.5', tag: 'clang-4.0', extras: 'llvm-4.0' }
+          - { os: 'bionic', baseruby: '2.5', tag: 'clang-3.9', extras: 'llvm-3.9' }
+
+          - { os: 'focal',   baseruby: '2.7', tag: 'mingw-w64' }
+          - { os: 'focal',   baseruby: '2.7', tag: 'crossbuild-essential-arm64' }
+          - { os: 'focal',   baseruby: '2.7', tag: 'crossbuild-essential-ppc64el' }
+          - { os: 'focal',   baseruby: '2.7', tag: 'crossbuild-essential-s390x' }
+
+    name: Publish ${{ matrix.entry.tag }}
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
-      - uses: docker/build-push-action@v1
+      - uses: actions/cache@v2
+        with:
+          path: /tmp/.buildx-cache
+          key: ${{ runner.os }}-buildx-${{ github.sha }}
+          restore-keys: |
+            ${{ runner.os }}-buildx-
+      - uses: docker/setup-buildx-action@v1
+      - uses: docker/login-action@v1
         with:
           username: ${{ github.actor }}
           password: ${{ secrets.ACCESS_TOKEN }}
           registry: ghcr.io
-          repository: ${{ github.repository }}
-          tag_with_ref: true
-        env:
-          DOCKER_BUILDKIT: 1
+      - uses: docker/build-push-action@v2
+        with:
+          build-args: |
+            version=${{ matrix.entry.os }}
+            baseruby=${{ matrix.entry.baseruby }}
+            packages=${{ matrix.entry.tag }} ${{ matrix.entry.extras }}
+          cache-from: type=local,src=/tmp/.buildx-cache
+          cache-to: type=local,dest=/tmp/.buildx-cache-new
+          push: ${{ github.event_name != 'pull_request' }}
+          tags: |
+            ghcr.io/${{ github.repository }}:${{ matrix.entry.tag }}
+
+      # https://github.com/docker/build-push-action/issues/252
+      # https://github.com/moby/buildkit/issues/1896
+      - run: |
+          rm -rf /tmp/.buildx-cache
+          mv /tmp/.buildx-cache-new /tmp/.buildx-cache
diff --git a/Dockerfile b/Dockerfile
index 85012d6..e14c73f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,14 @@
-FROM ubuntu:bionic as assets
-MAINTAINER shyouhei@ruby-lang.org
+ARG os=ubuntu
+ARG version=
+ARG variant=
+ARG baseruby=
+ARG packages=
+
+FROM ${os}:${version}${variant} as assets
+ARG os
+ARG version
+ARG variant
+
 RUN apt-get update
 RUN apt-get install -y wget gnupg2 ca-certificates
 RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key \
@@ -12,44 +21,20 @@ RUN grep '^deb ' /etc/apt/sources.list \
   | tee /etc/apt/sources.list.d/deb-src.list
 ADD assets/99apt.conf /etc/apt/apt.conf.d/
 ADD assets/99dpkg.cfg /etc/dpkg/dpkg.cfg.d/
-ADD assets/98gcc.list  /etc/apt/sources.list.d/
-ADD assets/99llvm.list /etc/apt/sources.list.d/
+ADD assets/99${version}.list /etc/apt/sources.list.d/
+
+FROM ${os}:${version}${variant} as compilers
+ARG baseruby
+ARG packages
 
-FROM ubuntu:bionic
-MAINTAINER shyouhei@ruby-lang.org
+LABEL maintainer=shyouhei@ruby-lang.org
 ENV DEBIAN_FRONTEND=noninteractive
 COPY --from=assets /etc/ssl /etc/ssl
 COPY --from=assets /etc/apt /etc/apt
 COPY --from=assets /etc/dpkg /etc/dpkg
 
-RUN set -ex                          \
- && apt-get update                   \
- && apt-get install                  \
-        clang-3.9 llvm-3.9           \
-        clang-4.0 llvm-4.0           \
-        clang-5.0 llvm-5.0           \
-        clang-6.0 llvm-6.0           \
-        clang-7   llvm-7             \
-        clang-8   llvm-8             \
-        clang-9   llvm-9             \
-        clang-10  llvm-10            \
-        clang-11  llvm-11            \
-        clang-12  llvm-12            \
-        clang-13  llvm-13            \
-        gcc-4.8   g++-4.8            \
-        gcc-5     g++-5              \
-        gcc-6     g++-6              \
-        gcc-7     g++-7              \
-        gcc-8     g++-8              \
-        gcc-9     g++-9              \
-        gcc-10    g++-10             \
-        mingw-w64                    \
-        crossbuild-essential-arm64   \
-        crossbuild-essential-ppc64el \
-        crossbuild-essential-s390x   \
-        libjemalloc-dev              \
-        openssl                      \
-        ruby                         \
-        tzdata                       \
-        valgrind                     \
- && apt-get build-dep ruby2.5
+RUN set -ex                                      \
+ && apt-get update                               \
+ && apt-get install ${packages}                  \
+    libjemalloc-dev openssl ruby tzdata valgrind \
+ && apt-get build-dep ruby${baseruby}
diff --git a/assets/98gcc.list b/assets/98gcc.list
deleted file mode 100644
index bc22b8c..0000000
--- a/assets/98gcc.list
+++ /dev/null
@@ -1,5 +0,0 @@
-deb http://ppa.launchpad.net/ubuntu-toolchain-r/ppa/ubuntu bionic main 
-deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/ppa/ubuntu bionic main 
-
-deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu bionic main 
-deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu bionic main 
diff --git a/assets/99bionic.list b/assets/99bionic.list
new file mode 100644
index 0000000..5005d14
--- /dev/null
+++ b/assets/99bionic.list
@@ -0,0 +1,11 @@
+deb http://ppa.launchpad.net/ubuntu-toolchain-r/ppa/ubuntu bionic main
+deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu bionic  main
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-6.0 main
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-7 main
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main
+
+deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/ppa/ubuntu bionic main
+deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu bionic main
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-6.0 main
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-7 main
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main
diff --git a/assets/99focal.list b/assets/99focal.list
new file mode 100644
index 0000000..0417ef2
--- /dev/null
+++ b/assets/99focal.list
@@ -0,0 +1,15 @@
+deb http://ppa.launchpad.net/ubuntu-toolchain-r/ppa/ubuntu focal main
+deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu focal  main
+deb http://apt.llvm.org/focal/ llvm-toolchain-focal-9 main
+deb http://apt.llvm.org/focal/ llvm-toolchain-focal-10 main
+deb http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main
+deb http://apt.llvm.org/focal/ llvm-toolchain-focal-12 main
+deb http://apt.llvm.org/focal/ llvm-toolchain-focal main
+
+deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/ppa/ubuntu focal main
+deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu focal main
+deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-9 main
+deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-10 main
+deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main
+deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-12 main
+deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal main
diff --git a/assets/99llvm.list b/assets/99llvm.list
deleted file mode 100644
index 2b8f307..0000000
--- a/assets/99llvm.list
+++ /dev/null
@@ -1,24 +0,0 @@
-# i386 not available
-deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic main
-deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic main
-# 6.0
-deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-6.0 main
-deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-6.0 main
-# 7
-deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-7 main
-deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-7 main
-# 8
-deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main
-deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main
-# 9
-deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main
-deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main
-# 10
-deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main
-deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main
-# 11
-deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main
-deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main
-# 12
-deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-12 main
-deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-12 main
