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 Concept | Docker Equivalent |
|---|
--filesystem= | -v volume mount |
--env= | -e environment variable |
flatpak override | docker-compose override |
/app | Image 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
|
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:
| Parameter | Purpose | Docker Analogy |
|---|
--env=QT_STYLE_OVERRIDE=kvantum | Inject environment variable | -e VAR=value |
--filesystem=xdg-config/Kvantum:ro | Read-only mount theme config dir | -v /path:/path:ro |
--user | User-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
|
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
| Scenario | Flatpak | Docker/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
| Concept | Flatpak Practice | Container Connection |
|---|
| Namespace isolation | Process/filesystem/network isolation | Docker/K8s core mechanism |
| Filesystem mount | --filesystem= | Volume Mount |
| Env var injection | --env= | ConfigMap/Secret |
| Least privilege | Portal mechanism | RBAC / SecurityContext |
Core insight: A seemingly simple theme configuration problem reveals complete containerization isolation concepts. Understanding Flatpak’s sandbox mechanism helps understand Docker/K8s fundamentals.