Docker container for compiled software

I’m using TrueNAS 24.10. I currently have a jailmaker jail from 24.04 that has ffmpeg that I compiled from scratch. It’s a complex process.

I was thinking of creating a container with an image of debian in it, then building ffmpeg in it. But I just realized it would all disappear when the container gets stopped. Is that right?

Maybe another option is to save it to external storage, then edit the YAML with a command to copy it into the container when it starts. I could also have YAML commands to install all the build tools automatically too, I think.

Is there a better way to do this? Or should I stick with the old jail? I would prefer having everything in Docker so I don’t have to also remember all the jailmaker structure and commands.

I should think you can create a docker app containing Debian and only have it running when you want to compile ffmpeg. Define a Host Path (i.e. a normal TrueNAS / ZFS directory that you mount as a host path in Docker) to a directory where you put the compiled executable file.

You can then refer to the same host path in other docker containers from where you can run this executable.

2 Likes

Yes. But the trick is to mount host storage over the top of directories you want to persist.

You should perhaps consider writing a dockerfile that builds ffmpeg as part of its construction :wink:

Then the built version is a frozen container.

Of course, wouldn’t be surprised if there are already many ffmpeg build containers floating around.

Or just continue using the jail. Incus is coming.

1 Like

Thanks. That multi-stage stuff looks way out of my league. But I did manage to set up the container with Debian, and set up much of the environment for the build (the external/persistent storage, installing a lot of auxiliary stuff via apt, setting up directories, etc), using a Dockerfile and YAML code.

ffmpeg is complex. There are tons of features you can add with various other packages. And the other packages have their options. I build it 4-5 times a year, and every time something has been changed so tweaks are needed. It doesn’t lend itself to automation. And an off-the-shelf ffmpeg package probably won’t have what an experienced user wants.

I’ll try the approach that Protopia suggested, building (static build) in the container, then copy the binary to the external folder.

1 Like

Easy.
Build the container and then commit/save the container.
You will need to recompile it and save it when there is an update to the OS or the app.

Here’s what I eventually settled on, in case someone with as little knowledge as me is trying something similar.

I create a Dockerfile that sets environment variables and directory paths, installs dependencies needed for the ffmpeg build (and tzdata for time zone setting), creates directories, sets a handy alias for bash root, and sets time zone. PUID and PGID are set to my user ID.

Then simple YAML code is used to start the container. It sets an important link between an internal container path and external host path for persistent storage. That storage is used for the Dockerfile, local git repositories and other packages that need to be compiled before ffmpeg, and the ffmpeg build script. This volumes step cannot be done in the Dockerfile.

Then the location of the Dockerfile is specified, network mode set, and needed commands executed, including the ffmpeg build script. I tried using the command directive for the commands, but the order of execution changes, and the commands attempt to execute before the volumes directive. That doesn’t work in this case.

The ffmpeg build script (not shown) logs all output to a file in external storage, so I can see what goes wrong, if anything, and tweak the script as needed. At the end it copies the final binaries to the external storage so they can be used from anywhere.

Dockerfile:

FROM debian:latest

# Set environment variables and directory paths
ENV PAKS=/ffstor/ffmpeg/packages \
    BUILD=/ffmpeg/build \
    TARGET=/ffmpeg/target \
    PATH=$PATH:/ffmpeg/target/bin \
    TZ="America/Los_Angeles" \
    PUID=1001 \
    PGID=1001

# Install build dependencies, create directories, set alias, and set time zone
# Third apt is build dependencies for fontconfig
RUN apt update && \
    apt --yes install curl git build-essential pkg-config yasm nasm cmake autoconf libtool libfribidi-dev rsync nano wget tzdata && \
    apt --yes install gperf libfreetype-dev libxml2-dev python-is-python3 && \
    mkdir -p ${BUILD} ${TARGET} && \
    echo "alias ll='ls -lahp'" >> /root/.bashrc && \
    ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
    echo $TZ > /etc/timezone

YAML code:

services:
  debian-container:
    volumes:
      - /mnt/Ark/Media/FFstor:/ffstor
    build:
      context: /mnt/Ark/Media/FFstor/ffmpeg  # location of 'Dockerfile' on host
    network_mode: host
    entrypoint: ["/bin/bash", "-c", "chmod u+s /ffstor && /ffstor/ffmpeg/buildffmpeg.sh && sleep infinity"]
2 Likes