Contents

Linux Desktop Customization: Flatpak Theme Integration and Container Isolation Principles

A simple requirement: make a Flatpak-installed PDF reader support dark mode. But solving it involves Flatpak’s sandbox mechanism, filesystem mounts, and environment variable injection — concepts highly similar to Docker/K8s containerization.

1. Problem Background

After installing Okular (PDF reader) via Flatpak on Linux desktop, it doesn’t follow the system dark theme. Reason: Flatpak apps run in a sandbox, isolated from the host system.

1.1 Flatpak Sandbox Mechanism

┌─────────────────────────────────────────────────────────┐
│                    Host System                          │
│  /home/user/.config/                                    │
│  /usr/share/themes/                                     │
│  System GTK/Qt Theme                                    │
└─────────────────────────────────────────────────────────┘
                            │
                    ❌ Isolated by default
                            │
┌─────────────────────────────────────────────────────────┐
│                Flatpak Sandbox                          │
│  /app/                    (read-only application)       │
│  ~/.var/app/org.kde.okular/  (app private data)         │
│  Limited privileges and filesystem access               │
└─────────────────────────────────────────────────────────┘

This matches Docker container isolation philosophy: default minimal permissions, grant on demand.

1.2 Docker Analogy

Flatpak ConceptDocker Equivalent
--filesystem=-v volume mount
--env=-e environment variable
flatpak overridedocker-compose override
/appImage read-only layer
~/.var/app/<id>Container writable layer

2. Solution

2.1 Install Kvantum Theme Engine

Kvantum is a Qt theme engine, install on host system:

# Fedora
sudo dnf install kvantum

# Ubuntu/Debian
sudo apt install qt5-style-kvantum

# Arch
sudo pacman -S kvantum

2.2 Configure Dark Theme

# Launch theme manager
kvantummanager

Select KvDark or another dark theme and apply.

2.3 Key: Grant Flatpak Access to Theme Config

# Temporary test (single run)
flatpak run \
  --env=QT_STYLE_OVERRIDE=kvantum \
  --filesystem=xdg-config/Kvantum:ro \
  org.kde.okular

# Permanent
flatpak override \
  --user \
  --env=QT_STYLE_OVERRIDE=kvantum \
  --filesystem=xdg-config/Kvantum:ro \
  org.kde.okular

Command breakdown:

ParameterPurposeDocker Analogy
--env=QT_STYLE_OVERRIDE=kvantumInject environment variable-e VAR=value
--filesystem=xdg-config/Kvantum:roRead-only mount theme config dir-v /path:/path:ro
--userUser-level config (not global)~/.docker/config.json

2.4 Verify Mount

# View app permissions
flatpak info --show-permissions org.kde.okular

# View override config
cat ~/.local/share/flatpak/overrides/org.kde.okular

3. Deep Dive: Flatpak Sandbox

3.1 Namespace Isolation

Flatpak uses Linux kernel namespaces for isolation:

# View Flatpak process namespaces
ls -la /proc/$(pgrep okular)/ns/

# Output
lrwxrwxrwx 1 user user 0 Dec 11 01:00 mnt -> 'mnt:[4026532xxx]'
lrwxrwxrwx 1 user user 0 Dec 11 01:00 net -> 'net:[4026532xxx]'
lrwxrwxrwx 1 user user 0 Dec 11 01:00 pid -> 'pid:[4026532xxx]'

This is the core of container technology! Docker, K8s Pods use the same kernel mechanisms.

3.2 Filesystem Isolation

# Enter Flatpak app's sandbox perspective
flatpak run --command=sh org.kde.okular

# View filesystem inside sandbox
$ ls /
app  dev  etc  home  proc  run  sys  tmp  usr  var

# /app is the application (read-only)
$ ls /app
bin  lib  share

# User data at ~/.var/app/
$ ls ~/.var/app/org.kde.okular/
cache  config  data

3.3 Portal Mechanism

For accessing host resources (opening files, printing), Flatpak uses Portals:

App → Portal (DBus) → Host System

Example:
okular requests to open file
  → Calls host file picker via Portal
  → User selects file
  → Portal grants that file to okular

This is least privilege principle in practice: apps can’t directly access all files, only those explicitly authorized by user.

4. Batch Configuration

4.1 Global Theme Config

# Set theme for all Flatpak Qt apps
flatpak override --user \
  --env=QT_STYLE_OVERRIDE=kvantum \
  --filesystem=xdg-config/Kvantum:ro

# View global config
cat ~/.local/share/flatpak/overrides/global

4.2 Config File Format

# ~/.local/share/flatpak/overrides/org.kde.okular
[Context]
filesystems=xdg-config/Kvantum:ro

[Environment]
QT_STYLE_OVERRIDE=kvantum

4.3 Reset Configuration

# Remove specific app override
flatpak override --user --reset org.kde.okular

# Remove global override
rm ~/.local/share/flatpak/overrides/global

5. Connection to Container Configuration

5.1 Configuration Injection Patterns

ScenarioFlatpakDocker/K8s
Env vars--env=KEY=VALUE-e KEY=VALUE / env:
Config file mount--filesystem=path:ro-v /path:/path:ro / volumeMounts:
Persistent data~/.var/app/<id>Named volume / PVC
Network access--share=network--network / hostNetwork:

5.2 Least Privilege Principle

# K8s Pod security context - same concept
securityContext:
  readOnlyRootFilesystem: true
  runAsNonRoot: true
  capabilities:
    drop: ["ALL"]

Flatpak’s sandbox, Docker’s seccomp, K8s PodSecurityPolicy — all practice default deny, explicit grant.

6. Troubleshooting

6.1 View App Actual Permissions

flatpak info --show-permissions org.kde.okular

6.2 View Runtime Environment

flatpak run --command=env org.kde.okular | grep -E "QT_|XDG_"

6.3 Check File Accessibility

flatpak run --command=ls org.kde.okular ~/.config/Kvantum/

7. Summary

ConceptFlatpak PracticeContainer Connection
Namespace isolationProcess/filesystem/network isolationDocker/K8s core mechanism
Filesystem mount--filesystem=Volume Mount
Env var injection--env=ConfigMap/Secret
Least privilegePortal mechanismRBAC / SecurityContext

Core insight: A seemingly simple theme configuration problem reveals complete containerization isolation concepts. Understanding Flatpak’s sandbox mechanism helps understand Docker/K8s fundamentals.