Packaging Tutorial

Creating a Flatpak of an application that is already packaged in Fedora involves two steps. First you need to create a module for the application. This module will be used to rebuild the application RPM and RPMs. Then you need to create a container out of the module. In the Fedora context, flatpaks are just another form of container, and are handled very similar to the Docker containers used for server applications.

Just as for packages, the instructions for building modules and containers are stored in git on https://src.fedoraproject.org and builds are coordinated by https://koji.fedoraproject.org. The flatpak for a an application can be found on https://src.fedoraproject.org in the repository flatpaks/<application>; this git repository contains two files: <application>.yaml, which defines the contents of the module, and container.yaml, which defines how the module is turned into a Flatpak container.

Setup

Install the necessary tools:

$ sudo dnf install flatpak-module-tools fedmod

Make sure that your user is in the mock group (both local module builds and local container builds use mock).

$ sudo usermod -a -G mock $USER

(You may need to log out and log back in.)

Add Fedora testing flatpak remote:

$ flatpak remote-add fedora-testing oci+https://registry.fedoraproject.org#testing

On Fedora it could be already installed, but in disabled state. To enable it run:

$ flatpak remote-modify --enable fedora-testing

And install the Fedora Flatpak Runtime if you don’t already have it installed:

$ flatpak install fedora-testing org.fedoraproject.Platform/x86_64/f37

Creating <application>.yaml and container.yaml

$ mkdir feedreader && cd feedreader
$ fedmod fetch-metadata
$ fedmod rpm2flatpak --flatpak-common --flathub=feedreader feedreader

This generates initial versions of the two files. The --flatpak-common option makes the generated module depend on the flatpak-common module. This is not the default, since flatpak-common is still a bit experimental, but is often quite useful in making your module smaller and easier to build. The --flathub=feedreader option searches Flathub for an application whose name or application ID matches feedreader, and uses the Flathub manifest to initialize container.yaml. If multiple matches are found, they are displayed, and you’ll need to re-run fedmod rpm2flatpak with a more specific search string.

First we’ll look at the module definition file:

feedreader.yaml
---
document: modulemd
version: 2
data:
  summary: RSS desktop client (1)
  description: >- (1)
    FeedReader is a modern desktop application designed to complement existing web-based
    RSS accounts. It combines all the advantages of web based services like synchronization
    across all your devices with everything you expect from a modern desktop application.
  license:
    module:
    - MIT
  dependencies:
  - buildrequires:
      flatpak-common: [f37]
      flatpak-runtime: [f37]
      platform: [f37]
    requires:
      flatpak-common: [f37]
      flatpak-runtime: [f37]
      platform: [f37]
  profiles: (2)
    default:
      rpms:
      - feedreader
  components:
    rpms:
      feedreader: (3)
        buildorder: 10
        rationale: Application package
        ref: f37 (4)
      gnome-online-accounts: (5)
        rationale: Runtime dependency
        ref: f37
      gumbo-parser: (5)
        rationale: Runtime dependency
        ref: f37
      libpeas: (5)
        rationale: Runtime dependency
        ref: f37
...
1 Source and description come from RPM metadata
2 The default profile lists RPMs to be included along with their dependencies
3 The main package for the application
4 This is the branch of the RPM in https://src.fedoraproject.org to use for this component. You can use any branch, or even point to a specific commit.
5 Further source rpms that will be rebuilt for bundling

This could be used as-is. For more complex cases, it may be necessary to add additional buildorder: keys so that the bundle dependencies build in the correct order.

Then we’ll look at the container.yaml file.

container.yaml
compose:
    modules:
    - feedreader:stable
flatpak:
    id: org.gnome.FeedReader
    branch: stable
    command: feedreader
    finish-args: |-
        --socket=pulseaudio
        --socket=x11 (1)
        --share=ipc
        --socket=wayland
        --device=dri
        --share=network
        --filesystem=xdg-run/dconf
        --filesystem=~/.config/dconf:ro
        --talk-name=ca.desrt.dconf
        --env=DCONF_USER_CONFIG_DIR=.config/dconf
        --talk-name=org.gnome.OnlineAccounts
        --own-name=org.gnome.FeedReader.ArticleView
        --talk-name=org.freedesktop.Notifications
        --talk-name=org.freedesktop.secrets
        --env=DECSYNC_DIR=.local/share/decsync
        --filesystem=~/.local/share/decsync
1 This would be better as --socket=fallback-x11 to prevents access to the Xwayland socket when running in Wayland.

The container.yaml file can also be used as is. If there is no existing build of the application on Flathub, you can omit the --flathub option to fedmod rpm2flatpak. In this case you’ll need to pick an application ID and edit container.yaml.

Doing a local build

$ flatpak-module local-build --install

This is a shortcut for three steps:

$ flatpak-module build-module
$ flatpak-module build-container --from-local
$ flatpak-module install <application>-stable-<version>.oci.tar.gz

If building the module succeeds but building the container fails, and you need to change container.yaml and try again, you can do:

$ flatpak-module build-container --from-local --install

Testing

If installation succeeded, you can now do:

$ flatpak run org.gnome.FeedReader

To try it out.

src.fedoraproject.org request

Please request a new Git repository as follows:

$ fedpkg request-repo --namespace=flatpaks <application>

Importing your module content

Once the repository has been created:

$ mv <application> <application>.old
$ fedpkg clone flatpaks/<application>
$ cd <application>
$ cp ../application.old/{<application>.yaml,container.yaml} .
$ git add <application>.yaml container.yaml
$ git commit -m "Initial import"
$ git push origin stable

Building in Koji

First build the module

$ fedpkg module-build

If that completes successfully, you can then do:

$ fedpkg flatpak-build

Testing the build

To install the latest successful build from Koji, run:

$ flatpak-module install --koji <application>:stable

Creating an update

Find the NVR of your Flatpak build - if you don’t have it in your terminal scrollback go to https://koji.fedoraproject.org/ and search in "Packages" for the application name. The build ID for the Flatpak build will be something like: myapplication-20b180601144429.2.

Go to https://bodhi.fedoraproject.org/updates/new and enter the flatpak NVR under Candidate Builds (ignore “Packages”). Enter text under “Update notes” like “Initial Flatpak of <application>”, and hit <Submit>.