Skip to content

Comments

Build ffmpeg from source in Dockerfile#30569

Merged
renchap merged 13 commits intomastodon:mainfrom
vmstan:build-libvips-ffmpeg
Jun 18, 2024
Merged

Build ffmpeg from source in Dockerfile#30569
renchap merged 13 commits intomastodon:mainfrom
vmstan:build-libvips-ffmpeg

Conversation

@vmstan
Copy link
Contributor

@vmstan vmstan commented Jun 5, 2024

This PR enhances the production Dockerfile by converting from installing the version ffmpeg that is available in the Debian repos, to using a custom built versions. This has the following advantages:

  • Image size reduction: the current Dockerfile was optimized in Dockerfile rewrite based on Ruby image with performance optimizations and size reduction, dedicated Streaming image #26850 through a number of methods including separating the Core Image and Streaming image, removing Node from the resulting image. The 4.2 image is approximately 1.5GB in size while the current 4.3 image is just under 1GB. When ffmpeg is installed from the Debian repo, it includes a number of dependencies to support file formats that are not used or explicitly not desired in Mastodon, including the unused X11 server. Build libvips from source in Dockerfile #30571 took the first step in compiling libvips from source to eliminate this dependency. The size of the resulting Docker image built by this PR under 700MB!
  • Controlled version adoption: ffmpeg version control should be considered as essential as Ruby, Node, Postgres, or any other Mastodon dependency given the importance of media processing. The Debian repos are notoriously slow in adoption of upgrades, for example ffmpeg is currently at 5.1.4 when 7.0.1 is available.
  • Optimized library selection: Compiling these packages from source allows us to use only the libraries that are necessary for Mastodon. Ultimately I would like to become more restrictive about what formats are compiled as supported in ffmpeg as most are not needed by Mastodon.

ffmpeg compile/library settings

  • Versions can be controlled in a similar method as Ruby/Node through Docker build arguments, to enable easier local testing and customized version deployments. [--build-arg FFMPEG_VERSION="7.0.1"]
  • Source code is downloaded directly from ffmpeg.org.
  • Building documentation and direct network support are disabled. (Full list of compile options available at https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu)
  • libx264 is used for H.264 video encoding
  • libx265 is used for HEVC video encoding
  • libvpx is used for VP8/VP9 video encoding/decoding
  • libopus is used for Opus audio encoding/decoding
  • libdav1d is used for AV1 decoding
  • libmp3lame is used for MP3 encoding
  • libvorbis is used for Vorbis audio encoding/decoding
  • libwebp is used for WebP encoding
  • libsnappy is used for compression
$ ffmpeg -version
ffmpeg version 7.0.1 Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 12 (Debian 12.2.0-14)
configuration: --prefix=/usr/local/ffmpeg --toolchain=hardened --disable-doc --disable-network --disable-static --disable-debug --disable-ffplay --disable-devices --enable-gpl --enable-version3 --enable-shared --enable-ffmpeg --enable-ffprobe --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libwebp
libavutil      59.  8.100 / 59.  8.100
libavcodec     61.  3.100 / 61.  3.100
libavformat    61.  1.100 / 61.  1.100
libavdevice    61.  1.100 / 61.  1.100
libavfilter    10.  1.100 / 10.  1.100
libswscale      8.  1.100 /  8.  1.100
libswresample   5.  1.100 /  5.  1.100
libpostproc    58.  1.100 / 58.  1.100

@renchap
Copy link
Member

renchap commented Jun 5, 2024

Please split the vips part from the ffmpeg part.

Also, how to we ensure that we update those versions regularly?

@shleeable
Copy link
Contributor

I've given this PR a test as well... and this looks good on my machine.

@renchap renchap added the docker label Jun 6, 2024
@shleeable
Copy link
Contributor

shleeable commented Jun 7, 2024

image

This PR is running A.S now with no known regression.

Edit: It's likely the CPU drop was a combination of this PR and my S3 timeout PR.

@vmstan
Copy link
Contributor Author

vmstan commented Jun 7, 2024

Please split the vips part from the ffmpeg part.

Also, how to we ensure that we update those versions regularly?

When paired with #30602 both libvips and ffmpeg versions will be tracked by Renovate

@vmstan vmstan changed the title Build libvips and ffmpeg from source in Dockerfile Build ffmpeg from source in Dockerfile Jun 13, 2024
@vmstan
Copy link
Contributor Author

vmstan commented Jun 13, 2024

This has been renamed and rebased to only include ffmpeg changes, since the Vips changes were merged separately in #30571

@renchap
Copy link
Member

renchap commented Jun 13, 2024

I love this, but I wonder how we should handle the supported ffmpeg versions. Major versions might have incompatible options, and I dont think we even care about this right now, or we provide a minimum supported ffmpeg version?

@vmstan
Copy link
Contributor Author

vmstan commented Jun 13, 2024

Closes #20838

@vmstan
Copy link
Contributor Author

vmstan commented Jun 13, 2024

I love this, but I wonder how we should handle the supported ffmpeg versions. Major versions might have incompatible options, and I dont think we even care about this right now, or we provide a minimum supported ffmpeg version?

This shouldn't really impact overall supported versions, although ffmpeg would probably be the hardest one to come up with a minimum supported version as they're still providing updates for their 2.8.x

renchap
renchap previously approved these changes Jun 17, 2024
Copy link
Member

@renchap renchap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. We will probably need to run it in production and check that we do not have weird video formats/codecs that are no longer processed correctly due to a missing library.

@renchap renchap requested a review from a team June 17, 2024 09:15
@vmstan
Copy link
Contributor Author

vmstan commented Jun 18, 2024

Looks good to me. We will probably need to run it in production and check that we do not have weird video formats/codecs that are no longer processed correctly due to a missing library.

I cleaned up some of the options that upon further review seemed unnecessary, and also added support for libsnappy as a compression method (it's the same one used by the Debian repo builds).

I'm hopeful we'll be covered on most formats/codecs as it seems like a lot of the more advanced libraries are around encoding files which Mastodon has limited format support on that side (H.264 with AAC video, or MP3 audio)

@shleeable
Copy link
Contributor

shleeable commented Jun 18, 2024

Thanks for this @vmstan - I've been testing this PR without (known) regressions.

@renchap renchap added this pull request to the merge queue Jun 18, 2024
Merged via the queue into mastodon:main with commit d97fcd0 Jun 18, 2024
nomad-geek pushed a commit to dftba-club/mastodon that referenced this pull request Jul 3, 2024
@vmstan vmstan deleted the build-libvips-ffmpeg branch July 26, 2024 17:22
justinwritescode pushed a commit to justinwritescode/mastodon that referenced this pull request Sep 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants