├── .github └── workflows │ └── build.yml ├── README.md ├── clang ├── Dockerfile ├── install-clang.sh └── llvm.tar.xz ├── common └── install-cmake.sh ├── gcc └── Dockerfile └── test ├── CMakeLists.txt ├── build.sh └── main.cpp /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build and publish docker images 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | clang: 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | version: 13 | - {tag: 6, debian: buster, llvm: "6.0.1"} 14 | - {tag: 7, debian: buster, llvm: "7.0.1"} 15 | - {tag: 8, debian: buster, llvm: "8.0.0"} 16 | - {tag: 9, debian: buster, llvm: "9.0.0"} 17 | - {tag: 10, debian: buster, llvm: "10.0.0"} 18 | - {tag: 11, debian: bullseye, llvm: "11.0.0"} 19 | - {tag: 12, debian: bullseye, llvm: "12.0.0"} 20 | - {tag: 13, debian: bullseye, llvm: "13.0.0"} 21 | - {tag: 14, debian: bullseye, llvm: "14.0.0"} 22 | - {tag: 15, debian: bullseye, llvm: "15.0.6"} 23 | - {tag: 16, debian: bookworm, llvm: "16.0.4"} 24 | - {tag: 17, debian: bookworm, llvm: "17.0.6"} 25 | - {tag: 18, debian: bookworm, llvm: "18.1.8"} 26 | 27 | runs-on: ubuntu-latest 28 | env: 29 | IMAGE: ghcr.io/${{ github.repository_owner }}/clang:${{ matrix.version.tag }} 30 | steps: 31 | - name: Log-in 32 | uses: docker/login-action@v3 33 | with: 34 | registry: ghcr.io 35 | username: ${{ github.repository_owner }} 36 | password: ${{ secrets.GITHUB_TOKEN }} 37 | - name: Checkout 38 | uses: actions/checkout@v4 39 | - name: Set up QEMU 40 | uses: docker/setup-qemu-action@v3 41 | - name: Set up Docker Buildx 42 | id: buildx 43 | uses: docker/setup-buildx-action@v3 44 | 45 | - name: Build image 46 | run: | 47 | docker buildx build --push \ 48 | --build-arg DEBIAN_VERSION=${{ matrix.version.debian }} --build-arg LLVM_VERSION=${{ matrix.version.llvm }} \ 49 | --platform linux/amd64,linux/arm64/v8 --tag $IMAGE -f $GITHUB_WORKSPACE/clang/Dockerfile . 50 | 51 | - name: Test image 52 | run: | 53 | cat $GITHUB_WORKSPACE/test/build.sh | \ 54 | docker run -v "$GITHUB_WORKSPACE/test:/src" -i $IMAGE /bin/bash 55 | 56 | gcc: 57 | strategy: 58 | fail-fast: false 59 | matrix: 60 | version: [7, 8, 9, 10, 11, 12, 13, 14] 61 | 62 | runs-on: ubuntu-latest 63 | env: 64 | IMAGE: ghcr.io/${{ github.repository_owner }}/gcc:${{ matrix.version }} 65 | steps: 66 | - name: Log-in 67 | uses: docker/login-action@v3 68 | with: 69 | registry: ghcr.io 70 | username: ${{ github.repository_owner }} 71 | password: ${{ secrets.GITHUB_TOKEN }} 72 | - name: Checkout 73 | uses: actions/checkout@v4 74 | - name: Set up QEMU 75 | uses: docker/setup-qemu-action@v3 76 | - name: Set up Docker Buildx 77 | id: buildx 78 | uses: docker/setup-buildx-action@v3 79 | 80 | - name: Build image 81 | run: | 82 | docker buildx build --push \ 83 | --build-arg GCC_VERSION=${{ matrix.version }} \ 84 | --platform linux/amd64,linux/arm64/v8 --tag $IMAGE -f $GITHUB_WORKSPACE/gcc/Dockerfile . 85 | 86 | - name: Test image 87 | run: | 88 | cat $GITHUB_WORKSPACE/test/build.sh | \ 89 | docker run -v "$GITHUB_WORKSPACE/test:/src" -i $IMAGE /bin/bash 90 | 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # foonathan/docker 2 | 3 | This is a collection of docker container I use to test my projects on CI. 4 | They are designed to compile a CMake project using Ninja and a specific compiler version and run the tests; 5 | not to actually build a released executable or anything like that. 6 | 7 | ## Common Software 8 | 9 | * curl 10 | * git 11 | * CMake 3.30.3 12 | * ninja 13 | 14 | It is designed for a basic CMake workflow: 15 | 16 | ```sh 17 | cmake /path/to/src 18 | cmake --build . 19 | ctest 20 | ``` 21 | 22 | This will automatically select the specific compiler and Ninja as generator. 23 | 24 | ## Image ghcr.io/foonathan/clang: 25 | 26 | * clang 6-10 on Debian buster 27 | * clang 11-15 on Debian bullseye 28 | * clang 16-18 on Debian bookworm 29 | 30 | ## Image ghcr.io/foonathan/gcc: 31 | 32 | * GCC 7-14 33 | 34 | -------------------------------------------------------------------------------- /clang/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG DEBIAN_VERSION 2 | FROM bitnami/minideb:${DEBIAN_VERSION} 3 | LABEL maintainer="Jonathan Müller " 4 | 5 | WORKDIR /root 6 | COPY clang/install-clang.sh common/install-cmake.sh ./ 7 | 8 | ARG LLVM_VERSION 9 | RUN apt-get update -qq && \ 10 | apt-get install -y --no-install-recommends ca-certificates ninja-build git g++ curl xz-utils unzip && \ 11 | ./install-clang.sh $LLVM_VERSION && \ 12 | ./install-cmake.sh && \ 13 | rm install-clang.sh install-cmake.sh 14 | 15 | ENV CC clang 16 | ENV CXX clang++ 17 | ENV CMAKE_GENERATOR Ninja 18 | 19 | -------------------------------------------------------------------------------- /clang/install-clang.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Adapted from https://github.com/silkeh/docker-clang/blob/master/install.sh. 3 | set -eou pipefail 4 | 5 | LLVM_VERSION=$1 6 | case "${LLVM_VERSION}" in 7 | 6*|7*) 8 | MIRROR="llvm" 9 | if [ $(uname -m) = "x86_64" ]; then 10 | PLATFORM="x86_64-linux-gnu-ubuntu-16.04" 11 | elif [ $(uname -m) = "aarch64" ]; then 12 | PLATFORM="aarch64-linux-gnu" 13 | else 14 | echo "unknown architecture" >/dev/stderr 15 | exit 1 16 | fi 17 | ;; 18 | 8*|9*) 19 | MIRROR="llvm" 20 | if [ $(uname -m) = "x86_64" ]; then 21 | PLATFORM="x86_64-linux-gnu-ubuntu-18.04" 22 | elif [ $(uname -m) = "aarch64" ]; then 23 | PLATFORM="aarch64-linux-gnu" 24 | else 25 | echo "unknown architecture" >/dev/stderr 26 | exit 1 27 | fi 28 | ;; 29 | 10*) 30 | MIRROR="github" 31 | if [ $(uname -m) = "x86_64" ]; then 32 | PLATFORM="x86_64-linux-gnu-ubuntu-18.04" 33 | elif [ $(uname -m) = "aarch64" ]; then 34 | PLATFORM="aarch64-linux-gnu" 35 | else 36 | echo "unknown architecture" >/dev/stderr 37 | exit 1 38 | fi 39 | ;; 40 | 11*|12*|13*) 41 | MIRROR="github" 42 | if [ $(uname -m) = "x86_64" ]; then 43 | PLATFORM="x86_64-linux-gnu-ubuntu-20.04" 44 | elif [ $(uname -m) = "aarch64" ]; then 45 | PLATFORM="aarch64-linux-gnu" 46 | else 47 | echo "unknown architecture" >/dev/stderr 48 | exit 1 49 | fi 50 | ;; 51 | 14*|15*) 52 | MIRROR="github" 53 | if [ $(uname -m) = "x86_64" ]; then 54 | PLATFORM="x86_64-linux-gnu-ubuntu-18.04" 55 | elif [ $(uname -m) = "aarch64" ]; then 56 | PLATFORM="aarch64-linux-gnu" 57 | else 58 | echo "unknown architecture" >/dev/stderr 59 | exit 1 60 | fi 61 | ;; 62 | 16*) 63 | MIRROR="github" 64 | if [ $(uname -m) = "x86_64" ]; then 65 | PLATFORM="x86_64-linux-gnu-ubuntu-22.04" 66 | elif [ $(uname -m) = "aarch64" ]; then 67 | PLATFORM="aarch64-linux-gnu" 68 | else 69 | echo "unknown architecture" >/dev/stderr 70 | exit 1 71 | fi 72 | ;; 73 | 17*) 74 | MIRROR="github" 75 | if [ $(uname -m) = "x86_64" ]; then 76 | PLATFORM="x86_64-linux-gnu-ubuntu-22.04" 77 | elif [ $(uname -m) = "aarch64" ]; then 78 | PLATFORM="aarch64-linux-gnu" 79 | else 80 | echo "unknown architecture" >/dev/stderr 81 | exit 1 82 | fi 83 | ;; 84 | 18*) 85 | MIRROR="github" 86 | if [ $(uname -m) = "x86_64" ]; then 87 | PLATFORM="x86_64-linux-gnu-ubuntu-18.04" 88 | elif [ $(uname -m) = "aarch64" ]; then 89 | PLATFORM="aarch64-linux-gnu" 90 | else 91 | echo "unknown architecture" >/dev/stderr 92 | exit 1 93 | fi 94 | ;; 95 | esac 96 | 97 | case "${MIRROR}" in 98 | "github") 99 | MIRROR_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}" 100 | ;; 101 | "llvm") 102 | MIRROR_URL="http://releases.llvm.org/${LLVM_VERSION}" 103 | ;; 104 | esac 105 | 106 | # Install dependency. 107 | apt-get install -y --no-install-recommends libtinfo5 108 | 109 | # Set install target and download file 110 | TARGET="clang+llvm-${LLVM_VERSION}-${PLATFORM}" 111 | DOWNLOAD="clang+llvm-${LLVM_VERSION}-${PLATFORM}.tar.xz" 112 | DOWNLOAD_FILE="llvm.tar.xz" 113 | 114 | # Download 115 | echo "Downloading ${DOWNLOAD}" 116 | curl -L "${MIRROR_URL}/${DOWNLOAD}" --output "${DOWNLOAD_FILE}" 117 | 118 | # Install 119 | echo "Installing ${TARGET}" 120 | tar xf "${DOWNLOAD_FILE}" 121 | # Delete all binaries that are not clang-Major 122 | find ${TARGET}/bin -type f -not -regex '.*/clang-[0-9].*' -delete 123 | # Delete all now broken symlinks. 124 | find -L ${TARGET}/bin -maxdepth 1 -type l -delete 125 | # Copy the remaining binaries over. 126 | cp -a ${TARGET}/bin/* /usr/local/bin/ 127 | # And the necessary libs. 128 | cp -a ${TARGET}/lib/clang/ /usr/local/lib/ 129 | 130 | # Cleanup 131 | rm -rf "${DOWNLOAD_FILE}" "${TARGET:?}/" 132 | 133 | -------------------------------------------------------------------------------- /clang/llvm.tar.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foonathan/docker/32c1e95359f0a17d511943f59c49235d83b477e7/clang/llvm.tar.xz -------------------------------------------------------------------------------- /common/install-cmake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eou pipefail 3 | 4 | VERSION="3.30.3" 5 | MIRROR_URL="https://github.com/Kitware/CMake/releases/download/v$VERSION/" 6 | DOWNLOAD_X86="cmake-$VERSION-linux-x86_64.sh" 7 | DOWNLOAD_ARM="cmake-$VERSION-linux-aarch64.sh" 8 | DOWNLOAD_FILE="cmake.sh" 9 | 10 | if [ $(uname -m) = "x86_64" ]; then 11 | DOWNLOAD=$DOWNLOAD_X86 12 | elif [ $(uname -m) = "aarch64" ]; then 13 | DOWNLOAD=$DOWNLOAD_ARM 14 | else 15 | echo "unknown architecture" >/dev/stderr 16 | exit 1 17 | fi 18 | 19 | # Download 20 | echo "Downloading ${DOWNLOAD}" 21 | curl -L "${MIRROR_URL}/${DOWNLOAD}" --output "${DOWNLOAD_FILE}" 22 | 23 | # Install 24 | echo "Installing CMakee" 25 | bash "${DOWNLOAD_FILE}" --skip-license --prefix=/usr/local --exclude-subdir 26 | 27 | # Cleanup 28 | rm "${DOWNLOAD_FILE}" 29 | 30 | -------------------------------------------------------------------------------- /gcc/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG GCC_VERSION 2 | FROM gcc:${GCC_VERSION} 3 | LABEL maintainer="Jonathan Müller " 4 | 5 | WORKDIR /root 6 | COPY common/install-cmake.sh ./ 7 | 8 | RUN apt-get update -qq && \ 9 | apt-get install -y --no-install-recommends ninja-build && \ 10 | ./install-cmake.sh && \ 11 | rm install-cmake.sh 12 | 13 | ENV CMAKE_GENERATOR Ninja 14 | 15 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.18) 2 | project(docker_test) 3 | 4 | add_executable(app main.cpp) 5 | 6 | enable_testing() 7 | add_test(NAME test COMMAND app) 8 | 9 | -------------------------------------------------------------------------------- /test/build.sh: -------------------------------------------------------------------------------- 1 | set -eou pipefail 2 | 3 | cmake /src 4 | cmake --build . 5 | ctest 6 | 7 | -------------------------------------------------------------------------------- /test/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | std::cout << "Hello World!\n"; 6 | } 7 | 8 | --------------------------------------------------------------------------------