Skip to content

Commit

Permalink
Prepare to build multiarch container (AMD64 + aarch64)
Browse files Browse the repository at this point in the history
  • Loading branch information
emarsden committed Nov 27, 2023
1 parent 6a06032 commit 37155bf
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 3 deletions.
13 changes: 10 additions & 3 deletions .github/workflows/container.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Build a Docker/Podman container with dash-mpd-cli and its external helper applications.
# We currently build for Linux/AMD64 and for Linux/aarch64.

name: Build container image

Expand All @@ -19,7 +20,10 @@ jobs:

name: Build and push container/Linux
steps:
- name: Checkout
- name: Install qemu
run: sudo apt install qemu-user-static

- name: Checkout sources
uses: actions/checkout@v4

- name: Log in to ghcr.io
Expand All @@ -29,9 +33,12 @@ jobs:
password: ${{ env.REGISTRY_PASSWORD }}
registry: ${{ env.IMAGE_REGISTRY }}

- name: Build container image with podman
- name: Build container images with podman
id: build-image
run: podman build -f Containerfile --tag dash-mpd-cli
run: |
podman manifest create dash-mpd-cli
podman build . -f etc/Containerfile_linux_amd64 --arch amd64 --tag dash-mpd-cli-linux-amd64 --manifest dash-mpd-cli
podman build . -f etc/Containerfile_linux_aarch64 --arch arm64/v8 --tag dash-mpd-cli-linux-aarch64 --manifest dash-mpd-cli
- name: Push container image
id: push-to-registry
Expand Down
83 changes: 83 additions & 0 deletions etc/Containerfile_linux_aarch64
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# -*- Dockerfile -*-
#
# Recipe to build a container image for dash-mpd-cli + helper applications, for Linux/Aarch64.
#
# This Containerfile contains the recipe needed to generate a docker/podman/OCI container image
# including the dash-mpd-cli binary alongside the external helper applications that it uses for
# muxing media streams, for extracting/converting subtitle streams, and for decrypting content
# infected with DRM. These are packaged with a minimal Alpine Linux installation.
#
# To build the container locally (not needed for an end user)
#
# podman manifest create dash-mpd-cli
# podman build . -f etc/Containerfile_linux_aarch64 --platform linux/arm64/v8 --tag dash-mpd-cli-linux-aarch64 --manifest dash-mpd-cli



# We could in principle cross-compile the Rust code from an AMD64 machine using the
# aarch64-uknown-linux-musl target, but that fails as of 2023-11. Instead, we build in the aarch64
# Alpine Linux image, which works.
#
# static build of MP4Box from GPAC, which is not packaged for Alpine Linux.
# https://github.com/gpac/gpac/wiki/GPAC-Build-Guide-for-Linux
FROM --platform=linux/arm64 alpine:latest AS builder
WORKDIR /src
COPY ./ ./
RUN apk update && \
apk upgrade && \
apk add --no-cache curl file musl-dev pkgconfig git g++ binutils make zlib-dev zlib-static && \
curl https://sh.rustup.rs -sSf --output rustup.sh && \
sh rustup.sh -y --default-toolchain none && \
export PATH="${HOME}/.cargo/bin:$PATH" && \
rustup toolchain install stable --target aarch64-unknown-linux-musl && \
cargo update && \
cargo build --target aarch64-unknown-linux-musl --release && \
git clone https://github.com/gpac/gpac.git && \
cd gpac && ./configure --static-bin && \
make -j 4 && \
ls -l bin/gcc/ && \
file bin/gcc/MP4Box # check that we built for aarch64


# Now build the final image
FROM --platform=linux/arm64 alpine:latest
LABEL org.opencontainers.image.description="Download media content from a DASH-MPEG or DASH-WebM MPD manifest." \
org.opencontainers.image.title="dash-mpd-cli" \
org.opencontainers.image.url="https://github.com/emarsden/dash-mpd-cli" \
org.opencontainers.image.source="https://github.com/emarsden/dash-mpd-cli" \
org.opencontainers.image.version="0.2.9" \
org.opencontainers.image.authors="[email protected]" \
org.opencontainers.image.licenses="MIT,GPL-2.0-or-later"

# Install our external dependencies. Licences for the external dependencies:
# - ffmpeg: GNU GPL v2
# - mkvmerge (from mkvtoolnix): GNU GPL v2
# - vlc: GNU GPL v2, not installed because it inflates image size considerably
# - mp4decrypt (from bento4): GNU GPL v2
# - xsltproc (from libxslt): MIT
# - Shaka packager: MIT
#
# We can't install shaka-packager from the docker.io/google/shaka-packager image, because it's only
# built for AMD64.
RUN apk update && \
apk upgrade && \
apk add --no-cache libc6-compat wget ffmpeg mkvtoolnix bento4 libxslt && \
wget -q -O /tmp/shaka-packager https://github.com/shaka-project/shaka-packager/releases/latest/download/packager-linux-arm64 && \
mv /tmp/shaka-packager /usr/local/bin && \
chmod +x /usr/local/bin/shaka-packager && \
mkdir /content && \
chown root.root /content && \
chmod a=rwx,o+t /content

COPY --from=builder --chown=root:root --chmod=755 \
/src/target/aarch64-unknown-linux-musl/release/dash-mpd-cli /usr/local/bin
COPY --from=builder --chown=root:root --chmod=755 \
/src/gpac/bin/gcc/MP4Box /usr/local/bin

WORKDIR /content
ENTRYPOINT ["/usr/local/bin/dash-mpd-cli"]

# Size of our container image:
# with vlc: 331 MB
# without vlc: 203 MB (aarch64)

81 changes: 81 additions & 0 deletions etc/Containerfile_linux_amd64
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# -*- Dockerfile -*-
#
# Recipe to build a container image for dash-mpd-cli + help applications, for Linux/AMD64.
#
# This Containerfile contains the recipe needed to generate a docker/podman/OCI container image
# including the dash-mpd-cli binary alongside the external helper applications that it uses for
# muxing media streams, for extracting/converting subtitle streams, and for decrypting content
# infected with DRM. These are packaged with a minimal Alpine Linux installation so that they can be
# run on any host that can run Linux/AMD64 containers (using Podman or Docker on Linux, Microsoft
# Windows and MacOS).
#
# To build the container locally (not needed for an end user) on an AMD64 host:
#
# podman manifest create dash-mpd-cli
# podman build . -f etc/Containerfile_linux_amd64 --arch amd64 --tag dash-mpd-cli-linux-amd64 --manifest dash-mpd-cli


FROM docker.io/rust:latest AS rustbuilder
RUN rustup target add x86_64-unknown-linux-musl
RUN apt update && apt install -y musl-tools musl-dev
RUN update-ca-certificates

WORKDIR /src
COPY ../ ./
RUN cargo update && \
cargo build --target x86_64-unknown-linux-musl --release

# static build of MP4Box from GPAC, which is not packaged for Alpine Linux.
# https://github.com/gpac/gpac/wiki/GPAC-Build-Guide-for-Linux
FROM alpine:latest AS gpacbuilder
WORKDIR /src
RUN apk update && \
apk upgrade && \
apk add --no-cache musl-dev pkgconfig git g++ binutils make zlib-dev zlib-static && \
git clone https://github.com/gpac/gpac.git && \
cd gpac && ./configure --static-bin && \
make && \
ls -l bin/gcc/
# here there should be MP4Box


# Now build the final image
FROM alpine:latest
LABEL org.opencontainers.image.description="Download media content from a DASH-MPEG or DASH-WebM MPD manifest." \
org.opencontainers.image.title="dash-mpd-cli" \
org.opencontainers.image.url="https://github.com/emarsden/dash-mpd-cli" \
org.opencontainers.image.source="https://github.com/emarsden/dash-mpd-cli" \
org.opencontainers.image.version="0.2.9" \
org.opencontainers.image.authors="[email protected]" \
org.opencontainers.image.licenses="MIT,GPL-2.0-or-later"

# Install our external dependencies. Licences for the external dependencies:
# - ffmpeg: GNU GPL v2
# - mkvtoolnix: GNU GPL v2
# - vlc: GNU GPL v2, not installed because it inflates image size considerably
# - mp4decrypt (bento4): GNU GPL v2
# - xsltproc: MIT
# - Shaka packager: MIT
RUN apk update && \
apk upgrade && \
apk add --no-cache ffmpeg mkvtoolnix bento4 libxslt && \
mkdir /content && \
chown root.root /content && \
chmod a=rwx,o+t /content

COPY --from=docker.io/google/shaka-packager:latest --chown=root:root \
/usr/bin/packager /usr/local/bin/shaka-packager
COPY --from=rustbuilder --chown=root:root --chmod=755 \
/src/target/x86_64-unknown-linux-musl/release/dash-mpd-cli /usr/local/bin
COPY --from=gpacbuilder --chown=root:root --chmod=755 \
/src/gpac/bin/gcc/MP4Box /usr/local/bin

WORKDIR /content
ENTRYPOINT ["/usr/local/bin/dash-mpd-cli"]

# Size of our container image:
# with vlc: 331 MB
# without vlc: 217 MB
# static ffmpeg + shaka-packager from docker: 299 MB
# shaka-packager from docker: 216 MB

0 comments on commit 37155bf

Please sign in to comment.