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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
┌─────────────────────────────────────────────────────────┐
                    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:

1
2
3
4
5
6
7
8
# Fedora
sudo dnf install kvantum

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

# Arch
sudo pacman -S kvantum

2.2 Configure Dark Theme

1
2
# Launch theme manager
kvantummanager

Select KvDark or another dark theme and apply.

2.3 Key: Grant Flatpak Access to Theme Config

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 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

1
2
3
4
5
# 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:

1
2
3
4
5
6
7
# 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 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:

1
2
3
4
5
6
7
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

1
2
3
4
5
6
7
# 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

1
2
3
4
5
6
# ~/.local/share/flatpak/overrides/org.kde.okular
[Context]
filesystems=xdg-config/Kvantum:ro

[Environment]
QT_STYLE_OVERRIDE=kvantum

4.3 Reset Configuration

1
2
3
4
5
# 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

1
2
3
4
5
6
# 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

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

6.2 View Runtime Environment

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

6.3 Check File Accessibility

1
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.