Docker on GitHub Actions
Docker images are useful for reproducibility and ease of setup and for software binary distribution on platforms not natively available on GitHub Actions runner images. While one can setup a custom Docker image, it’s often possible to simply use an existing official image from Docker Hub.
Example: Ubuntu 20.04
This example GitHub Actions workflow uses the Ubuntu 20.04 image to build a C++ binary with the GNU C++ compiler. For APT operations, the “-y” option is necessary. Environment variable DEBIAN_FRONTEND is set to “noninteractive” to avoid interactive prompts for certain operations despite “-y”. Don’t use “sudo” as the container user is root and the “sudo” package is not installed.
A special feature of this example is using Kitware’s CMake APT repo to install the latest version of CMake on an EOL Ubuntu distro.
name: ubuntu-20.04
on: [push]
# avoid wasted runs
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
ubuntu-20.04:
runs-on: ubuntu-latest
container:
image: ubuntu:20.04
env:
DEBIAN_FRONTEND: noninteractive
strategy:
fail-fast: false
matrix:
gcc-version: [7, 8]
env:
CC: gcc-${{ matrix.gcc-version }}
CXX: g++-${{ matrix.gcc-version }}
FC: gfortran-${{ matrix.gcc-version }}
steps:
- name: install compilers
run: |
apt update -y
apt install -y --no-install-recommends ca-certificates gpg curl ninja-build ${{ env.CC }} ${{ env.CXX }} ${{ env.FC }}
- name: install CMake
run: |
curl -s https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null
apt-get update
test -f /usr/share/doc/kitware-archive-keyring/copyright || rm /usr/share/keyrings/kitware-archive-keyring.gpg
apt-get install --no-install-recommends -y kitware-archive-keyring
apt-get install --no-install-recommends -y cmake
- uses: actions/checkout@v4
- name: CMake configure
run: cmake -B build
- name: CMake build
run: cmake --build build
- name: CMake test
run: ctest --test-dir build
Example: Alpine Linux
This example GitHub Actions workflow uses the Alpine Linux image with the MUSL C library to build a statically-linked binary.
name: alpine-musl
on: [push]
jobs:
musl:
runs-on: ubuntu-latest
container:
image: alpine
steps:
- uses: actions/checkout@v4
- name: install build tools
run: apk add --no-cache ninja-build cmake make gfortran openmpi-dev
- name: print MUSL version
continue-on-error: true
run: ldd --version
- name: CMake configure
run: cmake -B build
- name: CMake build
run: cmake --build build
# Good idea to ensure self-tests pass before packaging
- name: CMake test
run: ctest --test-dir build
(Optional) If a CPack archive is desired add step:
- name: CMake package
if: success()
run: cpack --config build/CPackConfig.cmake
The binary artifact or CPack archive can be uploaded by step upload-artifact:
- name: .exe for release
uses: actions/upload-artifact@v4
if: success()
with:
name: my.exe
path: build/my.exe