├── .github └── workflows │ └── actions.yml ├── .gitignore ├── LICENSE ├── README.md └── update.sh /.github/workflows/actions.yml: -------------------------------------------------------------------------------- 1 | name: actions 2 | on: 3 | push: 4 | schedule: 5 | - cron: '0 0 * * 0' 6 | jobs: 7 | ubuntu-core: 8 | runs-on: ubuntu-latest 9 | strategy: 10 | matrix: 11 | QEMU_VER: [v6.1.0-5] 12 | DOCKER_REPO: [docker.io/multiarch/ubuntu-core] 13 | VERSION: [trusty, xenial, bionic, focal, hirsute] 14 | UNAME_ARCH: [x86_64, arm64, armhf, i386, ppc64el, s390x] 15 | include: 16 | - {ARCH: amd64, QEMU_ARCH: x86_64, UNAME_ARCH: x86_64} 17 | - {ARCH: arm64, QEMU_ARCH: aarch64, UNAME_ARCH: arm64} 18 | - {ARCH: armhf, QEMU_ARCH: arm, UNAME_ARCH: armhf} 19 | - {ARCH: i386, QEMU_ARCH: i386, UNAME_ARCH: i386} 20 | - {ARCH: ppc64el, QEMU_ARCH: ppc64, UNAME_ARCH: ppc64el} 21 | - {ARCH: s390x, QEMU_ARCH: s390x, UNAME_ARCH: s390x} 22 | exclude: 23 | - {VERSION: trusty, UNAME_ARCH: s390x} 24 | - {VERSION: xenial, UNAME_ARCH: s390x} 25 | - {VERSION: focal, UNAME_ARCH: i386} 26 | - {VERSION: hirsute, UNAME_ARCH: i386} 27 | steps: 28 | - uses: actions/checkout@v2 29 | - name: Build 30 | run: | 31 | sudo add-apt-repository 'deb http://archive.ubuntu.com/ubuntu focal main universe' 32 | sudo apt-get update && sudo apt-get install -y qemu-user-static 33 | sudo ./update.sh -a ${{ matrix.ARCH }} -v ${{ matrix.VERSION }} -q ${{ matrix.QEMU_ARCH }} -u ${{ matrix.QEMU_VER }} -d ${{ matrix.DOCKER_REPO }} -t ${{ matrix.UNAME_ARCH }} 34 | - name: Publish 35 | if: github.ref == 'refs/heads/master' 36 | run: | 37 | docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_TOKEN }} 38 | docker push -a ${{ matrix.DOCKER_REPO }} 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | */*.tar.gz 2 | */*.manifest 3 | */build-info.txt 4 | */Dockerfile 5 | */MD5SUMS* 6 | */SHA1SUMS* 7 | */SHA256SUMS* 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Multiarch 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :earth_africa: ubuntu-core [![actions](https://github.com/multiarch/ubuntu-core/actions/workflows/actions.yml/badge.svg)](https://github.com/multiarch/ubuntu-core/actions/workflows/actions.yml) 2 | 3 | ![](https://raw.githubusercontent.com/multiarch/dockerfile/master/logo.jpg) 4 | 5 | Multiarch Ubuntu images for Docker. 6 | 7 | Based on https://github.com/tianon/docker-brew-ubuntu-core/ 8 | 9 | * `multiarch/ubuntu-core` on [Docker Hub](https://hub.docker.com/r/multiarch/ubuntu-core/) 10 | * [Available tags](https://hub.docker.com/r/multiarch/ubuntu-core/tags/) 11 | 12 | ## Usage 13 | 14 | Once you need to configure binfmt-support on your Docker host. 15 | This works locally or remotely (i.e using boot2docker or swarm). 16 | 17 | ```console 18 | # configure binfmt-support on the Docker host (works locally or remotely, i.e: using boot2docker) 19 | $ docker run --rm --privileged multiarch/qemu-user-static:register --reset 20 | ``` 21 | 22 | Then you can run an `armhf` image from your `x86_64` Docker host. 23 | 24 | ```console 25 | $ docker run -it --rm multiarch/ubuntu-core:armhf-wily 26 | root@a0818570f614:/# uname -a 27 | Linux a0818570f614 4.1.13-boot2docker #1 SMP Fri Nov 20 19:05:50 UTC 2015 armv7l armv7l armv7l GNU/Linux 28 | root@a0818570f614:/# exit 29 | ``` 30 | 31 | Or an `x86_64` image from your `x86_64` Docker host, directly, without qemu emulation. 32 | 33 | ```console 34 | $ docker run -it --rm multiarch/ubuntu-core:amd64-wily 35 | root@27fe384370c9:/# uname -a 36 | Linux 27fe384370c9 4.1.13-boot2docker #1 SMP Fri Nov 20 19:05:50 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux 37 | root@27fe384370c9:/# 38 | ``` 39 | 40 | It also works for `arm64` 41 | 42 | ```console 43 | $ docker run -it --rm multiarch/ubuntu-core:arm64-wily 44 | root@723fb9f184fa:/# uname -a 45 | Linux 723fb9f184fa 4.1.13-boot2docker #1 SMP Fri Nov 20 19:05:50 UTC 2015 aarch64 aarch64 aarch64 GNU/Linux 46 | ``` 47 | 48 | ## License 49 | 50 | MIT 51 | -------------------------------------------------------------------------------- /update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # A POSIX variable 4 | OPTIND=1 # Reset in case getopts has been used previously in the shell. 5 | 6 | while getopts "a:v:q:u:d:t:" opt; do 7 | case "$opt" in 8 | a) ARCH=$OPTARG 9 | ;; 10 | v) VERSION=$OPTARG 11 | ;; 12 | q) QEMU_ARCH=$OPTARG 13 | ;; 14 | u) QEMU_VER=$OPTARG 15 | ;; 16 | d) DOCKER_REPO=$OPTARG 17 | ;; 18 | t) TAG_ARCH=$OPTARG 19 | ;; 20 | esac 21 | done 22 | 23 | thisTarBase="ubuntu-$VERSION-core-cloudimg-$ARCH" 24 | thisTar="$thisTarBase-root.tar.gz" 25 | baseUrl="https://partner-images.canonical.com/core/$VERSION" 26 | 27 | 28 | # install qemu-user-static 29 | if [ -n "${QEMU_ARCH}" ]; then 30 | if [ ! -f x86_64_qemu-${QEMU_ARCH}-static.tar.gz ]; then 31 | wget -N https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_VER}/x86_64_qemu-${QEMU_ARCH}-static.tar.gz 32 | fi 33 | tar -xvf x86_64_qemu-${QEMU_ARCH}-static.tar.gz -C $ROOTFS/usr/bin/ 34 | fi 35 | 36 | 37 | # get the image 38 | if \ 39 | wget -q --spider "$baseUrl/current" \ 40 | && wget -q --spider "$baseUrl/current/$thisTar" \ 41 | ; then 42 | baseUrl+='/current' 43 | fi 44 | wget -qN "$baseUrl/"{{MD5,SHA{1,256}}SUMS{,.gpg},"$thisTarBase.manifest",'unpacked/build-info.txt'} || true 45 | wget -N "$baseUrl/$thisTar" 46 | 47 | # check checksum 48 | if [ -f SHA256SUMS ]; then 49 | sha256sum="$(sha256sum "$thisTar" | cut -d' ' -f1)" 50 | if ! grep -q "$sha256sum" SHA256SUMS; then 51 | echo >&2 "error: '$thisTar' has invalid SHA256" 52 | exit 1 53 | fi 54 | fi 55 | 56 | cat > Dockerfile <<-EOF 57 | FROM scratch 58 | ADD $thisTar / 59 | ENV ARCH=${ARCH} UBUNTU_SUITE=${VERSION} DOCKER_REPO=${DOCKER_REPO} 60 | EOF 61 | 62 | # add qemu-user-static binary 63 | if [ -n "${QEMU_ARCH}" ]; then 64 | cat >> Dockerfile <> Dockerfile <<-EOF 72 | # a few minor docker-specific tweaks 73 | # see https://github.com/docker/docker/blob/master/contrib/mkimage/debootstrap 74 | RUN echo '#!/bin/sh' > /usr/sbin/policy-rc.d \\ 75 | && echo 'exit 101' >> /usr/sbin/policy-rc.d \\ 76 | && chmod +x /usr/sbin/policy-rc.d \\ 77 | && dpkg-divert --local --rename --add /sbin/initctl \\ 78 | && cp -a /usr/sbin/policy-rc.d /sbin/initctl \\ 79 | && sed -i 's/^exit.*/exit 0/' /sbin/initctl \\ 80 | && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \\ 81 | && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \\ 82 | && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \\ 83 | && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \\ 84 | && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \\ 85 | && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes 86 | 87 | # enable the universe 88 | RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list 89 | 90 | # overwrite this with 'CMD []' in a dependent Dockerfile 91 | CMD ["/bin/bash"] 92 | EOF 93 | 94 | docker build -t "${DOCKER_REPO}:${TAG_ARCH}-${VERSION}" . 95 | docker run --rm "${DOCKER_REPO}:${TAG_ARCH}-${VERSION}" /bin/bash -ec "echo Hello from Ubuntu!" 96 | --------------------------------------------------------------------------------