We already talked about using flatpak packages in a previous tutorial: with this technology we universally distribute applications, which are packaged together with their dependencies and run inside a sandbox, isolated from the rest of the system. In this tutorial we see how to build and distribute an application inside a flatpak.
In this tutorial you will learn:
- How to install flatpak and flatpak-builder on the most used Linux distributions
- How to create and populate a manifest file with the needed parameters
- How to build, install and run the built application

Software requirements and conventions used
Category | Requirements, Conventions or Software Version Used |
---|---|
System | Distribution-independent |
Software | flatpak and flatpak-builder |
Other | None |
Conventions | # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command$ – requires given linux-commands to be executed as a regular non-privileged user |
Installing the required software
The first thing we must do to start creating a flatpak package for an application, is to install the software needed to build and run flatpaks: flatpak
and flatpak-builder
. We can perform such operation using the package manager of our favorite Linux distribution. On Fedora we must run:
$ sudo dnf install flatpak flatpak-builder
On Debian, or one of the many distributions based on it, instead:
$ sudo apt-get update && sudo apt-get install flatpak flatpak-builder
On Archlinux we can use pacman
to perform the same operation:
$ sudo pacman -Sy flatpak flatpak-builder
In many cases, the flatpak-builder
package already depends on flatpak
, so it could be superfluous to specify the latter explicitly; it should be installed anyway as a dependency.
Creating a flatpak: the basics
The whole process of packaging an application into a flatpak is based on a manifest
file. A manifest file can be written in the YAML or JSON format. In this tutorial we will see how to create a flatpak for ffmpeg: for those of you who don’t know it, it is a complete framework which can be used to convert and stream audio and video. The manifest file shall contain information such as the id
of the application, the runtime
and the sdk
it uses, the command
which shall be used to invoke it once built, the list of the modules
used to build it with the flatpak-builder
package, and the permissions the application should have. In a moment we will take a look at those parameters in detail, but first let’s create a directory for our project, we will call it ffmpeg-flatpak
:
$ mkdir ffmpeg-flatpak
Creating and populating the manifest file
Inside the project directory we must create our manifest. How to name the manifest file? The manifest file should be named after the application ID: every flatpak application must have an unique ID, created using a reverse-DNS style. It is composed of two sections:
- Domain controlled by the project
- The specific project name
The application ID for the gnome-dictionary
application, for example, is org.gnome.Dictionary
. For the sake of this tutorial we will use the org.linuxconfig.FFmpeg
ID to build our flatpak. Inside our project directory, we create the org.linuxconfig.FFmpeg.yml
file, and start reporting the ID of the application as the value of the app-id
parameter:
app-id: org.linuxconfig.FFmpeg
After the application ID, we should specify the runtime
and runtime-version
used by the application. What is it? A runtime is basically the “environment” inside which the application will run, and contains a set of essential libraries and services. There are currently 3 available runtimes:
- Freedesktop
- GNOME
- KDE
The first one contains a set of essential libraries and services, the other two are based on it, and expands it with a set of utilities and libraries for the specific environments they represent.
What of those we should use for our example? Since the application we are trying to build and distribute via flatpak (ffmpeg) has no desktop-environment specific requirements, we can avoid using the GNOME or KDE runtimes and just use org.freedesktop.Platform
. There are usually many versions of a runtime available. In this case we will use the 21.08
version of the freedesktop one. Inside the manifest file, the runtime version is specified via the runtime-version
parameter:
app-id: org.linuxconfig.FFmpeg runtime: org.freedesktop.Platform runtime-version: '21.08'
After the runtime we must also specify its matching SDK. What is an SDK? Every runtime we saw above has a matching SDK, which contains everything that is contained in the environment, and, in addition, development tools and package headers. In our case we will use the org.freedesktop.Sdk
SDK:
app-id: org.linuxconfig.FFmpeg runtime: org.freedesktop.Platform runtime-version: '21.08' sdk: org.freedesktop.Sdk
The specified runtime and sdk are not be installed automatically, we have to do it manually. To install them only for our user, from the flathub
repository, we use the following command:
$ flatpak install flathub --user org.feedesktop.Platform.ffmpeg-full//21.08 org.freedesktop.Sdk//21.08
After specifying the app-id
, the runtime
, runtime-version
and the sdk
, we should provide the name of the main binary of the application. We do it via the command
parameter:
app-id: org.linuxconfig.FFmpeg runtime: org.freedesktop.Platform runtime-version: '21.08' sdk: org.freedesktop.Sdk command: ffmpeg
The app modules
Another very important thing we have do specify inside the manifest file is the list of the modules which should be built. The most important module is the one dedicated to the application itself (ffmpeg in this case), the (eventual) others are dedicated to its dependencies. Modules are listed under the
modules
parameter of the manifest file:
app-id: org.linuxconfig.FFmpeg runtime: org.freedesktop.Platform runtime-version: '21.08' sdk: org.freedesktop.Sdk modules: - name: ffmpeg sources: - type: archive url: https://www.ffmpeg.org/releases/ffmpeg-4.4.1.tar.xz sha256: eadbad9e9ab30b25f5520fbfde99fae4a92a1ae3c0257a8d68569a4651e30e02 config-opts: - --enable-gpl - --enable-libmp3lame - --enable-libopus - --enable-libvpx - --enable-libx264 - --disable-static - --enable-shared - --disable-doc
Let’s analyze what we added in the manifest under the modules
section. First of all, we specified the name of the module, ffmpeg
. We than added the sources
dictionary, where we specified various parameters. First of all the type
of the source, which, can be one of the following:
- archive (we use this for sources in tar archives)
- git (to clone a git repository)
- file (for local files)
- dir (for local directories)
- script (array of shell commands)
- shell (array of shell commands run during source extraction)
- patch
- extra-data (extra data to be downloaded at install time)
In our case we used archive
as the source type, since we want to download the archive containing the ffmpeg source code. With the url
key we provided the URL of said archive, and with the sha256
parameter, the checksum which is used to verify it (the complete list of parameters which can be used for a source type is available here. We than specified a list of config-opts
, which are the ones we would pass to the ./configure
script when building the application manually.
Adding the sandbox permissions
Flatpak applications run in a sandbox, isolated from the main system, and are designed to have the least possible access to the host. If the application we are packaging needs specific permissions, we need to specify them inside the manifest file. In our case, for example, the application needs to read and write files to the host filesystem. Permissions are specified as a list, under the finish-args
parameter:
app-id: org.linuxconfig.FFmpeg runtime: org.freedesktop.Platform runtime-version: '21.08' sdk: org.freedesktop.Sdk modules: - name: ffmpeg sources: - type: archive url: https://www.ffmpeg.org/releases/ffmpeg-4.4.1.tar.xz sha256: eadbad9e9ab30b25f5520fbfde99fae4a92a1ae3c0257a8d68569a4651e30e02 config-opts: - --enable-gpl - --enable-libmp3lame - --enable-libopus - --enable-libvpx - --enable-libx264 - --disable-static - --enable-shared - --disable-doc finish-args: - --filesystem=home:rw
In this case we used the --filesystem=home:rw
permissions: this grants the packaged application full access (read and write) to files inside our home directory. This could be too much, but will be ok for the sake of this tutorial. For a comprehensive list of the available permissions that can be specified inside this section, you can take a look at the dedicated page of the official documentation. The principle, however, is simple: give an application the least possible privileges.
Building the application
At this point, we theoretically have everything we need inside the manifest to build the flatpak. We open a terminal inside the directory where the manifest file is, and we run the following command:
$ flatpak-builder build org.linuxconfig.Ffmpeg.yml
The flatpak-builder
command takes the directory in which the build should happen as first argument, and the manifest of the application as second. If we launch the command with our current manifest, however, we are notified of an error:
ERROR: libx264 not found
Why this happened? Since we specified the --enable-libx264
configure option for ffmpeg inside the manifest, we should also add a module to build the library which is needed by ffmpeg. Let’s do this. Our manifest becomes:
app-id: org.linuxconfig.FFmpeg runtime: org.freedesktop.Platform runtime-version: '21.08' sdk: org.freedesktop.Sdk modules: - name: x264 sources: - type: git url: https://code.videolan.org/videolan/x264.git config-opts: - --enable-shared - name: ffmpeg sources: - type: archive url: https://www.ffmpeg.org/releases/ffmpeg-4.4.1.tar.xz sha256: eadbad9e9ab30b25f5520fbfde99fae4a92a1ae3c0257a8d68569a4651e30e02 config-opts: - --enable-gpl - --enable-libmp3lame - --enable-libopus - --enable-libvpx - --enable-libx264 - --disable-static - --enable-shared - --disable-doc finish-args: - --filesystem=home:rw
In this case, to clone the repository containing the x264 sources, we specified git
as the sources type, and provided the url
of the repository. Let’s try to build the application again. This time we add the --force-clean
option to the command, to clean the build directory which already contains stuff (an error would be generated otherwise):
$ flatpak-builder build org.linuxconfig.FFmpeg.yml --force-clean
This time the build process should be completed successfully.
Installing and running the application
Once the application is built we can install it. All we have to do is to run the following command:
$ flatpak-builder --user --install build --force-clean org.linuxconfig.FFmpeg.yml
After the installation is performed we can test the application works as intended. Just as an example we can try to convert a flac music file to the vorbis opus format. Here is what we would run:
$ flatpak run org.linuxconfig.FFmpeg \ -i /home/egdoc/bk/Music/ripped/ac_dc/highway_to_hell/01_highway_to_hell.flac \ -acodec libopus \ -b:a 192K \ 01_highway_to_hell.opus
With the command above we converted the flac file /home/egdoc/bk/Music/ripped/ac_dc/highway_to_hell/01_highway_to_hell.flac
to opus (-acodec libopus
) with a variable bitrate of 192K (-b:a 192K
) and saved it as 01_highway_to_hell.opus
. All should have worked correctly!
Conclusions
The flatpak technology provides a universal method of distributing applications packaged with all their needed dependencies. In this tutorial we saw how to create a flatpak package for an application (ffmpeg): we saw how to install the needed software on the most commonly used Linux distributions, how to create and populate the “manifest” file with all the needed parameters (consult the flatpak-manifest manual for the complete list of parameters which can be used inside a manifest), and finally how to build, install and run the application.
Related Linux Tutorials:
- An Introduction to Linux Automation, Tools and Techniques
- How to Create and Publish Flatpak Packages
- Setting Up a Flatpak Remote Repository to Make Installing…
- How to Create a Flatpak Application from Scratch
- How to work with the Woocommerce REST API with Python
- Mint 20: Better Than Ubuntu and Microsoft Windows?
- Mastering Bash Script Loops
- An Introduction to Flatpak App Bundles
- How to rebuild a package using the Arch Linux Build System
- How to set kernel boot parameters on Linux