chore(docker): multi-stage build + static ffmpeg to shrink image (refs #12) #13

Merged
vmruiz merged 2 commits from chore/docker-image-size into main 2026-08-23 22:12:54 +02:00
Owner

Summary

Closes #12. Shrink the Docker image from 701MB → 521MB (−26%) with three changes:

  1. Multi-stage build: separate builder (isolated venv) / ffmpeg (pinned mwader/static-ffmpeg:7.0.2) / runtime stages, so build tooling never lands in the final image.
  2. Static ffmpeg: replace the apt apt-get install ffmpeg pull (~450MB of shared libs) with only the ffmpeg/ffprobe binaries copied from a pinned static image. Videos still get thumbnails (used by app/telegram/thumbnails.py).
  3. .dockerignore: excludes .git, tests/, docs, caches and venvs from the build context and the final layers.

Verification

  • docker images: baseline 701MB vs optimized 521MB.
  • ffmpeg -version inside the image → 7.0.2 (functional).
  • App boots on the new image and serves /login with HTTP 200 (tested locally with SQLite + uvicorn).
  • ruff and compileall gates: no new errors vs origin/main (the 57 pre-existing lint warnings are unchanged).

Notes / decisions

  • Tried johnvansickle static builds too: smaller (422MB) but their release URL is a moving "latest" with no stable per-version checksum, making CI non-reproducible. Chose mwader/static-ffmpeg:7.0.2 (pinned tag, ~2s cached build, reproducible) as the better trade-off.
  • ffmpeg is not obsolete — it generates video thumbnails. Removing it would regress that feature (the code already degrades gracefully to no-thumbnail, but we keep it).
## Summary Closes #12. Shrink the Docker image from **701MB → 521MB (−26%)** with three changes: 1. **Multi-stage build**: separate `builder` (isolated venv) / `ffmpeg` (pinned `mwader/static-ffmpeg:7.0.2`) / `runtime` stages, so build tooling never lands in the final image. 2. **Static ffmpeg**: replace the apt `apt-get install ffmpeg` pull (~450MB of shared libs) with only the `ffmpeg`/`ffprobe` binaries copied from a pinned static image. Videos still get thumbnails (used by `app/telegram/thumbnails.py`). 3. **`.dockerignore`**: excludes `.git`, `tests/`, `docs`, caches and venvs from the build context and the final layers. ## Verification - `docker images`: baseline `701MB` vs optimized `521MB`. - `ffmpeg -version` inside the image → `7.0.2` (functional). - App boots on the new image and serves `/login` with **HTTP 200** (tested locally with SQLite + uvicorn). - `ruff` and `compileall` gates: no new errors vs `origin/main` (the 57 pre-existing lint warnings are unchanged). ## Notes / decisions - Tried `johnvansickle` static builds too: smaller (422MB) but their release URL is a moving "latest" with no stable per-version checksum, making CI non-reproducible. Chose `mwader/static-ffmpeg:7.0.2` (pinned tag, ~2s cached build, reproducible) as the better trade-off. - ffmpeg is **not** obsolete — it generates video thumbnails. Removing it would regress that feature (the code already degrades gracefully to no-thumbnail, but we keep it).
chore(docker): multi-stage build + static ffmpeg to shrink image (refs #12)
All checks were successful
Deploy Development Branch / deploy-dev (push) Successful in 2m1s
6337924a34
- Split into builder (venv) / ffmpeg (pinned mwader/static-ffmpeg:7.0.2)
  / runtime stages.
- Replace apt 'apt-get install ffmpeg' (~450MB of libs) with static
  ffmpeg/ffprobe copied from a pinned image.
- Add .dockerignore to keep .git, tests, caches, docs out of the
  build context and final layers.

Measured (docker images): baseline 701MB -> optimized 521MB (-26%).
ffmpeg 7.0.2 verified functional; app boots and serves /login (HTTP 200)
on the new image.
chore(docker): drop unused ffprobe binary (-124MB) (refs #12)
All checks were successful
Deploy Development Branch / deploy-dev (push) Successful in 1m17s
Clean Up Development Branch / cleanup-dev (pull_request) Successful in 19s
19e918d784
ffprobe is not referenced anywhere in app/tests; only ffmpeg is used
(for video thumbnail frames in app/telegram/thumbnails.py). Copying
just /ffmpeg from the pinned mwader image trims the image further.

Measured: 521MB -> 393MB (-26% vs the 701MB baseline, -44% total).
vmruiz merged commit 19adf548ab into main 2026-08-23 22:12:54 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
vmruiz/telegramarr!13
No description provided.