Build and publish container / build (pull_request) Canceled after 4m29s
Debian's ffmpeg package depends on libavdevice, which can capture from and render to X11, Wayland, SDL and OpenGL. That pulls in Mesa, and Mesa pulls in LLVM for its software rasteriser -- 127 MB of it -- plus Z3 at 27 MB and a speech synthesiser at 28 MB, in an image whose only job is to encode MP3s on a headless NAS. Alpine's ffmpeg brings none of that. The runtime image goes from 576 MB to 189 MB. Small X11 and Wayland client libraries remain, but they are kilobytes rather than megabytes. The test suite passes unchanged inside the new image, which is the point of running it there: the encoder under test is now a musl build from a different distribution, and the tests cover exactly the tag, cover art and container behaviour that could have differed. Verified separately that a CBR 256 encode comes out at the expected bitrate with non-ASCII tags intact. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
32 lines
1.1 KiB
Docker
32 lines
1.1 KiB
Docker
# Alpine rather than Debian slim purely because of ffmpeg's dependencies.
|
|
# Debian's ffmpeg depends on libavdevice, which can render to X11, Wayland and
|
|
# OpenGL, so it drags in Mesa and with it LLVM (127 MB) and Z3 (27 MB) to
|
|
# encode an MP3 on a headless NAS. Alpine's build brings none of that: 576 MB
|
|
# down to 189 MB.
|
|
FROM python:3.13-alpine AS runtime
|
|
|
|
ENV PYTHONUNBUFFERED=1
|
|
|
|
# ffmpeg does the encoding; the application itself has no Python dependencies.
|
|
RUN apk add --no-cache ffmpeg
|
|
|
|
WORKDIR /app
|
|
COPY pyproject.toml README.md ./
|
|
COPY music_mirror.py ./
|
|
RUN pip install --no-cache-dir . \
|
|
&& rm -rf build music_mirror.egg-info
|
|
|
|
# Runs as root by default so a bind-mounted dataset of any ownership is
|
|
# writable. Override with `user:` in compose to run as the dataset's owner.
|
|
ENTRYPOINT ["music-mirror"]
|
|
|
|
# Test stage: the suite runs against this image's own ffmpeg, which is the one
|
|
# that ships. Build it with `--target test`; a failing test fails the build.
|
|
# The published image is the `runtime` stage above and carries none of this.
|
|
FROM runtime AS test
|
|
|
|
RUN pip install --no-cache-dir pytest
|
|
COPY pytest.ini ./
|
|
COPY tests ./tests
|
|
RUN python -m pytest
|