Setup Alpine Linux environment
ActionsTags
(1)A GitHub Action to easily set up and use a chroot-based [1] Alpine Linux environment in your workflows and emulate any supported CPU architecture (using QEMU).
runs-on: ubuntu-latest
steps:
- uses: jirutka/setup-alpine@v1
with:
branch: v3.15
- run: cat /etc/alpine-release
shell: alpine.sh {0}See more examples…
-
Easy to use and flexible
-
Add one step
uses: jirutka/setup-alpine@v1to set up the Alpine environment, for the next steps that should run in this environment, specifyshell: alpine.sh {0}. See Usage examples for more. -
You can switch between one, or even more, Alpine environments and the host system (Ubuntu) within a single job (i.e. each step can run in a different environment). This is ideal, for example, for cross-compilations.
-
-
Emulation of non-x86 architectures
-
This couldn’t be easier; just specify input parameter arch. The action sets up QEMU user space emulator and installs Alpine Linux environment for the specified architecture. You can then build and run binaries for/from this architecture, just like on real hardware, but (significantly) slower (it’s a software emulation after all).
-
-
No hassle with Docker images
-
You don’t have to write any Dockerfiles, for example, to cross-compile Rust crates with C dependencies.[2]
-
No, you really don’t need any so-called “official” Docker image for gcc, nodejs, python or whatever you need… just install it using apk from Alpine packages. It is fast, really fast!
-
-
Always up to date environment
-
The whole environment, all packages, are always installed directly from the Alpine Linux’s official repositories using apk-tools (Alpine’s package manager). There’s no intermediate layer that tends to lang behind with security fixes (such as Docker images). — You might be thinking, isn’t that slow? No, it’s faster than pulling a Docker image!
-
No, you really don’t need any Docker image to get a stable build environment. Alpine Linux provides stable releases (branches); these get just (security) fixes, no breaking changes.
-
-
It’s simple and lightweight
-
You don’t have to worry about that on a hosted CI service, but still… This action is written in ~220 LoC and uses only basic Unix tools (chroot, mount, wget, Bash, …) and apk-tools (Alpine’s package manager). That’s it.
-
- apk-tools-url
-
URL of the apk-tools static binary to use. It must end with
#!sha256!followed by a SHA-256 hash of the file. This should normally be left at the default value.Default: see action.yml
- arch
-
CPU architecture to emulate using QEMU user space emulator. Allowed values are:
x86_64(native),x86(native),aarch64,armhf[3],armv7,loongarch64[4],ppc64le,riscv64[5], ands390x.Default:
x86_64 - branch
-
Alpine branch (aka release) to install:
vMAJOR.MINOR,latest-stable, oredge.Example:
v3.15
Default:latest-stable - extra-keys
-
A list of paths of additional trusted keys (for installing packages from the extra-repositories) to copy into /etc/apk/keys/. The paths should be relative to the workspace directory (the default location of your repository when using the checkout action).
Example:
.keys/pkgs@example.org-56d0d9fd.rsa.pub - extra-repositories
-
A list of additional Alpine repositories to add into /etc/apk/repositories (Alpine’s official main and community repositories are always added).
- mirror-url
-
URL of an Alpine Linux mirror to fetch packages from.
Default:
http://dl-cdn.alpinelinux.org/alpine - packages
-
A list of Alpine packages to install.
Example:
build-base openssh-client
Default: no extra packages - shell-name
-
Name of the script to run
shin the Alpine chroot that will be added toGITHUB_PATH. This name should be used injobs.<job_id>.steps[*].shell(e.g.shell: alpine.sh {0}) to run the step’s script in the chroot.Default:
alpine.sh - volumes
-
A list of directories on the host system to mount bind into the chroot. You can specify the source and destination path:
<src-dir>:<dest-dir>. The<src-dir>is an absolute path of existing directory on the host system,<dest-dir>is an absolute path in the chroot (it will be created if doesn’t exist). You can omit the latter if they’re the same.Please note that /home/runner/work (where’s your workspace located) is always mounted, don’t specify it here.
Example:
${{ steps.alpine-aarch64.outputs.root-path }}:/mnt/alpine-aarch64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup latest Alpine Linux
uses: jirutka/setup-alpine@v1
- name: Run script inside Alpine chroot as root
run: |
cat /etc/alpine-release
apk add nodejs npm
shell: alpine.sh --root {0}
- name: Run script inside Alpine chroot as the default user (unprivileged)
run: |
ls -la # as you would expect, you're in your workspace directory
npm build
shell: alpine.sh {0}
- name: Run script on the host system (Ubuntu)
run: |
cat /etc/os-release
shell: bash- uses: jirutka/setup-alpine@v1
with:
branch: v3.15
packages: >
build-base
libgit2-dev
mesonruns-on: ubuntu-latest
steps:
- name: Setup Alpine Linux v3.15 for aarch64
uses: jirutka/setup-alpine@v1
with:
arch: aarch64
branch: v3.15
- name: Run script inside Alpine chroot with aarch64 emulation
run: uname -m
shell: alpine.sh {0}- uses: jirutka/setup-alpine@v1
with:
extra-repositories: |
http://dl-cdn.alpinelinux.org/alpine/edge/testing
packages: some-pkg-from-testingruns-on: ubuntu-latest
steps:
- name: Setup latest Alpine Linux for x86_64
uses: jirutka/setup-alpine@v1
with:
shell-name: alpine-x86_64.sh
- name: Setup latest Alpine Linux for aarch64
uses: jirutka/setup-alpine@v1
with:
arch: aarch64
shell-name: alpine-aarch64.sh
- name: Run script inside Alpine chroot
run: uname -m
shell: alpine-x86_64.sh {0}
- name: Run script inside Alpine chroot with aarch64 emulation
run: uname -m
shell: alpine-aarch64.sh {0}
- name: Run script on the host system (Ubuntu)
run: cat /etc/os-release
shell: bashruns-on: ubuntu-latest
strategy:
matrix:
include:
- rust-target: aarch64-unknown-linux-musl
os-arch: aarch64
env:
CROSS_SYSROOT: /mnt/alpine-${{ matrix.os-arch }}
steps:
- uses: actions/checkout@v4
- name: Set up Alpine Linux for ${{ matrix.os-arch }} (target arch)
id: alpine-target
uses: jirutka/setup-alpine@v1
with:
arch: ${{ matrix.os-arch }}
branch: edge
packages: >
dbus-dev
dbus-static
shell-name: alpine-target.sh
- name: Set up Alpine Linux for x86_64 (build arch)
uses: jirutka/setup-alpine@v1
with:
arch: x86_64
packages: >
build-base
pkgconf
lld
rustup
volumes: ${{ steps.alpine-target.outputs.root-path }}:${{ env.CROSS_SYSROOT }}
shell-name: alpine.sh
- name: Install Rust stable toolchain via rustup
run: rustup-init --target ${{ matrix.rust-target }} --default-toolchain stable --profile minimal -y
shell: alpine.sh {0}
- name: Build statically linked binary
env:
CARGO_BUILD_TARGET: ${{ matrix.rust-target }}
CARGO_PROFILE_RELEASE_STRIP: symbols
PKG_CONFIG_ALL_STATIC: '1'
PKG_CONFIG_LIBDIR: ${{ env.CROSS_SYSROOT }}/usr/lib/pkgconfig
RUSTFLAGS: -C linker=/usr/bin/ld.lld
SYSROOT: /dummy # workaround for https://github.com/rust-lang/pkg-config-rs/issues/102
run: |
# Workaround for https://github.com/rust-lang/pkg-config-rs/issues/102.
echo -e '#!/bin/sh\nPKG_CONFIG_SYSROOT_DIR=${{ env.CROSS_SYSROOT }} exec pkgconf "$@"' \
| install -m755 /dev/stdin pkg-config
export PKG_CONFIG="$(pwd)/pkg-config"
cargo build --release --locked --verbose
shell: alpine.sh {0}
- name: Try to run the binary
run: ./myapp --version
working-directory: target/${{ matrix.rust-target }}/release
shell: alpine-target.sh {0}This action is an evolution of the alpine-chroot-install script I originally wrote for Travis CI in 2016. The implementation is principally the same, but tailored to GitHub Actions. It’s so simple and fast thanks to how awesome apk-tools is!
This project is licensed under MIT License. For the full text of the license, see the LICENSE file.
Setup Alpine Linux environment is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.