diff --git a/.github/workflows/build-test-push.yml b/.github/workflows/build-test-push.yml new file mode 100644 index 0000000..e7307e0 --- /dev/null +++ b/.github/workflows/build-test-push.yml @@ -0,0 +1,327 @@ +name: Build, test and push to the Client Library + +on: + workflow_dispatch: + inputs: + production: + description: | + 'Push to production registries' + 'not checked - to testing' + required: true + type: boolean + default: false + + version_major: + description: 'AlmaLinux major version' + required: true + default: '9' + type: choice + options: + - 9 + - 8 + + type_default: + description: 'default' + required: true + type: boolean + default: true + + type_minimal: + description: 'minimal' + required: true + type: boolean + default: true + + type_micro: + description: 'micro' + required: true + type: boolean + default: true + + type_base: + description: 'base' + required: true + type: boolean + default: true + + type_init: + description: 'init' + required: true + type: boolean + default: true + +env: + # Latest version + version_latest: 9 + + # Platforms list: linux/amd64, linux/ppc64le, linux/s390x, linux/arm64 + platforms: 'linux/amd64, linux/ppc64le, linux/s390x, linux/arm64' + + # Registries list + # production: docker.io/almalinux, quay.io/almalinuxorg, ghcr.io/almalinux + # testing: quay.io/almalinuxautobot + registries: ${{ inputs.production && 'docker.io/almalinux, quay.io/almalinuxorg, ghcr.io/almalinux' || 'quay.io/almalinuxautobot' }} + +jobs: + build: + name: Deploy ${{ inputs.version_major }} ${{ matrix.image_types }} images + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + # Set image types matrix based on boolean inputs.type_* with true value + image_types: ${{ fromJSON(format('["{0}", "{1}", "{2}", "{3}", "{4}"]', ( inputs.type_default && 'default' ), ( inputs.type_minimal && 'minimal' ), ( inputs.type_micro && 'micro' ), ( inputs.type_base && 'base' ), ( inputs.type_init && 'init' ) )) }} + exclude: + - image_types: 'false' + + steps: + + - + name: Prepare AlmaLinux Minor version number + run: | + case ${{ inputs.version_major }} in + 8) + version_minor="9" ;; + 9) + version_minor="3" ;; + 10) + version_minor="0" ;; + *) + echo "Almalinux ${{ inputs.version_major }} is not supported!" && false + esac + echo "version_minor=${version_minor}" >> $GITHUB_ENV + + # [Debug] + echo "version_minor=${version_minor}" + + - + name: Prepare date stamp + id: date_stamp + run: | + # date stamp + date_stamp=$(date -u '+%Y%m%d') + echo "date_stamp=${date_stamp}" >> $GITHUB_ENV + echo "date_stamp=${date_stamp}" >> "$GITHUB_OUTPUT" + [ -z "$date_stamp-x" ] && false + + # [Debug] + echo "date_stamp=${date_stamp}" + + - + name: Generate list of images to use as base name for tags + run: | + # list of registries to push to + REGISTRIES="${{ env.registries }}" + + IMAGE_NAMES= + # generate image names in format $REGISTRY/almalinux or $REGISTRY/${{ inputs.version_major }}-${{ matrix.image_types }} + # image names are used by docker/metadata-action to set 'images' + for REGISTRY in ${REGISTRIES//,/ }; do + # 'default' images should not go to docker.io + [ "${{ matrix.image_types }}" = "default" ] && [[ $REGISTRY = *'docker.io'* ]] && continue + + # 'default' images goes to $REGISTRY/almalinux + [ "${{ matrix.image_types }}" = "default" ] \ + && IMAGE_NAME="$REGISTRY/almalinux" \ + || IMAGE_NAME="$REGISTRY/${{ inputs.version_major }}-${{ matrix.image_types }}" + IMAGE_NAMES="${IMAGE_NAMES} ${IMAGE_NAME}" + unset IMAGE_NAME + done + + # remove space at the beginning of string + IMAGE_NAMES=${IMAGE_NAMES# } + # separate with comma instead of space and export to the action + echo "IMAGE_NAMES=${IMAGE_NAMES// /,}" >> $GITHUB_ENV + + # [Debug] + echo $IMAGE_NAMES + + - + name: Enable containerd image store on Docker Engine + run: | + # Use containerd image store + sudo jq '.features |= . + { "containerd-snapshotter": true }' /etc/docker/daemon.json > ./daemon.json.${{ env.date_stamp }} && \ + sudo mv -f ./daemon.json.${{ env.date_stamp }} /etc/docker/daemon.json + sudo systemctl restart docker + docker info -f '{{ .DriverStatus }}' + + - + name: Checkout ${{ github.repository }}, branch 'main' + uses: actions/checkout@v4 + + - + name: Checkout ${{ github.repository }}, branch 'docker-library', path 'docker-library' + uses: actions/checkout@v4 + with: + ref: docker-library + path: docker-library + + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - + name: Login to Docker.io + if: contains(env.registries, 'docker.io') + uses: docker/login-action@v3 + with: + registry: docker.io + username: ${{ inputs.production && secrets.DOCKERHUB_USERNAME || secrets.TEST_DOCKERHUB_USERNAME }} + password: ${{ inputs.production && secrets.DOCKERHUB_TOKEN || secrets.TEST_DOCKERHUB_TOKEN }} + + - + name: Login to Quay.io + if: contains(env.registries, 'quay.io') + uses: docker/login-action@v3 + with: + registry: quay.io + username: ${{ inputs.production && secrets.QUAY_IO_USERNAME || secrets.TEST_QUAY_IO_USERNAME }} + password: ${{ inputs.production && secrets.QUAY_IO_CLI_PASSWORD || secrets.TEST_QUAY_IO_CLI_PASSWORD }} + + - + name: Login to Ghcr.io + if: contains(env.registries, 'ghcr.io') + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ inputs.production && secrets.GIT_HUB_USERNAME || secrets.TEST_GITHUB_USERNAME }} + password: ${{ inputs.production && secrets.GIT_HUB_TOKEN || secrets.TEST_GITHUB_TOKEN }} + + - + name: Generate tags and prepare metadata to build and push + id: meta + uses: docker/metadata-action@v5 + with: + # list of Docker images to use as base names for tags + images: ${{ env.IMAGE_NAMES }} + + # list of tags + tags: | + type=raw,value=latest,enable=${{ matrix.image_types != 'default' || ( matrix.image_types == 'default' && inputs.version_major == env.version_latest ) }} + type=raw,value=${{ inputs.version_major }},enable=true + type=raw,value=${{ inputs.version_major }}.${{ env.version_minor }},enable=true + type=raw,value=${{ inputs.version_major }}.${{ env.version_minor }}-${{ env.date_stamp }},enable=true + + - + name: Build images + id: build-images + uses: docker/build-push-action@v5 + with: + provenance: false + context: "{{defaultContext}}:Containerfiles/${{ inputs.version_major }}" + file: ./Containerfile.${{ matrix.image_types }} + platforms: ${{ env.platforms }} + push: false + load: true + tags: ${{ steps.meta.outputs.tags }} + + - + name: Test images + id: test-images + run: | + # [Test] + platforms="${{ env.platforms }}" + for platform in ${platforms//,/ }; do + echo "Testing AlmaLinux ${{ inputs.version_major }} ${{ matrix.image_types }} for ${platform} image:" + + docker run --platform=${platform} ${{ steps.build-images.outputs.digest }} /bin/bash -c " \ + uname -m \ + && cat /etc/almalinux-release \ + && ( test "${{ matrix.image_types }}" != "micro" && rpm -q gpg-pubkey) || true " + done + + - + name: Push images to Client Library + id: push-images + uses: docker/build-push-action@v5 + with: + provenance: false + context: "{{defaultContext}}:Containerfiles/${{ inputs.version_major }}" + file: ./Containerfile.${{ matrix.image_types }} + platforms: ${{ env.platforms }} + push: true + tags: ${{ steps.meta.outputs.tags }} + + # Change date stamp in 'docker-library/Containerfiles/*/Containerfile.*' + - + name: Change date stamp in Containerfile (default and minimal only) + # 'default' or 'minimal' images only go to Docker Official Library + if: matrix.image_types == 'default' || matrix.image_types == 'minimal' + run: | + containerfile=docker-library/Containerfiles/${{ inputs.version_major }}/Containerfile.${{ matrix.image_types }} + + case ${{ matrix.image_types }} in + default) + tags="${{ inputs.version_major }}, ${{ inputs.version_major }}.${{ env.version_minor }}, ${{ inputs.version_major }}.${{ env.version_minor }}-${{ env.date_stamp }}" + [ "${{ inputs.version_major }}" = "9" ] && tags="latest, ${tags}" ;; + minimal) + tags="${{ inputs.version_major }}-${{ matrix.image_types }}, ${{ inputs.version_major }}.${{ env.version_minor }}-${{ matrix.image_types }}, ${{ inputs.version_major }}.${{ env.version_minor }}-${{ matrix.image_types }}-${{ env.date_stamp }}" + [ "${{ inputs.version_major }}" = "9" ] && tags="minimal, ${tags}" ;; + *) + esac + + # Tags: 8, 8.9, 8.9-20231124 + sed -i "/^\([[:space:]]*#[[:space:]]*Tags: \).*/s//\1${tags}/" ${containerfile} + + # FROM quay.io/almalinuxorg/almalinux:8.9-20231124 + sed -i 's/^\([[:space:]]*FROM[[:space:]]\+.\+:\).\+$/\1${{ inputs.version_major }}.${{ env.version_minor }}-${{ env.date_stamp}}/' ${containerfile} + + # [Debug] + cat ${containerfile} + + # Upload changed 'Containerfiles/*/Containerfile.*' + - + name: Upload changed Containerfile (default and minimal only) + uses: actions/upload-artifact@v4 + # 'default' or 'minimal' images only go to Docker Official Library + if: matrix.image_types == 'default' || matrix.image_types == 'minimal' + with: + name: containerfiles-${{ matrix.image_types }} + path: docker-library/Containerfiles/${{ inputs.version_major }}/Containerfile.${{ matrix.image_types }} + + outputs: + date_stamp: ${{ steps.date_stamp.outputs.date_stamp }} + + commit: + # 'default' or 'minimal' images only go to Docker Official Library + if: inputs.type_default || inputs.type_minimal + name: Collect and save changed Containerfile(s) used by Docker Official Library + runs-on: ubuntu-latest + needs: + - build + steps: + + - + name: Checkout ${{ github.repository }}, branch 'docker-library' + uses: actions/checkout@v4 + with: + ref: docker-library + + # Download uploaded above 'Containerfiles/*/Containerfile.*' + - + name: Download changed Containerfiles + uses: actions/download-artifact@v4 + with: + merge-multiple: true + path: Containerfiles/${{ inputs.version_major }} + + - + name: "[Debug] Print Containerfiles/${{ inputs.version_major }}/Containerfile.*" + run: | + # [Debug] + cat Containerfiles/${{ inputs.version_major }}/Containerfile.* + + # Commit 'Containerfiles/*/Containerfile.*' + - + name: "Commit and push Containerfiles/${{ inputs.version_major }}/Containerfile.* changes" + # if 'Push to production' is checked + if: inputs.production + uses: EndBug/add-and-commit@v9 + with: + default_author: user_info + new_branch: docker-library + message: "AlmaLinux ${{ inputs.version_major }} image built as of ${{ needs.build.outputs.date_stamp }} (generated on ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})." + push: true diff --git a/.github/workflows/publish-docker-library.yml b/.github/workflows/publish-docker-library.yml new file mode 100644 index 0000000..c055bb0 --- /dev/null +++ b/.github/workflows/publish-docker-library.yml @@ -0,0 +1,223 @@ +name: Publish images to the Docker Library + +on: + workflow_dispatch: + inputs: + pr: + description: 'Publish to the Docker Official Library' + required: true + type: boolean + default: true + + draft: + description: 'Draft Pull Request' + required: true + type: boolean + +env: + # Docker Library Git repository name (upstream): docker-library/official-images + docker_library: docker-library/official-images + # Docker Library Git repository name (local fork): ${{ github.actor }}/official-images or almalinux/docker-library-official-images + local_library: almalinux/docker-library-official-images + +jobs: + prepare-definitions: + + name: "${{ matrix.version_major }} ${{ matrix.image_types }} definition preparing" + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + image_types: + - default + - minimal + + version_major: + - 8 + - 9 + + steps: + - + name: Checkout ${{ github.repository }}, branch 'docker-library' + uses: actions/checkout@v4 + with: + ref: docker-library + fetch-depth: 0 # Checkout all commits + + - + name: Checkout ${{ env.local_library }}, branch 'master' + uses: actions/checkout@v4 + with: + repository: ${{ env.local_library }} + path: official-images + + - + name: "Get need data for the definition" + run: | + # Containerfile for specific version and image type + containerfile=Containerfiles/${{ matrix.version_major }}/Containerfile.${{ matrix.image_types }} + + # The recent commit of the Containerfile + last_commit=$( git log -1 --format='%H' -- ${containerfile} ) + echo "commit_hash=${last_commit}" >> $GITHUB_ENV + + # Get tags from the Containerfile + tags=$( grep 'Tags:' ${containerfile} | sed "s/^[[:space:]]*#[[:space:]]*Tags: \(.*\)$/\1/" ) + echo "tags=${tags}" >> $GITHUB_ENV + + [ -z "$last_commit-x" -o -z "$tags-x" ] && false + + echo "[Debug]" + echo "tags=${tags}" + echo "commit_hash=${last_commit}" + + - + name: "Render the definition" + uses: chuhlomin/render-template@v1 + with: + template: docker-library-definition.tmpl + result_path: official-images/library/almalinux.${{ matrix.version_major }}.${{ matrix.image_types }} + vars: | + tags: ${{ env.tags }} + commit_hash: ${{ env.commit_hash}} + version_major: ${{ matrix.version_major }} + image_type: ${{ matrix.image_types }} + + - + name: "[Debug] Check definitions" + run: | + cat official-images/library/almalinux.${{ matrix.version_major }}.${{ matrix.image_types }} + + # Upload 'official-images/library/almalinux.*' + - uses: actions/upload-artifact@v4 + name: Upload definitions for ${{ matrix.version_major }} ${{ matrix.image_types }} + with: + name: definition-${{ matrix.version_major }}.${{ matrix.image_types }} + path: official-images/library/almalinux.${{ matrix.version_major }}.${{ matrix.image_types }} + + push-pr: + if: inputs.pr + name: "Create Pull Request with the new definition file" + runs-on: ubuntu-latest + needs: + - prepare-definitions + + steps: + - + name: Checkout ${{ env.local_library }}, branch 'master' + uses: actions/checkout@v4 + with: + repository: ${{ env.local_library }} + path: official-images + token: ${{ secrets.GIT_HUB_TOKEN }} + fetch-depth: 0 # Checkout all commits + + - + name: "Sync ${{ env.local_library }} with ${{ env.docker_library }}" + run: | + # sync ${{ env.local_library }} + cd official-images + + git remote add upstream https://github.com/${{ env.docker_library }}.git + git fetch upstream + git checkout master + + ret=0 + git rebase upstream/master || ret=$? + + if [ $ret -ne 0 ]; then + echo "Abort the rebase, reset last commit, stash it and try to rebase again ..." + git rebase --abort + git reset HEAD~1 + git stash + git rebase upstream/master + fi + + # Download uploaded above 'official-images/library/almalinux.*' + - uses: actions/download-artifact@v4 + name: Download all definitions + with: + pattern: definition-* + merge-multiple: true + path: official-images/library/ + + - + name: "Create head of official-images/library/almalinux" + run: | + echo "# This file was generated on ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + Maintainers: The AlmaLinux OS Foundation (@AlmaLinux) + GitRepo: ${{ github.server_url }}/${{ github.repository }}.git" > official-images/library/almalinux + + - + name: "Merge definitions into official-images/library/almalinux" + run: | + # create official-images/library/almalinux + for file in $( ls -1 official-images/library/almalinux.*.* ); do + echo "" >> official-images/library/almalinux + cat $file >> official-images/library/almalinux + done + rm -f official-images/library/almalinux.*.* + + echo "[Debug]" + cat official-images/library/almalinux + + - + name: "Prepare date stamp" + run: | + # date stamp + date_stamp=$(date -u '+%Y%m%d') + echo "date_stamp=${date_stamp}" >> $GITHUB_ENV + [ -z "$date_stamp-x" ] && false + + # [Debug] + echo "date_stamp=${date_stamp}" + + - + name: "Prepare time stamp" + run: | + # time stamp + time_stamp=$(date -u '+%H:%M:%S') + echo "time_stamp=${time_stamp}" >> $GITHUB_ENV + [ -z "$time_stamp-x" ] && false + + # [Debug] + echo "time_stamp=${time_stamp}" + + - + name: "Commit and push official-images/library/almalinux" + uses: EndBug/add-and-commit@v9 + with: + cwd: official-images + default_author: user_info + message: "Almalinux auto-update - ${{ env.date_stamp }} ${{ env.time_stamp }}" + push: true + + - + name: Create Pull Request for official-images/library/almalinux + run: | + # create pull request with 'gh pr create' + gh_opts='' + [ "${{ inputs.draft }}" = "true" ] && gh_opts='--draft' + title="Almalinux auto-update - ${{ env.date_stamp }} ${{ env.time_stamp }}" + body="This is an auto-generated commit. Any concern or issues, please contact or email AlmaLinux OS Foundation cloud-infra@almalinux.org (@AlmaLinux)" + + cd official-images + gh auth login --with-token < <(echo ${{ secrets.GIT_HUB_TOKEN }}) + + prs=$(gh pr list \ + --repo ${{ env.docker_library }} \ + --base master \ + --json title \ + --jq 'length') + + echo "${prs} pull request(s) found for the ${{ env.docker_library }} branch master." + if [ $prs -lt 1 ]; then + echo "Create pull request with 'gh pr create'" + gh pr create \ + --title "${title}" \ + --body "${body}" \ + --repo ${{ env.docker_library }} \ + --base master \ + ${gh_opts} + fi \ No newline at end of file diff --git a/Containerfiles/8/Containerfile.base b/Containerfiles/8/Containerfile.base new file mode 100644 index 0000000..ea7c2f7 --- /dev/null +++ b/Containerfiles/8/Containerfile.base @@ -0,0 +1,71 @@ +ARG SYSBASE=almalinux:8 +FROM ${SYSBASE} as system-build + +RUN mkdir -p /mnt/sys-root; \ + dnf install --installroot /mnt/sys-root --releasever 8 --setopt install_weak_deps=false --nodocs -y \ + almalinux-release \ + bash \ + coreutils-single \ + crypto-policies-scripts \ + findutils \ + gdb-gdbserver \ + glibc-minimal-langpack \ + gzip \ + langpacks-en \ + libuser \ + passwd \ + rootfiles \ + systemd \ + tar \ + usermode \ + vim-minimal \ + virt-what \ + which \ + yum \ + ; +# Additional hacks for kickstart file and backward compatable support +RUN rm -rf /mnt/sys-root/var/log/dnf* /mnt/sys-root/var/log/yum.* /mnt/sys-root/var/cache/dnf/* /mnt/sys-root/var/lib/dnf/repos; \ + rm -rf /mnt/sys-root/var/log/hawkey.log /mnt/sys-root/boot /mnt/sys-root/dev/null /mnt/sys-root/var/log/* /mnt/sys-root/run/blkid ; \ + mkdir -p /mnt/sys-root/run/lock; \ + # generate build time file for compatibility with CentOS /mnt/sys-root/run/* /mnt/sys-root/var/lib/dnf/history* + /bin/date +%Y%m%d_%H%M > /mnt/sys-root/etc/BUILDTIME; \ + echo '%_install_langs C.utf8' > /mnt/sys-root/etc/rpm/macros.image-language-conf; \ + echo 'LANG="C.utf8"' > /mnt/sys-root/etc/locale.conf; \ + echo 'container' > /mnt/sys-root/etc/dnf/vars/infra; \ + touch /mnt/sys-root/etc/.pwd.lock; \ + chmod 600 /mnt/sys-root/etc/.pwd.lock; \ + touch /mnt/sys-root/run/utmp ;\ + chmod 664 /mnt/sys-root/run/utmp ;\ + echo '0.0 0 0.0' > /mnt/sys-root/etc/adjtime; \ + echo '0' >> /mnt/sys-root/etc/adjtime; \ + echo 'UTC' >> /mnt/sys-root/etc/adjtime; \ + echo '# This file has been generated by the Anaconda Installer.' > /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo '# Allow root to log in using ssh. Remove this file to opt-out.' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'PERMITROOTLOGIN="-oPermitRootLogin=yes"' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'KEYMAP="us"' > /mnt/sys-root/etc/vconsole.conf; \ + echo 'FONT="eurlatgr"' >> /mnt/sys-root/etc/vconsole.conf; \ + rm -rf /mnt/sys-root/usr/share/locale/en_CA/ /mnt/sys-root/usr/share/locale/en_GB/ /mnt/sys-root/usr/share/locale/en@* /mnt/sys-root/usr/share/locale/en /mnt/sys-root/usr/share/locale/en*@* /mnt/sys-root/usr/share/i18n/charmaps /mnt/sys-root/usr/share/i18n/locales ;\ + rm -f /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/resolv.conf; \ + touch /mnt/sys-root/etc/hostname + +FROM scratch as stage2 + +COPY --from=system-build /mnt/sys-root/ / + +RUN systemctl set-default multi-user.target; \ + systemctl mask systemd-remount-fs.service \ + dev-hugepages.mount \ + sys-fs-fuse-connections.mount \ + systemd-logind.service \ + getty.target \ + console-getty.service + +FROM scratch + +COPY --from=stage2 / / + +ENV LANG=C.utf8 + +CMD ["/bin/bash"] diff --git a/Containerfiles/8/Containerfile.default b/Containerfiles/8/Containerfile.default new file mode 100644 index 0000000..ad75458 --- /dev/null +++ b/Containerfiles/8/Containerfile.default @@ -0,0 +1,70 @@ +ARG SYSBASE=almalinux:8 +FROM ${SYSBASE} as system-build + +RUN mkdir /mnt/sys-root; \ + dnf install -y \ + --installroot /mnt/sys-root \ + --releasever 8 \ + --setopt install_weak_deps=false \ + --nodocs \ + binutils \ + coreutils-single \ + dnf \ + findutils \ + glibc-minimal-langpack \ + hostname \ + iputils \ + langpacks-en \ + less \ + libcurl-minimal \ + rootfiles \ + tar \ + vim-minimal \ + yum \ + xz \ + ; \ + dnf --installroot /mnt/sys-root clean all; +# Additional hacks for kickstart file and backward compatable support +RUN rm -rf /mnt/sys-root/var/log/dnf* /mnt/sys-root/var/log/yum.* ; \ + rm -rf /mnt/sys-root/var/cache/dnf/* /mnt/sys-root/var/lib/dnf/repos /mnt/sys-root/boot /mnt/sys-root/dev/null ; \ + rm -rf /mnt/sys-root/var/lib/dnf/history* /mnt/sys-root/var/log/hawkey.log /mnt/sys-root/var/log/* ; \ + mkdir -p /mnt/sys-root/run/lock; \ + /bin/date +%Y%m%d_%H%M > /mnt/sys-root/etc/BUILDTIME; \ + echo '%_install_langs C.utf8' > /mnt/sys-root/etc/rpm/macros.image-language-conf; \ + echo 'LANG="C.utf8"' > /mnt/sys-root/etc/locale.conf; \ + echo 'container' > /mnt/sys-root/etc/dnf/vars/infra; \ + touch /mnt/sys-root/etc/.pwd.lock; \ + chmod 600 /mnt/sys-root/etc/.pwd.lock; \ + touch /mnt/sys-root/run/utmp ;\ + chmod 664 /mnt/sys-root/run/utmp ;\ + echo '0.0 0 0.0' > /mnt/sys-root/etc/adjtime; \ + echo '0' >> /mnt/sys-root/etc/adjtime; \ + echo 'UTC' >> /mnt/sys-root/etc/adjtime; \ + echo '# This file has been generated by the Anaconda Installer.' > /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo '# Allow root to log in using ssh. Remove this file to opt-out.' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'PERMITROOTLOGIN="-oPermitRootLogin=yes"' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'KEYMAP="us"' > /mnt/sys-root/etc/vconsole.conf; \ + echo 'FONT="eurlatgr"' >> /mnt/sys-root/etc/vconsole.conf; \ + rm -rf /mnt/sys-root/usr/share/locale/en_US@piglati* /mnt/sys-root/run/blkid ; \ + rm -f /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/resolv.conf; \ + touch /mnt/sys-root/etc/hostname + +FROM scratch as stage2 +COPY --from=system-build /mnt/sys-root/ / + +RUN systemctl set-default multi-user.target; \ + systemctl mask systemd-remount-fs.service \ + dev-hugepages.mount \ + sys-fs-fuse-connections.mount \ + systemd-logind.service \ + getty.target \ + console-getty.service ; + +FROM scratch +COPY --from=stage2 / / + +ENV LANG=C.utf8 + +CMD ["/bin/bash"] diff --git a/Containerfiles/8/Containerfile.init b/Containerfiles/8/Containerfile.init new file mode 100644 index 0000000..e6b0e9e --- /dev/null +++ b/Containerfiles/8/Containerfile.init @@ -0,0 +1,80 @@ +ARG SYSBASE=almalinux:8 +FROM ${SYSBASE} as system-build + +RUN mkdir -p /mnt/sys-root; \ + dnf install --installroot /mnt/sys-root --releasever 8 --setopt install_weak_deps=false --nodocs -y \ + almalinux-release \ + bash \ + coreutils-single \ + crypto-policies-scripts \ + findutils \ + gdb-gdbserver \ + glibc-minimal-langpack \ + gzip \ + langpacks-en \ + libuser \ + passwd \ + procps-ng \ + rootfiles \ + systemd \ + tar \ + usermode \ + vim-minimal \ + virt-what \ + which \ + yum \ + ; +# Additional hacks for kickstart file and backward compatable support +RUN rm -rf /mnt/sys-root/var/log/dnf* /mnt/sys-root/var/log/yum.* /mnt/sys-root/var/cache/dnf/* /mnt/sys-root/var/lib/dnf/repos; \ + rm -rf /mnt/sys-root/var/log/hawkey.log /mnt/sys-root/boot /mnt/sys-root/dev/null /mnt/sys-root/var/log/* /mnt/sys-root/run/blkid ; \ + mkdir -p /mnt/sys-root/run/lock; \ + # generate build time file for compatibility with CentOS /mnt/sys-root/run/* /mnt/sys-root/var/lib/dnf/history* + /bin/date +%Y%m%d_%H%M > /mnt/sys-root/etc/BUILDTIME; \ + echo '%_install_langs C.utf8' > /mnt/sys-root/etc/rpm/macros.image-language-conf; \ + echo 'LANG="C.utf8"' > /mnt/sys-root/etc/locale.conf; \ + echo 'container' > /mnt/sys-root/etc/dnf/vars/infra; \ + touch /mnt/sys-root/etc/.pwd.lock; \ + chmod 600 /mnt/sys-root/etc/.pwd.lock; \ + touch /mnt/sys-root/run/utmp ;\ + chmod 664 /mnt/sys-root/run/utmp ;\ + echo '0.0 0 0.0' > /mnt/sys-root/etc/adjtime; \ + echo '0' >> /mnt/sys-root/etc/adjtime; \ + echo 'UTC' >> /mnt/sys-root/etc/adjtime; \ + echo '# This file has been generated by the Anaconda Installer.' > /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo '# Allow root to log in using ssh. Remove this file to opt-out.' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'PERMITROOTLOGIN="-oPermitRootLogin=yes"' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'KEYMAP="us"' > /mnt/sys-root/etc/vconsole.conf; \ + echo 'FONT="eurlatgr"' >> /mnt/sys-root/etc/vconsole.conf; \ + rm -rf /mnt/sys-root/usr/share/locale/en_CA/ /mnt/sys-root/usr/share/locale/en_GB/ /mnt/sys-root/usr/share/locale/en@* /mnt/sys-root/usr/share/locale/en /mnt/sys-root/usr/share/locale/en*@* /mnt/sys-root/usr/share/i18n/charmaps /mnt/sys-root/usr/share/i18n/locales ;\ + rm -f /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/resolv.conf; \ + touch /mnt/sys-root/etc/hostname + +FROM scratch as stage2 + +COPY --from=system-build /mnt/sys-root/ / + +ENV LANG=C.utf8 + +RUN systemctl set-default multi-user.target; \ + systemctl mask systemd-remount-fs.service \ + dev-hugepages.mount \ + sys-fs-fuse-connections.mount \ + systemd-logind.service \ + getty.target \ + console-getty.service \ + systemd-udev-trigger.service \ + systemd-udevd.service \ + systemd-random-seed.service \ + systemd-machine-id-commit.service + +FROM scratch + +COPY --from=stage2 / / + +ENV LANG=C.utf8 + +CMD ["/sbin/init"] + +STOPSIGNAL SIGRTMIN+3 diff --git a/Containerfiles/8/Containerfile.micro b/Containerfiles/8/Containerfile.micro new file mode 100644 index 0000000..3fe0267 --- /dev/null +++ b/Containerfiles/8/Containerfile.micro @@ -0,0 +1,36 @@ +ARG SYSBASE=almalinux:8 +FROM ${SYSBASE} as system-build + +RUN mkdir -p /mnt/sys-root; \ + dnf install --installroot /mnt/sys-root coreutils-single glibc-minimal-langpack \ + --releasever 8 --setopt install_weak_deps=false --nodocs -y; \ + dnf --installroot /mnt/sys-root clean all; +# Additional hacks for kickstart file and backward compatable support +RUN rm -rf /mnt/sys-root/var/cache/dnf /mnt/sys-root/var/log/dnf* /mnt/sys-root/var/lib/dnf /mnt/sys-root/var/log/yum.*; \ + /bin/date +%Y%m%d_%H%M > /mnt/sys-root/etc/BUILDTIME ; \ + echo '%_install_langs C.utf8' > /mnt/sys-root/etc/rpm/macros.image-language-conf; \ + echo 'LANG="C.utf8"' > /mnt/sys-root/etc/locale.conf; \ + echo 'container' > /mnt/sys-root/etc/dnf/vars/infra; \ + rm -f /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/.pwd.lock; \ + touch /mnt/sys-root/etc/resolv.conf; \ + touch /mnt/sys-root/etc/hostname; \ + chmod 600 /mnt/sys-root/etc/.pwd.lock; \ + rm -rf /mnt/sys-root/usr/share/locale/en* /mnt/sys-root/boot /mnt/sys-root/dev/null /mnt/sys-root/var/log/hawkey.log ; \ + echo '0.0 0 0.0' > /mnt/sys-root/etc/adjtime; \ + echo '0' >> /mnt/sys-root/etc/adjtime; \ + echo 'UTC' >> /mnt/sys-root/etc/adjtime; \ + echo '# This file has been generated by the Anaconda Installer.' > /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo '# Allow root to log in using ssh. Remove this file to opt-out.' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'PERMITROOTLOGIN="-oPermitRootLogin=yes"' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'KEYMAP="us"' > /mnt/sys-root/etc/vconsole.conf; \ + echo 'FONT="eurlatgr"' >> /mnt/sys-root/etc/vconsole.conf; \ + cd /mnt/sys-root/etc ; \ + ln -s ../usr/share/zoneinfo/UTC localtime + +FROM scratch + +COPY --from=system-build /mnt/sys-root/ / + +CMD /bin/sh diff --git a/Containerfiles/8/Containerfile.minimal b/Containerfiles/8/Containerfile.minimal new file mode 100644 index 0000000..04a8e9c --- /dev/null +++ b/Containerfiles/8/Containerfile.minimal @@ -0,0 +1,48 @@ +ARG SYSBASE=almalinux:8 +FROM ${SYSBASE} as builder + +RUN mkdir /mnt/sys-root; \ + dnf install \ + --installroot /mnt/sys-root \ + --releasever 8 \ + --setopt install_weak_deps=false \ + --nodocs -y \ + coreutils-single \ + glibc-minimal-langpack \ + microdnf \ + libusbx \ + langpacks-en \ + rootfiles; \ + dnf --installroot /mnt/sys-root clean all; +# Additional hacks for kickstart file and backward compatable support +RUN rm -rf /mnt/sys-root/var/log/dnf* /mnt/sys-root/var/log/yum.* /mnt/sys-root/var/cache/dnf /mnt/sys-root/var/lib/dnf/repos; \ + rm -rf /mnt/sys-root/var/lib/dnf/history* /mnt/sys-root/var/log/hawkey.log /mnt/sys-root/boot /mnt/sys-root/dev/null /mnt/sys-root/run/*; \ + mkdir -p /mnt/sys-root/run/lock; \ + # generate build time file for compatibility with CentOS + /bin/date +%Y%m%d_%H%M > /mnt/sys-root/etc/BUILDTIME; \ + echo '%_install_langs C.utf8' > /mnt/sys-root/etc/rpm/macros.image-language-conf; \ + echo 'LANG="C.utf8"' > /mnt/sys-root/etc/locale.conf; \ + echo 'container' > /mnt/sys-root/etc/dnf/vars/infra; \ + touch /mnt/sys-root/etc/.pwd.lock; \ + chmod 600 /mnt/sys-root/etc/.pwd.lock; \ + echo '0.0 0 0.0' > /mnt/sys-root/etc/adjtime; \ + echo '0' >> /mnt/sys-root/etc/adjtime; \ + echo 'UTC' >> /mnt/sys-root/etc/adjtime; \ + echo '# This file has been generated by the Anaconda Installer.' > /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo '# Allow root to log in using ssh. Remove this file to opt-out.' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'PERMITROOTLOGIN="-oPermitRootLogin=yes"' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'KEYMAP="us"' > /mnt/sys-root/etc/vconsole.conf; \ + echo 'FONT="eurlatgr"' >> /mnt/sys-root/etc/vconsole.conf; \ + rm -rf /mnt/sys-root/usr/share/locale/en_CA/ /mnt/sys-root/usr/share/locale/en_GB/ /mnt/sys-root/usr/share/locale/en@* /mnt/sys-root/usr/share/locale/en /mnt/sys-root/usr/share/locale/en*@* /mnt/sys-root/usr/share/i18n/charmaps /mnt/sys-root/usr/share/i18n/locales ;\ + rm -f /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/resolv.conf; \ + touch /mnt/sys-root/etc/hostname; \ + cd /mnt/sys-root/etc ; \ + ln -s ../usr/share/zoneinfo/UTC localtime + +# Almalinux minimal build +FROM scratch +COPY --from=builder /mnt/sys-root/ / + +CMD ["/bin/bash"] diff --git a/Containerfiles/9/Containerfile.base b/Containerfiles/9/Containerfile.base new file mode 100644 index 0000000..79f6cdc --- /dev/null +++ b/Containerfiles/9/Containerfile.base @@ -0,0 +1,91 @@ +ARG SYSBASE=almalinux:9 +FROM ${SYSBASE} as system-build + +RUN mkdir -p /mnt/sys-root; \ + dnf install -y \ + --installroot /mnt/sys-root --releasever 9 --setopt install_weak_deps=false --nodocs \ + almalinux-release \ + bash \ + coreutils-single \ + crypto-policies-scripts \ + curl-minimal \ + findutils \ + gdb-gdbserver \ + glibc-minimal-langpack \ + gzip \ + libcurl-minimal \ + libusbx \ + rootfiles \ + systemd \ + tar \ + usermode \ + vim-minimal \ + virt-what \ + yum \ + ; \ + echo '%_install_langs en_US.UTF-8' > /etc/rpm/macros.image-language-conf ;\ + dnf reinstall -y \ + --installroot /mnt/sys-root \ + --releasever 9 \ + --setopt install_weak_deps=false \ + --nodocs \ + krb5-libs ; \ + dnf --installroot /mnt/sys-root clean all; +# Additional hacks for kickstart file and backward compatable support +RUN rm -rf /mnt/sys-root/var/log/dnf* /mnt/sys-root/var/log/yum.* /mnt/sys-root/var/cache/dnf/* /mnt/sys-root/var/lib/dnf/repos; \ + rm -rf /mnt/sys-root/var/log/hawkey.log /mnt/sys-root/boot /mnt/sys-root/dev/null /mnt/sys-root/var/log/* /mnt/sys-root/run/blkid ; \ + mkdir -p /mnt/sys-root/run/lock; \ + # generate build time file for compatibility with CentOS /mnt/sys-root/run/* /mnt/sys-root/var/lib/dnf/history* + /bin/date +%Y%m%d_%H%M > /mnt/sys-root/etc/BUILDTIME; \ + echo '%_install_langs C.utf8' > /mnt/sys-root/etc/rpm/macros.image-language-conf; \ + echo 'LANG="C.utf8"' > /mnt/sys-root/etc/locale.conf; \ + echo 'container' > /mnt/sys-root/etc/dnf/vars/infra; \ + touch /mnt/sys-root/etc/.pwd.lock; \ + chmod 600 /mnt/sys-root/etc/.pwd.lock; \ + touch /mnt/sys-root/run/utmp ;\ + chmod 664 /mnt/sys-root/run/utmp ;\ + echo '0.0 0 0.0' > /mnt/sys-root/etc/adjtime; \ + echo '0' >> /mnt/sys-root/etc/adjtime; \ + echo 'UTC' >> /mnt/sys-root/etc/adjtime; \ + echo '# This file has been generated by the Anaconda Installer.' > /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo '# Allow root to log in using ssh. Remove this file to opt-out.' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'PERMITROOTLOGIN="-oPermitRootLogin=yes"' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'KEYMAP="us"' > /mnt/sys-root/etc/vconsole.conf; \ + echo 'FONT="eurlatgr"' >> /mnt/sys-root/etc/vconsole.conf; \ + rm -rf /mnt/sys-root/usr/share/locale/en_CA/ /mnt/sys-root/usr/share/locale/en_GB/ /mnt/sys-root/usr/share/locale/en@* /mnt/sys-root/usr/share/locale/en /mnt/sys-root/usr/share/locale/en*@* /mnt/sys-root/usr/share/i18n/charmaps /mnt/sys-root/usr/share/i18n/locales ;\ + rm -f /mnt/sys-root/etc/machine-id /mnt/sys-root/var/cache/dnf/.gpgkeyschecked.yum ; \ + touch /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/resolv.conf; \ + touch /mnt/sys-root/etc/hostname +# AL9 specific hacks +RUN mkdir -p /mnt/sys-root/var/cache/private /mnt/sys-root/var/lib/private /mnt/sys-root/var/lib/systemd/coredump /mnt/sys-root/var/lib/tpm2-tss/system/keystore ;\ + mkdir -p /mnt/sys-root/run/cryptsetup /mnt/sys-root/run/lock/subsys /mnt/sys-root/run/log /mnt/sys-root/run/user /mnt/sys-root/run/tpm2-tss/eventlog ;\ + mkdir -p /mnt/sys-root/run/systemd/ask-password /mnt/sys-root/run/systemd/machines /mnt/sys-root/run/systemd/seats /mnt/sys-root/run/systemd/sessions /mnt/sys-root/run/systemd/shutdown /mnt/sys-root/run/systemd/users ;\ + chmod 700 /mnt/sys-root/var/cache/private ; \ + chmod 700 /mnt/sys-root/var/lib/private ; \ + chmod 700 /mnt/sys-root/run/cryptsetup ; \ + groupadd -R '/mnt/sys-root/' -r -p '!*' -g 996 sgx && groupadd -R '/mnt/sys-root/' -r -p '!*' -g 995 systemd-oom ; \ + useradd -R '/mnt/sys-root/' -r -c 'systemd Userspace OOM Killer' -g 995 -u 995 -s '/usr/sbin/nologin' -M -d '/' systemd-oom ; \ + sed -i "/sgx/d" /mnt/sys-root/etc/group- ; \ + sed -i "/sgx/d" /mnt/sys-root/etc/gshadow- ; \ + cd /mnt/sys-root/etc ; \ + ln -s ../usr/share/zoneinfo/UTC localtime ; + +FROM scratch as stage2 + +COPY --from=system-build /mnt/sys-root/ / + +RUN systemctl set-default multi-user.target; \ + systemctl mask systemd-remount-fs.service \ + dev-hugepages.mount \ + sys-fs-fuse-connections.mount \ + systemd-logind.service \ + getty.target \ + console-getty.service + +FROM scratch +COPY --from=stage2 / / + +ENV LANG=C.utf8 + +CMD ["/bin/bash"] diff --git a/Containerfiles/9/Containerfile.default b/Containerfiles/9/Containerfile.default new file mode 100644 index 0000000..6de06c5 --- /dev/null +++ b/Containerfiles/9/Containerfile.default @@ -0,0 +1,95 @@ +ARG SYSBASE=almalinux:9 +FROM ${SYSBASE} as system-build + +RUN mkdir /mnt/sys-root; \ + dnf install -y \ + --installroot /mnt/sys-root \ + --releasever 9 \ + --setopt install_weak_deps=false \ + --nodocs \ + almalinux-release \ + bash \ + binutils \ + coreutils-single \ + crypto-policies-scripts \ + curl-minimal \ + findutils \ + hostname \ + iputils \ + glibc-minimal-langpack \ + krb5-libs \ + less \ + libcurl-minimal \ + rootfiles \ + systemd \ + tar \ + vim-minimal \ + yum \ + xz \ + ; \ + echo '%_install_langs en_US.UTF-8' > /etc/rpm/macros.image-language-conf ;\ + dnf reinstall -y \ + --installroot /mnt/sys-root \ + --releasever 9 \ + --setopt install_weak_deps=false \ + --nodocs \ + krb5-libs ; \ + dnf --installroot /mnt/sys-root clean all; +# Additional hacks for kickstart file and backward compatable support /mnt/sys-root/var/lib/dnf/history* +RUN rm -rf /mnt/sys-root/var/log/dnf* /mnt/sys-root/var/log/yum.* /mnt/sys-root/usr/share/i18n/charmaps /mnt/sys-root/usr/share/i18n/locales ; \ + rm -rf /mnt/sys-root/var/cache/dnf/* /mnt/sys-root/var/lib/dnf/repos /mnt/sys-root/boot /mnt/sys-root/dev/null ; \ + rm -rf /mnt/sys-root/var/log/hawkey.log /mnt/sys-root/var/log/* ; \ + mkdir -p /mnt/sys-root/run/lock; \ + /bin/date +%Y%m%d_%H%M > /mnt/sys-root/etc/BUILDTIME; \ + echo '%_install_langs C.utf8' > /mnt/sys-root/etc/rpm/macros.image-language-conf; \ + echo 'LANG="C.utf8"' > /mnt/sys-root/etc/locale.conf; \ + echo 'container' > /mnt/sys-root/etc/dnf/vars/infra; \ + touch /mnt/sys-root/etc/.pwd.lock; \ + chmod 600 /mnt/sys-root/etc/.pwd.lock; \ + touch /mnt/sys-root/run/utmp ;\ + chmod 664 /mnt/sys-root/run/utmp ;\ + echo '0.0 0 0.0' > /mnt/sys-root/etc/adjtime; \ + echo '0' >> /mnt/sys-root/etc/adjtime; \ + echo 'UTC' >> /mnt/sys-root/etc/adjtime; \ + echo '# This file has been generated by the Anaconda Installer.' > /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo '# Allow root to log in using ssh. Remove this file to opt-out.' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'PERMITROOTLOGIN="-oPermitRootLogin=yes"' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'KEYMAP="us"' > /mnt/sys-root/etc/vconsole.conf; \ + echo 'FONT="eurlatgr"' >> /mnt/sys-root/etc/vconsole.conf; \ + rm -rf /mnt/sys-root/usr/share/locale/en_US@piglati* /mnt/sys-root/run/blkid /mnt/sys-root/var/cache/dnf/.gpgkeyschecked.yum ; \ + rm -f /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/resolv.conf; \ + touch /mnt/sys-root/etc/hostname +# AL9 specific hacks +RUN mkdir -p /mnt/sys-root/var/cache/private /mnt/sys-root/var/lib/private /mnt/sys-root/var/lib/systemd/coredump /mnt/sys-root/var/lib/tpm2-tss/system/keystore ;\ + mkdir -p /mnt/sys-root/run/cryptsetup /mnt/sys-root/run/lock/subsys /mnt/sys-root/run/log /mnt/sys-root/run/user /mnt/sys-root/run/tpm2-tss/eventlog ;\ + mkdir -p /mnt/sys-root/run/systemd/ask-password /mnt/sys-root/run/systemd/machines /mnt/sys-root/run/systemd/seats /mnt/sys-root/run/systemd/sessions /mnt/sys-root/run/systemd/shutdown /mnt/sys-root/run/systemd/users ;\ + chmod 700 /mnt/sys-root/var/cache/private ; \ + chmod 700 /mnt/sys-root/var/lib/private ; \ + chmod 700 /mnt/sys-root/run/cryptsetup ; \ + groupadd -R '/mnt/sys-root/' -r -p '!*' -g 996 sgx && groupadd -R '/mnt/sys-root/' -r -p '!*' -g 995 systemd-oom ; \ + useradd -R '/mnt/sys-root/' -r -c 'systemd Userspace OOM Killer' -g 995 -u 995 -s '/usr/sbin/nologin' -M -d '/' systemd-oom ; \ + sed -i "/sgx/d" /mnt/sys-root/etc/group- ; \ + sed -i "/sgx/d" /mnt/sys-root/etc/gshadow- ; \ + cd /mnt/sys-root/etc ; \ + ln -s ../usr/share/zoneinfo/UTC localtime ; + +# Almalinux default build +FROM scratch as stage2 +COPY --from=system-build /mnt/sys-root/ / + +RUN systemctl set-default multi-user.target; \ + systemctl mask systemd-remount-fs.service \ + dev-hugepages.mount \ + sys-fs-fuse-connections.mount \ + systemd-logind.service \ + getty.target \ + console-getty.service + +FROM scratch +COPY --from=stage2 / / + +ENV LANG=C.utf8 + +CMD ["/bin/bash"] diff --git a/Containerfiles/9/Containerfile.init b/Containerfiles/9/Containerfile.init new file mode 100644 index 0000000..3cf2acf --- /dev/null +++ b/Containerfiles/9/Containerfile.init @@ -0,0 +1,103 @@ +ARG SYSBASE=almalinux:9 +FROM ${SYSBASE} as system-build + +RUN mkdir /mnt/sys-root; \ + dnf install -y \ +# --nogpgcheck --repoid=AppStream --repoid=BaseOS \ +# --repofrompath='BaseOS,https://repo.almalinux.org/almalinux/9/BaseOS/$basearch/os/' \ +# --repofrompath='AppStream,https://repo.almalinux.org/almalinux/9/AppStream/$basearch/os/' \ + --installroot /mnt/sys-root \ + --releasever 9 \ + --setopt install_weak_deps=false \ + --nodocs \ + almalinux-release \ + bash \ + coreutils-single \ + crypto-policies-scripts \ + curl-minimal \ + findutils \ + gdb-gdbserver \ + glibc-minimal-langpack \ + gzip \ + libcurl-minimal \ + libusbx \ + procps-ng \ + rootfiles \ + systemd \ + tar \ + usermode \ + vim-minimal \ + virt-what \ + yum \ + ; \ + echo '%_install_langs en_US.UTF-8' > /etc/rpm/macros.image-language-conf ;\ + dnf reinstall -y \ + --installroot /mnt/sys-root \ + --releasever 9 \ + --setopt install_weak_deps=false \ + --nodocs \ + krb5-libs ; \ + dnf --installroot /mnt/sys-root clean all; +# Additional hacks for kickstart file and backward compatable support +RUN rm -rf /mnt/sys-root/var/log/dnf* /mnt/sys-root/var/log/yum.* /mnt/sys-root/var/cache/dnf/* /mnt/sys-root/var/lib/dnf/repos; \ + rm -rf /mnt/sys-root/var/log/hawkey.log /mnt/sys-root/boot /mnt/sys-root/dev/null /mnt/sys-root/var/log/* /mnt/sys-root/run/blkid ; \ + mkdir -p /mnt/sys-root/run/lock; \ + # generate build time file for compatibility with CentOS /mnt/sys-root/run/* /mnt/sys-root/var/lib/dnf/history* + /bin/date +%Y%m%d_%H%M > /mnt/sys-root/etc/BUILDTIME; \ + echo '%_install_langs C.utf8' > /mnt/sys-root/etc/rpm/macros.image-language-conf; \ + echo 'LANG="C.utf8"' > /mnt/sys-root/etc/locale.conf; \ + echo 'container' > /mnt/sys-root/etc/dnf/vars/infra; \ + touch /mnt/sys-root/etc/.pwd.lock; \ + chmod 600 /mnt/sys-root/etc/.pwd.lock; \ + touch /mnt/sys-root/run/utmp ;\ + chmod 664 /mnt/sys-root/run/utmp ;\ + echo '0.0 0 0.0' > /mnt/sys-root/etc/adjtime; \ + echo '0' >> /mnt/sys-root/etc/adjtime; \ + echo 'UTC' >> /mnt/sys-root/etc/adjtime; \ + echo '# This file has been generated by the Anaconda Installer.' > /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo '# Allow root to log in using ssh. Remove this file to opt-out.' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'PERMITROOTLOGIN="-oPermitRootLogin=yes"' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'KEYMAP="us"' > /mnt/sys-root/etc/vconsole.conf; \ + echo 'FONT="eurlatgr"' >> /mnt/sys-root/etc/vconsole.conf; \ + rm -rf /mnt/sys-root/usr/share/locale/en_CA/ /mnt/sys-root/usr/share/locale/en_GB/ /mnt/sys-root/usr/share/locale/en@* /mnt/sys-root/usr/share/locale/en /mnt/sys-root/usr/share/locale/en*@* /mnt/sys-root/usr/share/i18n/charmaps /mnt/sys-root/usr/share/i18n/locales ;\ + rm -f /mnt/sys-root/etc/machine-id /mnt/sys-root/var/cache/dnf/.gpgkeyschecked.yum ; \ + touch /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/resolv.conf; \ + touch /mnt/sys-root/etc/hostname +# AL9 specific hacks +RUN mkdir -p /mnt/sys-root/var/cache/private /mnt/sys-root/var/lib/private /mnt/sys-root/var/lib/systemd/coredump /mnt/sys-root/var/lib/tpm2-tss/system/keystore ;\ + mkdir -p /mnt/sys-root/run/cryptsetup /mnt/sys-root/run/lock/subsys /mnt/sys-root/run/log /mnt/sys-root/run/user /mnt/sys-root/run/tpm2-tss/eventlog ;\ + mkdir -p /mnt/sys-root/run/systemd/ask-password /mnt/sys-root/run/systemd/machines /mnt/sys-root/run/systemd/seats /mnt/sys-root/run/systemd/sessions /mnt/sys-root/run/systemd/shutdown /mnt/sys-root/run/systemd/users ;\ + chmod 700 /mnt/sys-root/var/cache/private ; \ + chmod 700 /mnt/sys-root/var/lib/private ; \ + chmod 700 /mnt/sys-root/run/cryptsetup ; \ + groupadd -R '/mnt/sys-root/' -r -p '!*' -g 996 sgx && groupadd -R '/mnt/sys-root/' -r -p '!*' -g 995 systemd-oom ; \ + useradd -R '/mnt/sys-root/' -r -c 'systemd Userspace OOM Killer' -g 995 -u 995 -s '/usr/sbin/nologin' -M -d '/' systemd-oom ; \ + sed -i "/sgx/d" /mnt/sys-root/etc/group- ; \ + sed -i "/sgx/d" /mnt/sys-root/etc/gshadow- ; \ + cd /mnt/sys-root/etc ; \ + ln -s ../usr/share/zoneinfo/UTC localtime ; + +FROM scratch as stage2 + +COPY --from=system-build /mnt/sys-root/ / + +RUN systemctl set-default multi-user.target; \ + systemctl mask systemd-remount-fs.service \ + dev-hugepages.mount \ + sys-fs-fuse-connections.mount \ + systemd-logind.service \ + getty.target \ + console-getty.service \ + systemd-udev-trigger.service \ + systemd-udevd.service \ + systemd-random-seed.service \ + systemd-machine-id-commit.service + +FROM scratch +COPY --from=stage2 / / + +ENV LANG=C.utf8 + +STOPSIGNAL SIGRTMIN+3 +CMD ["/sbin/init"] diff --git a/Containerfiles/9/Containerfile.micro b/Containerfiles/9/Containerfile.micro new file mode 100644 index 0000000..0b60966 --- /dev/null +++ b/Containerfiles/9/Containerfile.micro @@ -0,0 +1,37 @@ +ARG SYSBASE=almalinux:9 +FROM ${SYSBASE} as system-build + +RUN mkdir -p /mnt/sys-root; \ + dnf install --installroot /mnt/sys-root coreutils-single glibc-minimal-langpack \ + --releasever 9 --setopt install_weak_deps=false --nodocs -y; \ + dnf --installroot /mnt/sys-root clean all; +# Additional hacks for kickstart file and backward compatable support +RUN rm -rf /mnt/sys-root/var/cache/dnf /mnt/sys-root/var/log/dnf* /mnt/sys-root/var/lib/dnf /mnt/sys-root/var/log/yum.*; \ + /bin/date +%Y%m%d_%H%M > /mnt/sys-root/etc/BUILDTIME ; \ + echo '%_install_langs C.utf8' > /mnt/sys-root/etc/rpm/macros.image-language-conf; \ + echo 'LANG="C.utf8"' > /mnt/sys-root/etc/locale.conf; \ + echo 'container' > /mnt/sys-root/etc/dnf/vars/infra; \ + rm -f /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/resolv.conf; \ + touch /mnt/sys-root/etc/hostname; \ + touch /mnt/sys-root/etc/.pwd.lock; \ + chmod 600 /mnt/sys-root/etc/.pwd.lock; \ + rm -rf /mnt/sys-root/usr/share/locale/en* /mnt/sys-root/boot /mnt/sys-root/dev/null /mnt/sys-root/var/log/hawkey.log ; \ + echo '0.0 0 0.0' > /mnt/sys-root/etc/adjtime; \ + echo '0' >> /mnt/sys-root/etc/adjtime; \ + echo 'UTC' >> /mnt/sys-root/etc/adjtime; \ + echo '# This file has been generated by the Anaconda Installer.' > /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo '# Allow root to log in using ssh. Remove this file to opt-out.' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'PERMITROOTLOGIN="-oPermitRootLogin=yes"' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'KEYMAP="us"' > /mnt/sys-root/etc/vconsole.conf; \ + echo 'FONT="eurlatgr"' >> /mnt/sys-root/etc/vconsole.conf; \ + mkdir -p /mnt/sys-root/run/lock; \ + cd /mnt/sys-root/etc ; \ + ln -s ../usr/share/zoneinfo/UTC localtime + +FROM scratch + +COPY --from=system-build /mnt/sys-root/ / + +CMD /bin/sh diff --git a/Containerfiles/9/Containerfile.minimal b/Containerfiles/9/Containerfile.minimal new file mode 100644 index 0000000..5d56399 --- /dev/null +++ b/Containerfiles/9/Containerfile.minimal @@ -0,0 +1,69 @@ +ARG SYSBASE=almalinux:9 +FROM ${SYSBASE} as system-build + +RUN mkdir /mnt/sys-root; \ + dnf install -y \ + --installroot /mnt/sys-root \ + --releasever 9 \ + --setopt install_weak_deps=false \ + --nodocs \ + almalinux-release \ + bash \ + coreutils-single \ + curl-minimal \ + glibc-minimal-langpack \ + libcurl-minimal \ + libusbx \ + microdnf \ + rootfiles \ + ; \ + echo '%_install_langs en_US.UTF-8' > /etc/rpm/macros.image-language-conf ;\ + dnf reinstall -y \ + --installroot /mnt/sys-root \ + --releasever 9 \ + --setopt install_weak_deps=false \ + --nodocs \ + krb5-libs ; \ + dnf --installroot /mnt/sys-root clean all; +# Additional hacks for kickstart file and backward compatable support +RUN rm -rf /mnt/sys-root/var/log/dnf* /mnt/sys-root/var/log/yum.* /mnt/sys-root/var/cache/dnf /mnt/sys-root/var/lib/dnf/repos; \ + rm -rf /mnt/sys-root/var/lib/dnf/history* /mnt/sys-root/var/log/hawkey.log /mnt/sys-root/boot /mnt/sys-root/dev/null /mnt/sys-root/run/*; \ + mkdir -p /mnt/sys-root/run/lock; \ + # generate build time file for compatibility with CentOS + /bin/date +%Y%m%d_%H%M > /mnt/sys-root/etc/BUILDTIME; \ + echo '%_install_langs C.utf8' > /mnt/sys-root/etc/rpm/macros.image-language-conf; \ + echo 'LANG="C.utf8"' > /mnt/sys-root/etc/locale.conf; \ + echo 'container' > /mnt/sys-root/etc/dnf/vars/infra; \ + touch /mnt/sys-root/etc/.pwd.lock; \ + chmod 600 /mnt/sys-root/etc/.pwd.lock; \ + echo '0.0 0 0.0' > /mnt/sys-root/etc/adjtime; \ + echo '0' >> /mnt/sys-root/etc/adjtime; \ + echo 'UTC' >> /mnt/sys-root/etc/adjtime; \ + echo '# This file has been generated by the Anaconda Installer.' > /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo '# Allow root to log in using ssh. Remove this file to opt-out.' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'PERMITROOTLOGIN="-oPermitRootLogin=yes"' >> /mnt/sys-root/etc/sysconfig/sshd-permitrootlogin ;\ + echo 'KEYMAP="us"' > /mnt/sys-root/etc/vconsole.conf; \ + echo 'FONT="eurlatgr"' >> /mnt/sys-root/etc/vconsole.conf; \ + # /mnt/sys-root/usr/share/locale/en@* /mnt/sys-root/usr/share/locale/en /mnt/sys-root/usr/share/locale/en*@* + rm -rf /mnt/sys-root/usr/share/locale/en_CA/ /mnt/sys-root/usr/share/locale/en_GB/ /mnt/sys-root/usr/share/i18n/charmaps /mnt/sys-root/usr/share/i18n/locales ;\ + rm -f /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/machine-id; \ + touch /mnt/sys-root/etc/resolv.conf; \ + touch /mnt/sys-root/etc/hostname; \ + mkdir -p /mnt/sys-root/var/cache/private /mnt/sys-root/var/lib/private /mnt/sys-root/var/lib/systemd/coredump ;\ + chmod 700 /mnt/sys-root/var/cache/private ; \ + chmod 700 /mnt/sys-root/var/lib/private ; \ + groupadd -R '/mnt/sys-root/' -r -p '!*' -g 996 sgx && groupadd -R '/mnt/sys-root/' -r -p '!*' -g 995 systemd-oom ; \ + useradd -R '/mnt/sys-root/' -r -c 'systemd Userspace OOM Killer' -g 995 -u 995 -s '/usr/sbin/nologin' -M -d '/' systemd-oom ; \ + sed -i "/sgx/d" /mnt/sys-root/etc/group- ; \ + sed -i "/sgx/d" /mnt/sys-root/etc/gshadow- ; \ + cd /mnt/sys-root/etc ; \ + ln -s ../usr/share/zoneinfo/UTC localtime ; \ + cd /mnt/sys-root/etc/systemd/system ; \ + ln -s /usr/lib/systemd/system/multi-user.target default.target + +# Almalinux minimal build +FROM scratch +COPY --from=system-build /mnt/sys-root/ / + +CMD ["/bin/bash"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..5c09208 --- /dev/null +++ b/README.md @@ -0,0 +1,705 @@ +# Overview + +The repository provides scripts and workflows to: + +- Build AlmaLinux Container Images (Docker Images) +- Test these images +- Push them into different registries, the *Client Library*: + - [Docker.io](https://hub.docker.com) + - [Quay.io](https://quay.io) + - [GitHub Packages](https://github.com/features/packages) +- Publish the images to the [Docker *Official Library*](https://hub.docker.com/u/library). + +These Container Images can be used with all [OCI complaint](https://opencontainers.org/) container runtime environments such as Docker, Podman and Kubernetes as well as serve as drop-in replacements for CentOS images as they reach [End of Life](https://centos.org/centos-linux-eol/). + +## Requirements/Prerequisites + +Personal, Organization or Enterprise account on GitHub is the only requirement. Please read more about [accounts on GitHub](https://docs.github.com/en/enterprise-server@3.10/get-started/learning-about-github/types-of-github-accounts). + +## The idea + + The project utilizes [GitHub Actions](https://github.com/features/actions) to provide public, transparent and fast workflows that are easy to understand, use and modify. + +There are two workflows on GitHub Actions designed to achieve the idea: +- Build, test and push all types of container images into the *Client Library* +- Use some of these images (`default` and `minimal` configurations types only) to request Docker to create images for the *Official Library*. + +You can read more about how the workflows work in the [section](#workflows-jobs-and-steps) below. + +The AlmaLinux ***Client Library*** includes the following registries/organizations: +- [Docker.io/almalinux](https://hub.docker.com/u/almalinux) (Sponsored by OSS) +- [Quay.io/almalinuxorg](https://quay.io/organization/almalinuxorg) +- [Ghcr.io/AlmaLinux](https://github.com/orgs/AlmaLinux/packages) + +The AlmaLinux [***Official Library***](https://hub.docker.com/_/almalinux) is maintained by Docker. + +## Containerfiles + +Each image pushed to the *Client Library* is built from a corresponding [Containerfile](https://github.com/AlmaLinux/container-images/tree/main/Containerfiles) that is a unique file for each AlmaLinux release and configuration type: `base`, `default`, `init`, `micro`, `minimal`. +These files match [Dockerfile](https://docs.docker.com/reference/dockerfile/) standard and contain commands and instructions on how to install AlmaLinux's whole root filesystem in them. + +Images for the *Docker Official* Library are built using other [Containerfiles](https://github.com/AlmaLinux/container-images/tree/docker-library/Containerfiles) that are also designed for each AlmaLinux release but only `default` and `minimal` types. These Containerfiles correspond images from the *Client Library* at [Quay.io/almalinuxorg](https://quay.io/organization/almalinuxorg) + +## What Container Images are built + +### AlmaLinux releases + +Container images are built for AlmaLinux OS 8 and 9. The Major version of the release must be set for the **Build, Test and Push** workflow. The Minor version is automatically set by the workflow as *the latest*. + +**Publish Images** workflow pushes build requests to the Docker also for both AlmaLinux releases, 8 and 9. + +### Image configuration types + +AlmaLinux container images types match [Red Hat Universal Base Image](https://catalog.redhat.com/software/base-images): +- `base` +- `default` (the image is also available via the Docker *Official Library*) +- `init` +- `micro` +- `minimal` (the image is also available via the Docker *Official Library*) + +### Supported platforms/architectures + +**Build, Test and Push** workflow builds container images of the following platforms simultaneously with `docker buildx`. They result in the following machine hardware names (`uname -m`): + +| docker platform | hardware name | +| --------------- | ------------- | +| linux/amd64 | x86_64 | +| linux/ppc64le | ppc64le | +| linux/s390x | s390x | +| linux/arm64 | aarch64 | + +The [**containerd image store store**](https://docs.docker.com/storage/containerd/) for Docker Engine together with `buildx` are used to build and push multiple platforms at once. + +### Repositories + +The following *repositories* are created on all registries ([Docker.io/almalinux](https://hub.docker.com/u/almalinux), [Quay.io/almalinuxorg](https://quay.io/organization/almalinuxorg), [Ghcr.io/AlmaLinux](https://github.com/orgs/AlmaLinux/packages)) for all supported images types: + +- `/almalinux` - [Quay.io/almalinuxorg](https://quay.io/repository/almalinuxorg/almalinux) only. Is built from the `default` image. +- `/8-base` +- `/9-base` +- `/8-init` +- `/9-init` +- `/8-micro` +- `/9-micro` +- `/8-minimal` +- `/9-minimal` + +They are the *Client Library*. + +### Tags + +The following tags are created under each *repository* (AlmaLinux 9.3 example as of 24 Nov 2023): + +| tag | example | +| ---------------------- | ------------- | +| latest | latest | +| MAJOR | 9 | +| MAJOR.MINOR | 9.3 | +| MAJOR.MINOR-DATE_STAMP | 9.3-20231124 | + +The `/almalinux` *repository* includes the `latest` tag for AlmaLinux release 9.x only. + +## *container-images* repository structure + +### Directories structure + +1. Branch 'main' +```sh +. +├── .github +│   └── workflows +│   ├── build-test-push.yml +│   └── publish-docker-library.yml +├── Containerfiles +│   ├── 8 +│   │   ├── Containerfile.base +│   │   ├── Containerfile.default +│   │   ├── Containerfile.init +│   │   ├── Containerfile.micro +│   │   └── Containerfile.minimal +│   └── 9 +│   ├── Containerfile.base +│   ├── Containerfile.default +│   ├── Containerfile.init +│   ├── Containerfile.micro +│   └── Containerfile.minimal +├── LICENSE +└── README.md +``` + +2. Branch 'docker-library' +```sh +. +├── Containerfiles +│   ├── 8 +│   │   ├── Containerfile.default +│   │   └── Containerfile.minimal +│   └── 9 +│   ├── Containerfile.default +│   └── Containerfile.minimal +└── docker-library-definition.tmpl +``` + +### Workflow **.yml* files + +The [`.github/workflows/build-test-push.yml`](https://github.com/AlmaLinux/container-images/blob/main/.github/workflows/build-test-push.yml) workflow is used to **Build, Test and Push** images to the *Client Library*: +```yaml +name: Build, test and push to the Client Library + +on: + workflow_dispatch: + inputs: + production: + description: | + 'Push to production registries' + 'not checked - to testing' + required: true + type: boolean + default: true +... +``` + +The +[`.github/workflows/publish-docker-library.yml`](https://github.com/AlmaLinux/container-images/blob/main/.github/workflows/publish-docker-library.yml) workflow is used to **Publish Images** to the Docker *Official Library*: +```yaml +name: Publish images to the Docker Library + +on: + workflow_dispatch: + inputs: + pr: + description: 'Publish to Docker Official Library' + required: true + type: boolean + default: true +... +``` + +Both workflows are triggered manually by the [**workflow_dispatch**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch) event of GitHub Actions. + +### Sourced *Containerfiles* + +This [`Containerfiles/9/Containerfile.minimal`](https://github.com/AlmaLinux/container-images/blob/main/Containerfiles/9/Containerfile.minimal) file is a Containerfile example for AlmaLinux release 9 and `minimal` type used to build container image for the *Client Library*: +```Dockerfile +ARG SYSBASE=almalinux:9 +FROM ${SYSBASE} as system-build + +RUN mkdir /mnt/sys-root; \ + dnf install -y \ + --installroot /mnt/sys-root \ + --releasever 9 \ + --setopt install_weak_deps=false \ + --nodocs \ + almalinux-release \ + bash \ + +... + +FROM scratch +COPY --from=system-build /mnt/sys-root/ / + +CMD ["/bin/bash"] +``` + +This [`Containerfiles/9/Containerfile.minimal`](https://github.com/AlmaLinux/container-images/blob/docker-library/Containerfiles/9/Containerfile.minimal) file is a Containerfile example for AlmaLinux release 9 and `minimal` type used to build container image for the Docker *Official Library*: +```Dockerfile +# Tags: minimal, 9-minimal, 9.3-minimal, 9.3-minimal-20231124 +FROM quay.io/almalinuxorg/9-minimal:9.3-20231124 + +CMD ["/bin/bash"] +``` + +### Template file for Docker *Library Definition* + +The Docker *Official Library* uses [Definition File](https://github.com/docker-library/official-images/blob/master/library/almalinux) to request building of official images. Changing the file triggers a new image(s) building on the Docker side. The [`docker-library-definition.tmpl`](https://github.com/yuravk/container-images/blob/docker-library/docker-library-definition.tmpl) template is used to generate the Definition file: +```yaml +Tags: {{ .tags }} +GitFetch: refs/heads/docker-library +GitCommit: {{ .commit_hash }} +File: Containerfiles/{{ .version_major }}/Containerfile.{{ .image_type }} +Architectures: amd64, arm64v8, ppc64le, s390x +``` + +# How to contribute/help and customize workflow(s) + +## Fork GitHub repositories + +Fork the following repositories: +- [**container-images**](https://github.com/AlmaLinux/container-images), you will need both the `main` and the `container-library` branches. +- [**docker-library**](https://github.com/docker-library/official-images) + +Read more about GitHub [forks here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo). + +❗ Please, note, that you won't be able to create a Pull Request to this repository as only AlmaLinux organization members have access to do it. + +## Set Action's secrets + +To set secrets needed for this repository, go to your GitHub account **Settings** -> expand **Secrets and variables** (located under the **Security** section) -> select **Actions**. Read more about [Github Secrets in Actions](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions). + +The following *Repository secrets* are required. Set them with your personal data and ***only for registries you are using***. + +For production *Client Library* please define secrets: +| Secret name | Description | +| ---------------------- | -------------------- | +| `DOCKERHUB_USERNAME` | docker.io user | +| `DOCKERHUB_TOKEN` | docker.io token | +| `QUAY_IO_USERNAME` | quay.io user | +| `QUAY_IO_CLI_PASSWORD` | quay.io CLI password | +| `GIT_HUB_USERNAME` | GitHub user | +| `GIT_HUB_TOKEN` | GitHub token | + +The same secrets with `TEST_` prefix in secret names (like `TEST_DOCKERHUB_USERNAME`) should be set for corresponded registries if testing *Client Library* (testing mode). + +On how to create tokens/CLI passwords please read: +- Manage **Quay.io** [Access Tokens](https://docs.quay.io/glossary/access-token.html) +- [Create and manage access tokens](https://docs.docker.com/security/for-developers/access-tokens/) on **Docker** +- [Managing your personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) on **GitHub**. + +When creating a new personal access token on **GitHub**, please, select: +- *write:packages* scope, to allow packages uploading to GitHub Package Registry; +- *admin:org* scope, to allow Pull Request creation to [docker-library](https://github.com/docker-library/official-images). + +## Change registries list + +On needed registries create your own accounts in case you don't have any as you won't be able to use AlmaLinux accounts. + +According to your list of needed registries and knowing your user names edit the [`.github/workflows/build-test-push.yml`](https://github.com/AlmaLinux/container-images/blob/main/.github/workflows/build-test-push.yml) workflow file (branch `master`): +```yaml +registries: 'docker.io/, quay.io/, ghcr.io/' +``` +Separate the registries with commas. + +`` - is your user name on the specific registry. + +## Change platforms list + +If you don't need to build images for all platforms, you can edit the list of platforms to meet your needs in the [`.github/workflows/build-test-push.yml`](https://github.com/AlmaLinux/container-images/blob/main/.github/workflows/build-test-push.yml) workflow file (branch `master`): + +```yaml +platforms: 'linux/amd64, linux/ppc64le, linux/s390x, linux/arm64' +``` +Separate the platforms with commas. + +## Change image types list + +Edit the [`.github/workflows/build-test-push.yml`](https://github.com/AlmaLinux/container-images/blob/main/.github/workflows/build-test-push.yml) workflow file (branch `master`) to change type of images which are built: + +- Add/modify/delete input for specific type name of image: +```yaml + type_: + description: '' + required: true + type: boolean +``` + +- Add/modify/delete the image type in the matrix for the `build` job: +```yaml +image_types: ${{ fromJSON(format('["{0}"]', ( inputs.type_ && '' ) )) }} +``` +Where `` is the name of your image type. + +Default are: *base*, *default*, *init*, *micro*, *minimal* + +## To bump AlmaLinux release (*Major* number) + +If a new AlmaLinux major release is available, edit the [`.github/workflows/build-test-push.yml`](https://github.com/AlmaLinux/container-images/blob/main/.github/workflows/build-test-push.yml) workflow file (branch `master`), to set this major version: + +- `inputs.version_major` like: +```yaml + version_major: + description: 'AlmaLinux major version' + required: true + default: '' + type: choice + options: + - + - 9 + - 8 +``` + - `env.version_latest` like: +```yaml +version_latest: +``` +Where `` is an AlmaLinux version major version, for example `10`. + +## To bump AlmaLinux release (*Minor* number) + +If a new AlmaLinux minor release is available, edit the [`.github/workflows/build-test-push.yml`](https://github.com/AlmaLinux/container-images/blob/main/.github/workflows/build-test-push.yml) workflow file (branch `master`) to set it. To do so, you need the "DeployPrepare AlmaLinux Minor version number" step: + +```sh + case ${{ inputs.version_major }} in + 8) + version_minor="<8_minor>" ;; + 9) + version_minor="<9_minor>" ;; + 10) + version_minor="<10_minor>" ;; + +``` + +Where `<8_minor>`, `<9_minor>`, `<10_minor>` are AlmaLinux's corresponding minor versions. + +For example Minors are `10`, `4` or `1` for new **8.10**, **9.4** or **10.1** versions respectively. + +## Restrictions + +❗ Only AlmaLinux organization members have access to create Pull Requests and publish container images into the Docker *Official Library*. + +❗ **Build, test and push to the Client Library** workflow will work only for your *Client Library*, but not for AlmaLinux-owned ones. + +# Workflows jobs and steps + +## Build, test and push to the Client Library + +Tree illustration of the workflow Jobs and Steps for AlmaLinux 9 minimal image: +``` + Build, test and push to the Client Library + │ + ├── Deploy 9 minimal images + │   ├── Set up job + │   ├── DeployPrepare AlmaLinux Minor version number + │   ├── Prepare date stamp + │   ├── Generate list of Docker images to use as base name for tags + │   ├── Enable containerd image store on Docker Engine + │   ├── Checkout _container-images, branch 'main' + │   ├── Checkout _container-images, branch 'docker-library', path 'docker-library' + │   ├── Set up QEMU + │   ├── Set up Docker Buildx + │   ├── Login to Docker.io + │   ├── Login to Quay.io + │   ├── Login to Ghcr.io + │   ├── Generate tags and prepare metadata to build and push + │   ├── Build images + │   ├── Test images + │   ├── Push images to Client Library + │   ├── Change date stamp in Containerfile (default and minimal only) + │   ├── Upload changed Containerfile (default and minimal only) + │   ├── Post Push images to Client Library + │   ├── Post Build images + │   ├── Post Login to Ghcr.io + │   ├── Post Set up Docker Buildx + │   ├── Post Checkout _container-images, branch 'docker-library', path 'docker-library' + │   ├── Post Checkout _container-images, branch 'main' + │   └── Complete job + │ + └── Collect and save changed Containerfile(s) used by Docker Official Library + ├── Set up job + ├── Checkout container-images, branch 'docker-library' + ├── Download changed Containerfiles + ├── [Debug] Print Containerfiles/9/Containerfile. + ├── Commit and push Containerfiles/9/Containerfile.minimal changes + ├── Post Checkout container-images, branch 'docker-library' + └── Complete job +``` + +### Inputs + +The workflow inputs are: +- `production` - boolean '*Push to production registries*' with the default value `true` (checked). Container images are pushed into the production *Client Library*: [Docker.io/almalinux](https://hub.docker.com/u/almalinux), [Quay.io/almalinuxorg](https://quay.io/organization/almalinuxorg) and [Ghcr.io/AlmaLinux](https://github.com/orgs/AlmaLinux/packages). Otherwise, images are pushed into the testing *Client Library*: [Quay.io/almalinuxautobot](https://quay.io/organization/almalinuxautobot) + +- `version_major` - dropdown 'AlmaLinux major version' with the default value `9`. This is a major number of AlmaLinux version to build images for. + +- Checklist of image types: *base*, *default*, *init*, *micro*, *minimal*. At least one should be checked. + +### Job: Deploy *version_major* *image_types* images + +Job proceeds to input `version_major` and iterates with selected `image_types` using matrix. Multiple jobs run simultaneously for each image type. + +#### Step: DeployPrepare AlmaLinux Minor version number + +The step sets AlmaLinux `version_minor` according to set on inputs `version_major`. + +#### Step: Prepare date stamp + +Generates `date_stamp` in format *YYYYMMDD*. It is used in image tags. + +#### Step: Generate list of Docker images to use as base name for tags + +Generates `env.IMAGE_NAMES` for each registry including image type like: `docker.io/***/8-minimal quay.io/***/8-minimal` + +#### Step: Enable containerd image store on Docker Engine + +Modifies the /etc/docker/daemon.json as: +```json +"features": +{ + "containerd-snapshotter": true +} +``` +Restarts the `docker` service to get a new image store working. +The successful switch is printed in the docker info: +```json +[[driver-type io.containerd.snapshotter.v1]] +``` + +#### Step: Checkout *container-images*, branch 'main' + +Checkouts *container-images* into branch 'main'. The repository directory is located at `/home/runner/work/container-images/container-images`. Please note, the only last commit is checked out. +The [actions/checkout@v4](https://github.com/actions/checkout/) is used. + +#### Step: Checkout *container-images*, branch 'docker-library', path 'docker-library' + +Checkouts *container-images* into branch 'docker-library'. The repository directory is located at `/home/runner/work/container-images/docker-library`. +The [actions/checkout@v4](https://github.com/actions/checkout/) is used. + +#### Step: Set up QEMU + +Installs [QEMU](https://github.com/qemu/qemu) static binaries. The [docker/setup-qemu-action@v3](https://github.com/docker/setup-qemu-action) is used. The QEMU static binaries are required to build different platforms within one machine. + +#### Step: Set up Docker Buildx + +Sets up Docker [Buildx](https://github.com/docker/buildx). It uses [docker/setup-buildx-action@v3](https://github.com/docker/setup-buildx-action) + +#### Step: Login to Docker.io + +The [docker/login-action@v3](https://github.com/docker/login-action) is used. The following secrets are used: + +*production* mode: +- DOCKERHUB_USERNAME +- DOCKERHUB_TOKEN + +*testing* mode: +- TEST_DOCKERHUB_USERNAME +- TEST_DOCKERHUB_TOKEN + +#### Step: Login to Quay.io + +The [docker/login-action@v3](https://github.com/docker/login-action) is used. The following secrets are used: + +*production* mode: +- QUAY_IO_USERNAME +- QUAY_IO_CLI_PASSWORD + +*testing* mode: +- TEST_QUAY_IO_USERNAME +- TEST_QUAY_IO_CLI_PASSWORD + +#### Step: Login to Ghcr.io + +The [docker/login-action@v3](https://github.com/docker/login-action) is used. The following secrets are used: + +*production* mode: +- GIT_HUB_USERNAME +- GIT_HUB_TOKEN + +*testing* mode: +- TEST_GIT_HUB_USERNAME +- TEST_GIT_HUB_TOKEN + +#### Step: Generate tags and prepare metadata to build and push + +The [docker/metadata-action@v5](https://github.com/docker/metadata-action) is used to generate tags, labels and annotations for images. Here is an example of AlmaLinux 8 minimal image's tags: +```json +"tags": [ + "docker.io/***/8-minimal:latest", + "docker.io/***/8-minimal:8", + "docker.io/***/8-minimal:8.9", + "docker.io/***/8-minimal:8.9-20240319", + "quay.io/***/8-minimal:latest", + "quay.io/***/8-minimal:8", + "quay.io/***/8-minimal:8.9", + "quay.io/***/8-minimal:8.9-20240319", + ], +``` +#### Step: Build images + +The [docker/build-push-action@v5](https://github.com/docker/build-push-action) is used to build images. This step builds the images from corresponding [`Containerfile`](https://github.com/AlmaLinux/container-images/tree/main/Containerfiles), for specified `env.platforms` and uses tags from the previous step. After the successful building, the images are loaded into docker, but not pushed yet as they need to be tested first. AlmaLinux 8 minimal images `buildx` looks like this: +```sh +/usr/bin/docker buildx build --file ./Containerfile.minimal ... \ + --platform linux/amd64,linux/ppc64le,linux/s390x,linux/arm64 \ + --provenance false ... \ + --tag docker.io/***/8-minimal:latest --tag docker.io/***/8-minimal:8 --tag docker.io/***/8-minimal:8.9 --tag docker.io/***/8-minimal:8.9-20240319 --tag quay.io/***/8-minimal:latest --tag quay.io/***/8-minimal:8 --tag quay.io/***/8-minimal:8.9 --tag quay.io/***/8-minimal:8.9-20240319 \ + --load \ + --metadata-file /home/runner/work/_temp/docker-actions-toolkit-*/metadata-file \ + https://github.com/***/container-images.git#270a6d3fd433cfa6c3e1fff5896a92d1ae2896be:Containerfiles/8 +``` +`provenance: false` is to disable the [Provenance attestations](https://docs.docker.com/build/attestations/slsa-provenance/) as Quay.io registry doesn't support such kind of images data. + +#### Step: Test images + +Every image can be tested separately for each type and platform as each image is loaded into docker. Docker run images "by digest": +```sh +docker run --platform=${platform} ${{ steps.build-images.outputs.digest }} +``` + +#### Step: Push images to Client Library + +The [docker/build-push-action@v5](https://github.com/docker/build-push-action) is used. This step pushes built images into *Client Library*. The options are the same as for **Build images** step. + + +#### Step: Change date stamp in Containerfile (default and minimal only) + +❗ Skip this step if the image type is not 'default' or 'minimal'. + +The step changes (*# Tags* with date stamp) corresponded [`Containerfiles/*/Containerfile.*`](https://github.com/AlmaLinux/container-images/tree/docker-library), which Docker will use to build images for the *Official Library*. An example is for AlmaLinux 8 minimal `Containerfiles/8/Containerfile.minimal` file: +```docker +# Tags: 8-minimal, 8.9-minimal, 8.9-minimal-20240319 + +FROM quay.io/almalinuxorg/8-minimal:8.9-20240319 +``` +The change indicates that a new `default` and/or `minimal` container image was pushed to the *Client Library* and should be requested to be built by Docker. The change will later be committed to the `docker-library` branch. + +#### Step: Upload changed *Containerfiles/*/Containerfile.** + +❗ Skip this step if the image type is not 'default' or 'minimal'. + +The step uses [actions/upload-artifact@v4](https://github.com/actions/upload-artifact) to store the artifact changed in the previous Containerfile step. The artifact is named against `image_type`, like `containerfiles-${image_type}`. + +Artifacts are used to transfer files between different jobs of the same workflow. The artifact is a zip archive of the file without file-path included. + +It is also possible to download artifacts via GitHub Action's web interface. + +### Job: Collect and save changed Containerfile(s) used by Docker Official Library + +❗ Skip this step if the image type is not 'default' or 'minimal'. + +#### Step: Checkout *container-images*, branch 'docker-library' + +Checkouts *container-images* into branch 'docker-library'. The repository directory is located at `/home/runner/work/container-images/container-images`. +The [actions/checkout@v4](https://github.com/actions/checkout/) is used. + +#### Step: Download changed Containerfiles + +Uses [actions/download-artifact@v4](https://github.com/actions/download-artifact) to download multiple (`merge-multiple: true`) artifacts with changed Containerfiles. The files are saved into the `Containerfiles/version_major/` directory. + +#### Step: Commit and push *Containerfiles/version_major/Containerfile.** changes + +> The step is skipped if '*Push to production registries*' is not checked (`inputs.production` set to `false`.) + +Uses [EndBug/add-and-commit@v9](https://github.com/marketplace/actions/add-commit) to commit and push Containerfiles, which was downloaded on the previous step, and changed by the previous job. + +The commit message is: +```yaml +AlmaLinux ${{ inputs.version_major }} image build as of ${{ needs.build.outputs.date_stamp }} (with ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}). +``` +It includes the AlmaLinux version major, image build date, and reference to this GitHub Action. + +## Publish images to the Docker Library + +Tree illustration of the workflow Jobs and Steps for AlmaLinux 9 minimal image: +``` +Publish images to the Docker Library +│ +├── 8 default definition preparing +. +. +. +├── 8 minimal definition preparing +. +. +. +├── 9 default definition preparing +. +. +. +├── 9 minimal definition preparing +│   ├── Set up job +│   ├── Checkout container-images, branch 'docker-library' +│   ├── Checkout official-images, branch 'master' +│   ├── Get need data for the definition +│   ├── Render the definition +│   ├── Upload the definition for 9 minimal +│   ├── Post Checkout official-images, branch 'master' +│   ├── Post Checkout container-images, branch 'docker-library' +│   └── Complete job +│ +└── Create Pull Request with the new definition file + ├── Set up job + ├── Checkout official-images, branch 'master' + ├── Sync official-images with docker-library/official-images + ├── Download all definitions + ├── Create head of official-images/library/almalinux + ├── Merge definitions into official-images/library/almalinux + ├── Prepare date stamp + ├── Prepare time stamp + ├── Commit and push official-images/library/almalinux + ├── Create Pull Request for official-images/library/almalinux + ├── Post Checkout official-images, branch 'master' + └── Complete job +``` + +### Inputs + +The workflow inputs are: +- `pr` - boolean '*Publish to the Docker Official Library*' with the default value `true` (checked). The input indicates whether to create a Pull Request to Docker with AlmaLinux *Definition File*. + +- `draft` - boolean '*Draft Pull Request*' with the default value `false` (not checked). The input indicates whether the [Pull Request is draft](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests) or it is ready to review. + +### Job: *version_major* *image_types* definition preparing + +Job iterates (using matrix) with AlmaLinux all `version_major`, and `image_types` (`default` and `minimal`). Multiple jobs run simultaneously for each of the versions and each of the image types. + +#### Step: Checkout *container-images*, branch 'docker-library' + +The [actions/checkout@v4](https://github.com/actions/checkout/) checkouts *container-images* into branch 'docker-library'. The repository directory is located at `/home/runner/work/container-images/container-images`. All commits for the branch are checkout with `fetch-depth: 0`. + +#### Step: Checkout *official-images*, branch 'master' + +The [actions/checkout@v4](https://github.com/actions/checkout/) checkouts *container-images* into branch 'master'. The repository directory is located at `/home/runner/work/container-images/official-images`. + +That's your fork of [docker-library/official-images](https://github.com/docker-library/official-images) repository. + +#### Step: Get need data for the definition + +The step is written in bash. It reads the *# Tags:* string and the commit hash of `Containerfiles/${{ matrix.version_major }}/Containerfile.image_types` file changed by the **Build, test and push** workflow. `env.tags` and `env.last_commit` are exported. These data will be used to generate part of *Definition File*. + +#### Step: Render the definition + +The [chuhlomin/render-template@v1](https://github.com/marketplace/actions/render-template) generates from the `docker-library-definition.tmpl` using data (`env.tags`, `env.last_commit`, `matrix.version_major` and `matrix.image_types`) file `official-images/library/almalinux.version_major.image_types`. The file is a part of Docker Library *Definition File*. + +#### Step: Upload the definition for *version_major* *image_types* + +The step uses [actions/upload-artifact@v4](https://github.com/actions/upload-artifact) to store an artifact generated in the previous step `official-images/library/almalinux.version_major.image_types`. The artifact is named against `version_major` and `image_type`, following the pattern: `definition-${version_major}.${image_types}`. + +Artifacts are used to transfer files between different jobs of the same workflow. The artifact is a zip archive of the file without file-path included. + +It is also possible to download artifacts via GitHub Action's web interface. + +### Job: Create Pull Request with the new definition file + +> The job is skipped if the *'Publish to Docker Official Library'* isn't checked (`inputs.pr` set into `false`) + +#### Step: Checkout *official-images*, branch 'master' + +The [actions/checkout@v4](https://github.com/actions/checkout/) checkouts *container-images* into branch 'master'. The repository directory is located at `/home/runner/work/container-images/official-images`. + +That's your fork of [docker-library/official-images](https://github.com/docker-library/official-images) repository. + +#### Step: Sync *official-images* with upstream + +The step is written in bash. It adds the [official-images upstream](https://github.com/docker-library/official-images) repository, sets a local 'master' branch to track the corresponding one from the upstream, and tries to rebase with the 'upstream/master'. + +#### Step: Download all definitions + +Uses [actions/download-artifact@v4](https://github.com/actions/download-artifact) to download multiple (`merge-multiple: true`) artifacts with generated definitions. The files are saved into the `official-images/library/` directory. + +#### Step: Create head of *official-images/library/almalinux* + +Creates heading for the Docker *Definition File*. + +#### Step: Merge definitions into *official-images/library/almalinux* + +The step is written in bash. It appends the `official-images/library/almalinux` *Definition File* with downloaded on the previous step definitions `official-images/library/almalinux.version_major.image_types`. + +#### Step: Prepare date stamp + +Generates `date_stamp` in the *YYYYMMDD* format. It is used in the commit message and pull request title. + +#### Step: Prepare time stamp + +Generates `time_stamp` in the *HH:MM:SS* format. It is used in the commit message and pull request title. + +#### Step: Commit and push *official-images/library/almalinux* + +Uses [EndBug/add-and-commit@v9](https://github.com/marketplace/actions/add-commit) to commit and push the generated *Definition File*. + +The commit message is: +```yaml +Almalinux auto-update - ${{ env.date_stamp }}. +``` + +#### Step: Create Pull Request for *official-images/library/almalinux* + +The step is written in bash. It uses Github CLI to create a Pull Request for the `official-images/library/almalinux` *Definition File* from your fork and to [docker-library/official-images](https://github.com/docker-library/official-images) repository. + +The Pull Request will be drafted if the `draft` input is checked. When ready, [mark the request as ready for review](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request#marking-a-pull-request-as-ready-for-review). \ No newline at end of file