├── noextract-python.conf
├── noextract.conf
├── setup.sh
├── COPYING
├── docker-bake.hcl
├── keys
├── 3d:b9:c0:50:41:a7:68:4c:2e:2c:a9:a2:5a:04:b7:3f.plist
└── 60:ae:0c:d6:f0:95:17:80:bc:93:46:7a:89:af:a3:2d.plist
├── README.md
├── Containerfile
└── .github
└── workflows
└── build.yaml
/noextract-python.conf:
--------------------------------------------------------------------------------
1 | noextract=/usr/lib/python*/EXTERNALLY-MANAGED
2 |
--------------------------------------------------------------------------------
/noextract.conf:
--------------------------------------------------------------------------------
1 | noextract=/usr/share/man*
2 | noextract=/usr/lib/dracut*
3 | noextract=/etc/hosts
4 | noextract=/etc/mtab
5 | noextract=/etc/skel*
6 | noextract=/usr/lib/modprobe.d*
7 | noextract=/usr/lib/sysctl.d*
8 | noextract=/usr/lib/udev*
9 | noextract=/usr/share/bash-completion*
10 | noextract=/usr/share/fish/vendor_completions.d*
11 | noextract=/usr/share/zsh/site-functions*
12 | noextract=/usr/share/info*
13 | noextract=/usr/lib/gconv*
14 |
--------------------------------------------------------------------------------
/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | : "${MIRROR:=https://repo-ci.voidlinux.org/}"
4 |
5 | suffix() {
6 | case "${LIBC:?}" in
7 | musl) echo "-musl" ;;
8 | esac
9 | }
10 |
11 | repo() {
12 | case "${ARCH:?}" in
13 | aarch64*) echo "${MIRROR}/current/aarch64" ;;
14 | *-musl) echo "${MIRROR}/current/musl" ;;
15 | *) echo "${MIRROR}/current" ;;
16 | esac
17 | }
18 |
19 | case "${TARGETPLATFORM:?}" in
20 | linux/arm/v6) ARCH="armv6l$(suffix)" ;;
21 | linux/arm/v7) ARCH="armv7l$(suffix)" ;;
22 | linux/arm64) ARCH="aarch64$(suffix)" ;;
23 | linux/amd64) ARCH="x86_64$(suffix)" ;;
24 | linux/386) ARCH="i686$(suffix)" ;;
25 | esac
26 |
27 | REPO="$(repo)"
28 |
29 | export ARCH REPO
30 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008-2020 Juan Romero Pardines and contributors
2 | Copyright (c) 2017-2023 The Void Linux team and contributors
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions
7 | are met:
8 | 1. Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
--------------------------------------------------------------------------------
/docker-bake.hcl:
--------------------------------------------------------------------------------
1 | variable "MIRROR" {
2 | default = "https://repo-ci.voidlinux.org/"
3 | }
4 |
5 | target "docker-metadata-action" {}
6 |
7 | target "_common" {
8 | inherits = ["docker-metadata-action"]
9 | dockerfile = "Containerfile"
10 | no-cache-filter = ["bootstrap"]
11 | cache-to = ["type=local,dest=/tmp/buildx-cache"]
12 | cache-from = ["type=local,src=/tmp/buildx-cache"]
13 | args = {
14 | "MIRROR" = "${MIRROR}"
15 | }
16 | }
17 |
18 | target "_common-glibc" {
19 | inherits = ["_common"]
20 | platforms = ["linux/amd64", "linux/386", "linux/arm64", "linux/arm/v7", "linux/arm/v6"]
21 | args = { "LIBC" = "glibc" }
22 | }
23 |
24 | target "_common-musl" {
25 | inherits = ["_common"]
26 | platforms = ["linux/amd64", "linux/arm64", "linux/arm/v7", "linux/arm/v6"]
27 | args = { "LIBC" = "musl" }
28 | }
29 |
30 | target "void-glibc" {
31 | inherits = ["_common-glibc"]
32 | target = "image-default"
33 | }
34 |
35 | target "void-glibc-busybox" {
36 | inherits = ["_common-glibc"]
37 | target = "image-busybox"
38 | }
39 |
40 | target "void-glibc-full" {
41 | inherits = ["_common-glibc"]
42 | target = "image-full"
43 | }
44 |
45 | target "void-musl" {
46 | inherits = ["_common-musl"]
47 | target = "image-default"
48 | }
49 |
50 | target "void-musl-busybox" {
51 | inherits = ["_common-musl"]
52 | target = "image-busybox"
53 | }
54 |
55 | target "void-musl-full" {
56 | inherits = ["_common-musl"]
57 | target = "image-full"
58 | }
59 |
--------------------------------------------------------------------------------
/keys/3d:b9:c0:50:41:a7:68:4c:2e:2c:a9:a2:5a:04:b7:3f.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | public-key
6 | LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUFvM1Nrc2p5N01PMmc4UWxsZjdCVQp1aXhFUWlqN3FOSVJrU0hrWWw4SGxxd1hOczFnK1FzbzhGV3dSbDNMbUpTVW5wT1BaOG1sdVdSajd4Y2pLbnVJCnhPRjBtQS8vM0lzTnVId2dYV2RLL0JiT29wNzFLZmt4aEE0WjhwK0hRbmhLMThxUkFPbG9xOGJ6WXZhaGI2NmEKemdWVTVFM1JzRDU4V0M2ZTFOUVdSSGpiMG1TM2h6M1NxVWVWZFVMT20zVzZBRTdYdWlVQVJOSEdyY1ljMXkyKwpxNjBKWHMrVk5sRlMwaGdDdnpqS3phMVg5cWtzQndzTmdaRlhBcXN1MGFKRndYSTEvM2R4ZWxBcUZFbnRMWVFSCjA4NHpaTDFmWDVRMWlacGNEaHVhTWZVREVZQjA4UzdKTTBYKytibkxxVnphVTZzc0RXdGtzbFJaNjNaVStISTUKemk5a0pyc25LcU5Pa3BKSnJTUkRyMGFvRjV2RDRwN20vYWdZKzdTRk5aaDZzOUJ5V0x3NDVFdytwalVVUmp5aQp6T01TSFhEM3YzczhFdzZkV29wbTVQTGUvUEgzZWFiMEVnbG9yVDZhYmRwaCtaVG4zaUxMWVVkSGNmQ1FDN01GCkNmVGl1TWt4SkJpaCtoOEhKaUlBdmpDZjVxdjZiaFpEUHpGRzAwbEpYRUZwNHRpbGp6eTFmbitiMkdLY3BDOWQKUUs4TEc3M0RFaXhacHBmU09IU09MMWYxVlBzZTBRdnl6d2RWc0xzR0dqV0FaZkw4WUdVZDl4Y20yeW5tVzFuNgpKTjl6NE9oZ3lRa21mNUFFUXpYSUxQR0d1MlREUVh5c05IRG0vUnRMMHJPN3cxbFVKSTVYOW1kbEZYd0xUWHI3ClYrU25aK3U5VCtFREg1NTV6WDJDZTgwQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=
7 | public-key-size
8 | 4096
9 | signature-by
10 | Void Linux
11 |
12 |
13 |
--------------------------------------------------------------------------------
/keys/60:ae:0c:d6:f0:95:17:80:bc:93:46:7a:89:af:a3:2d.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | public-key
6 | LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF2clN6QlpNdmd2T0NJM0FYYk9qYQoycktSa0pTVE0zYy9FalRJZ0NnRFhndW05M0JQQ3RZOE1jRlZvQ1U0T2lYSEdmVG1xMzlCVk5wTHZMSEw5S2sxCnAyNzhTQmhYVk90YkIyRVZtREtudmZJREVUbGRMR3plN3JaTlJKZHR1TjJtWi9UVnJVQjlTMHlRYytJdWY0aHYKMytEOTdWSWRUSkhBN0FTcjA0MjhwcEVHSkd3U1NoWTJYSm05RDVJMEV1R1JXYzE0TUVHN2RJS0ppWWlNMG5FNAp0WW8yL3ZINElGVEhkblZBM2dZaVp5RG5idUNBUi84RVNmVVRVMTNTTkNPZGJ1ZGYzRDVCY3krVWlNREpJM1llCjRNRktCclQ5WmhaK0dzWEJaWTQ4MmxxaVppNkNMNXB0YzlJUUZmOC9lS1phOGphdGtpVkZWZ3JLZU5Sak9UeE4KZldTdTJua3hHTlgrYmhYWXRoaUdXbUpFWThjQ0FQeUZOK0x2NVJldEsyNTZnZGNiMnNrbUVxZWZ2MnpQQyt3VgpXQmJkSDViRDRiWmpuME42Wmw4MXJ2NVJ6RHZudmYrdkQxNGFGVWJaOFFGcXU3NVBiTDR3Nm1ZTTRsZE0vZzBSCjZOWEU4QXo5Qnd4MnREZlllS3V1dHcxRXBQbTJZdkZ5VFViMWNveUF1VEdSeUFhcDFVVEh2ZzlsaFBJSm1oRlEKSjVrQ2cxcUQ3QTMxV2wwUmxuZTZoZ0dvMFpaTko1Y0pNL3YvelNUS0pjdUZnd283SDBoT0dpbDZEZm84OUI0agpHOTZBQ3lQUytEVktQRlhSWXdqL0FrYkhwYVEyZjFGTUFvU3BCcXVEcUhoM3VrazcxS1g2ajE5dDBpRjhEUUxyCnZ0RlNTZElqREEwMmx3ZVY5TmFRcFdzQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=
7 | public-key-size
8 | 4096
9 | signature-by
10 | Void Linux
11 |
12 |
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Void Linux Container Images
2 |
3 | This repo contains what is needed to build void-linux OCI container
4 | images. There are 3 images provided for each libc (`glibc` or `musl`):
5 |
6 | - `void-LIBC`: This image contains far fewer packages and uses a
7 | `noextract` file to prevent certain directories from being added to
8 | the image. These images average 40-65MB.
9 |
10 | - `void-LIBC-full`: Large image based on the `base-container` package and
11 | does not contain a `noextract` configuration. If you want something
12 | that is as close to a full void VM as possible, this is the image you
13 | want to start with.These images average 80-135MB.
14 |
15 | - `void-LIBC-busybox`: This image is the same as the `void-LIBC` image
16 | above, but uses busybox instead of GNU coreutils. Note that this is
17 | not a well tested configuration with Void, but if you want a very
18 | small image, busybox is a good way to get it. These images average 15-40MB.
19 |
20 | These images are available for the following OCI platforms:
21 |
22 | - `linux/amd64`
23 | - `linux/386` (`glibc` only)
24 | - `linux/arm64`
25 | - `linux/arm/v7`
26 | - `linux/arm/v6`
27 |
28 | ```
29 | REPOSITORY TAG SIZE
30 | ghcr.io/void-linux/void-glibc latest 64.5MB
31 | ghcr.io/void-linux/void-musl latest 40.3MB
32 | ghcr.io/void-linux/void-glibc-full latest 135MB
33 | ghcr.io/void-linux/void-musl-full latest 81.4MB
34 | ghcr.io/void-linux/void-glibc-busybox latest 39.6MB
35 | ghcr.io/void-linux/void-musl-busybox latest 14.4MB
36 | ```
37 |
38 | ## Building locally
39 |
40 | With `docker` and `docker-buildx`:
41 |
42 | 1. Install and set up `docker` and `docker-buildx`. If building multi-platform images,
43 | `qemu-user-static`, and `binfmt-support` are also needed:
44 | ```sh
45 | xbps-install docker docker-buildx
46 | ln -s /etc/sv/docker /var/service
47 | # optional
48 | xbps-install binfmt-support
49 | ln -s /etc/sv/binfmt-support /var/service
50 | xbps-install qemu-user-static
51 | ```
52 | 2. Build the image:
53 | ```sh
54 | docker build --target "image-" -f Containerfile --build-arg="LIBC=" . --tag
55 | ```
56 | > Note: To easily build multi-platform images, `docker buildx bake` can be used.
57 |
58 | With `podman`:
59 |
60 | 1. Install and set up `podman`.
61 | 2. Build the image:
62 | ```sh
63 | podman build --target "image-" --build-arg="LIBC=" . --tag
64 | ```
65 |
--------------------------------------------------------------------------------
/Containerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1
2 | FROM --platform=${BUILDPLATFORM} alpine:3.22 AS bootstrap
3 | ARG TARGETPLATFORM
4 | ARG MIRROR=https://repo-ci.voidlinux.org
5 | ARG LIBC
6 | RUN apk add ca-certificates curl && \
7 | curl "${MIRROR}/static/xbps-static-static-0.59_5.$(uname -m)-musl.tar.xz" | tar vJx
8 | COPY keys/* /target/var/db/xbps/keys/
9 | COPY setup.sh /bootstrap/setup.sh
10 | COPY noextract-python.conf /target/etc/xbps.d/noextract-python.conf
11 | RUN --mount=type=cache,sharing=locked,target=/target/var/cache/xbps,id=repocache-${LIBC} \
12 | . /bootstrap/setup.sh; \
13 | XBPS_TARGET_ARCH=${ARCH} xbps-install -S \
14 | -R "${REPO}" \
15 | -r /target
16 |
17 | FROM --platform=${BUILDPLATFORM} bootstrap AS install-default
18 | ARG TARGETPLATFORM
19 | ARG MIRROR
20 | ARG LIBC
21 | COPY --from=bootstrap /target /target
22 | COPY noextract.conf /target/etc/xbps.d/noextract.conf
23 | RUN --mount=type=cache,sharing=locked,target=/target/var/cache/xbps,id=repocache-${LIBC} \
24 | . /bootstrap/setup.sh; \
25 | XBPS_TARGET_ARCH=${ARCH} xbps-install -y \
26 | -R "${REPO}" \
27 | -r /target \
28 | xbps base-files dash coreutils grep run-parts sed gawk
29 |
30 | FROM --platform=${BUILDPLATFORM} bootstrap AS install-busybox
31 | ARG TARGETPLATFORM
32 | ARG MIRROR
33 | ARG LIBC
34 | COPY --from=bootstrap /target /target
35 | COPY noextract.conf /target/etc/xbps.d/noextract.conf
36 | RUN --mount=type=cache,sharing=locked,target=/target/var/cache/xbps,id=repocache-${LIBC} \
37 | . /bootstrap/setup.sh; \
38 | XBPS_TARGET_ARCH=${ARCH} xbps-install -y \
39 | -R "${REPO}" \
40 | -r /target \
41 | xbps base-files busybox-huge
42 |
43 | FROM --platform=${BUILDPLATFORM} bootstrap AS install-full
44 | ARG TARGETPLATFORM
45 | ARG MIRROR
46 | ARG LIBC
47 | COPY --from=bootstrap /target /target
48 | RUN --mount=type=cache,sharing=locked,target=/target/var/cache/xbps,id=repocache-${LIBC} \
49 | . /bootstrap/setup.sh; \
50 | XBPS_TARGET_ARCH=${ARCH} xbps-install -y \
51 | -R "${REPO}" \
52 | -r /target \
53 | base-container
54 |
55 | FROM scratch AS image-default
56 | COPY --link --from=install-default /target /
57 | RUN \
58 | install -dm1777 tmp; \
59 | xbps-reconfigure -fa; \
60 | rm -rf /var/cache/xbps/*
61 | CMD ["/bin/sh"]
62 |
63 | FROM scratch AS image-busybox
64 | COPY --link --from=install-busybox /target /
65 | RUN \
66 | for util in $(/usr/bin/busybox --list); do \
67 | [ ! -f "/usr/bin/$util" ] && /usr/bin/busybox ln -sfv busybox "/usr/bin/$util"; \
68 | done; \
69 | install -dm1777 tmp; \
70 | xbps-reconfigure -fa; \
71 | rm -rf /var/cache/xbps/*
72 | CMD ["/bin/sh"]
73 |
74 | FROM scratch AS image-full
75 | COPY --link --from=install-full /target /
76 | RUN \
77 | install -dm1777 tmp; \
78 | xbps-reconfigure -fa; \
79 | rm -rf /var/cache/xbps/*
80 | CMD ["/bin/sh"]
81 |
--------------------------------------------------------------------------------
/.github/workflows/build.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: 'Build containers'
3 |
4 | on:
5 | schedule:
6 | - cron: "0 0 1 * *"
7 | workflow_dispatch:
8 | pull_request:
9 | branches:
10 | - master
11 | paths-ignore:
12 | - COPYING
13 | - README.md
14 | push:
15 | branches:
16 | - master
17 | paths-ignore:
18 | - COPYING
19 | - README.md
20 |
21 | concurrency:
22 | group: ${{ github.workflow }}-${{ github.ref }}
23 | cancel-in-progress: true
24 |
25 | jobs:
26 | build:
27 | runs-on: ubuntu-latest
28 |
29 | strategy:
30 | matrix:
31 | libc:
32 | - 'glibc'
33 | - 'musl'
34 | variant:
35 | - ''
36 | - '-full'
37 | - '-busybox'
38 |
39 | steps:
40 | - name: Checkout
41 | uses: classabbyamp/treeless-checkout-action@v1
42 |
43 | - name: Get image release
44 | id: release
45 | run: |
46 | # gets the list of all date-shaped tags for the image, finds the most recent one
47 | tag="$(skopeo list-tags "docker://ghcr.io/${{ github.repository_owner }}/void-${{ matrix.libc }}${{ matrix.variant }}" | \
48 | jq -r '.Tags | sort | reverse | map(select(test("^[0-9]{8}(R[0-9]+)?$")))[0]')"
49 | # tags from a different day or pre-YYYYMMDDRN
50 | if [ "${tag%R*}" != "$(date -u +%Y%m%d)" ] || [ "${tag%R*}" = "${tag}" ]; then
51 | rel=1
52 | else
53 | rel=$(( ${tag##*R} + 1 ))
54 | fi
55 | echo "rel=${rel}" >> "${GITHUB_OUTPUT}"
56 |
57 | - name: Docker metadata
58 | id: meta
59 | uses: docker/metadata-action@v4
60 | with:
61 | images: |
62 | ghcr.io/${{ github.repository_owner }}/void-${{ matrix.libc }}${{ matrix.variant }}
63 | tags: |
64 | type=sha,prefix=
65 | type=raw,value=latest,enable={{is_default_branch}}
66 | type=raw,value={{date 'YYYYMMDD'}}R${{ steps.release.outputs.rel }},enable={{is_default_branch}},priority=1000
67 | flavor: latest=false
68 | labels: |
69 | org.opencontainers.image.authors=Void Linux team and contributors
70 | org.opencontainers.image.url=https://voidlinux.org
71 | org.opencontainers.image.documentation=https://docs.voidlinux.org
72 | org.opencontainers.image.source=https://github.com/${{ github.repository }}
73 | org.opencontainers.image.vendor=Void Linux
74 | org.opencontainers.image.title=Void Linux
75 | org.opencontainers.image.description=general-purpose image based on Void Linux
76 | annotations: |
77 | org.opencontainers.image.authors=Void Linux team and contributors
78 | org.opencontainers.image.url=https://voidlinux.org
79 | org.opencontainers.image.documentation=https://docs.voidlinux.org
80 | org.opencontainers.image.source=https://github.com/${{ github.repository }}
81 | org.opencontainers.image.vendor=Void Linux
82 | org.opencontainers.image.title=Void Linux
83 | org.opencontainers.image.description=general-purpose image based on Void Linux
84 |
85 | - name: Set up QEMU
86 | uses: docker/setup-qemu-action@v2
87 |
88 | - name: Set up Docker Buildx
89 | uses: docker/setup-buildx-action@v2
90 |
91 | - name: Login to GHCR
92 | if: github.event_name != 'pull_request'
93 | uses: docker/login-action@v2
94 | with:
95 | registry: ghcr.io
96 | username: ${{ github.actor }}
97 | password: ${{ secrets.GITHUB_TOKEN }}
98 |
99 | - name: Build and push images
100 | id: build_and_push
101 | uses: docker/bake-action@v5
102 | with:
103 | push: ${{ github.event_name != 'pull_request' }}
104 | targets: void-${{ matrix.libc }}${{ matrix.variant }}
105 | files: |
106 | docker-bake.hcl
107 | ${{ steps.meta.outputs.bake-file }}
108 | set: |
109 | _common.cache-to=type=gha
110 | _common.cache-from=type=gha
111 | provenance: false
112 | sbom: false
113 |
--------------------------------------------------------------------------------