I am documenting my experience creating a render server for the kdenlive project using Docker. Although some of the findings are not optimal, they are the solutions I found to the problems. I believe that this information will be useful to other people with similar issues.
There was a server available with four GeForce GTX Titan Black GPUs, running Debian 9 Stretch. However, the system was outdated, and I could not upgrade it since other users were running projects on that server.
My first attempt was to install ffmpeg and melt, but I couldn't because the apt sources were outdated. I then tried to enable backport repositories, but I was unable to install the packages.
So, I decided to use Docker containers, even though I had no idea what they were.
To start, the code I used to run the container was:
docker run \
--name video-render \
--security-opt seccomp:unconfined \
-v /home/user/docker:/home/docker \
--gpus all \
-e NVIDIA_DRIVER_CAPABILITIES=all \
-ti \
ubuntu:rolling /bin/bash
The -security-opt seccomp:unconfined option allowed the apt update command to run properly, which was necessary because the Docker version was too old. The --gpus all parameter enabled all GPUs to be used inside the container, and the -e NVIDIA_DRIVER_CAPABILITIES=all parameter enabled all capabilities of the GPUs to be used in the container. Without it, nvenc could not be used.
I used the ubuntu:rolling image because the Nvidia images enabled a version of the Nvidia driver newer than the host image and it was not possible to use nvenc. Other versions of Nvidia images, with the correct Nvidia driver, had an old version of Ubuntu where I couldn't install the latest ffmpeg and melt.
To start the container, I used the following commands:
docker start video-renderer
docker attach video-renderer
Initially, I configured apt to work properly in the container:
apt update
apt install vim bash-completion
After installing these initial packages, I edited /etc/bash.bashrc to enable autocompletion. I found the following line and uncommented it:
# enable bash completion in interactive shells
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
I then saved the document and ran:
source /etc/bash.bashrc
to load autocompletion.
To enable apt autocompletion, I ran the following code:
rm /etc/apt/apt.conf.d/docker-clean
apt update
This enabled the apt cache to be saved and enabled autocompletion. However, it also made the container use more disk space, which was the reason it was disabled.
Instead of installing ffmpeg and melt separately, I opted to fully install kdenlive and have all the effects and other stuff installed with it. The downside is that I had to install all KDE stuff, even the components I would not use.
To install the PPA, I first installed software-properties-common:
apt install software-properties-common
This enabled add-apt-repository to install the PPA and get the latest kdenlive version:
add-apt-repository ppa:kdenlive/kdenlive-stable
apt update
apt install kdenlive
It will take a while...
I am using Kdenlive version 23.04.0.
To prepare the project for rendering on the server, you should set the project folder to the parent folder of the project file. This can be changed in Project Settings -> Settings.
Also, all the Project Bin assets should point to files in the Project Folder (the same folder where the .kdenlive file is located).
After saving the file, all file paths must be changed to relative paths, and the project root folder should be set to the "." directory.
Use this script to make the changes:
#!/bin/bash
# Define the function to change absolute paths to relative paths
function change_path {
sed -i -r "s,(kdenlive:clipid=\"[0-9]+\" .* url=\")/?(.*)(\" .*\$),\1.\2\3,g" $1
sed -i -r "s,(kdenlive:fileurl=\"/)?(.*)(\" .* >\n<property .*mlt_service=\"avformat\" .*\$),\1.\2\3,g" $1
sed -i -r "s,(kdenlive:projectfolderurl=\")/?([^/]*)(/.*/\" .*\$),\1.\2\3,g" $1
}
# Check if a file is passed as an argument
if [ -z "$1" ]; then
echo "Usage: $0 file.kdenlive"
exit 1
fi
# Check if the file exists
if [ ! -f "$1" ]; then
echo "File not found: $1"
exit 1
fi
# Make a backup of the original file
cp $1 $1.bkp
# Call the function to change the paths
change_path $1
# Change the root directory to .
sed -i -r "s,^(<mlt LC_NUMERIC=\"[^\"]*\" version=\"[^\"]*\" root=\").*(\">),\1.\\2," $1
echo "Done!"
After doing this, you can copy all your project files to the /home/user/docker folder on the server to make them accessible to the container in /home/docker, as set in the docker run command.
After preparing all the files, you need to install xvfb to run the render in a fake X11 environment.
apt install xvfb
Then, run this command to render the project, assuming the filename is project.kdenlive, and the resulting file is out.mp4:
xvfb-run -a melt-7 project.kdenlive \
-consumer avformat:out.mp4 \
vcodec=h264_nvenc \
acodec=aac
The vcodec=h264_nvenc sets the encoder to NVENC. You can change other parameters to match your desired render quality.
And... that's it. Enjoy the render :)