Here the solution I reach with a bit of help of deepseek
| Package | Purpose | Version |
|---------|---------|---------|
| md.obsidian.Obsidian | Markdown knowledge base (flatpak) | 1.12.7 |
| xorg-server-xvfb | Virtual X11 for headless service | repo |
## Installation
```bash
flatpak install flathub md.obsidian.Obsidian
sudo pacman -S xorg-server-xvfb
```
## Components
### 1. Desktop Entry
`~/.local/share/applications/md.obsidian.Obsidian.desktop` — custom override for the app grid/menu (Fuzzel):
```ini
[Desktop Entry]
Name=Obsidian
Comment=Obsidian notes
Exec=flatpak run md.obsidian.Obsidian %U
Terminal=false
Type=Application
Icon=md.obsidian.Obsidian
StartupWMClass=obsidian
Categories=Office;Utility;
```
The system flatpak desktop file was inaccessible because `XDG_DATA_DIRS` didn’t include the flatpak export path on Hyprland.
### 2. CLI (command-line interface)
The flatpak ships a companion CLI binary (`~/.local/bin/obsidian`) that communicates with a running Obsidian instance via a Unix socket.
**Problem:** The flatpak sandbox creates the socket at:
```
/run/user/UID/.flatpak/md.obsidian.Obsidian/xdg-run/.obsidian-cli.sock
```
But the CLI binary looks for it at:
```
/run/user/UID/.obsidian-cli.sock
```
**Fix:** A zsh function in `~/.zshrc` bridges the gap with a symlink:
```zsh
# obsidian cli fix flatpak sandbox
unalias obsidian 2>/dev/null
obsidian() {
local sock=“/run/user/$(id -u)/.flatpak/md.obsidian.Obsidian/xdg-run/.obsidian-cli.sock”
ln -sf “$sock” “/run/user/$(id -u)/.obsidian-cli.sock” 2>/dev/null
if [ ! -S “$sock” ]; then
echo “error: Obsidian is not running or CLI not enabled.” >&2
echo " Open Obsidian and go to Settings → Core Plugins → enable ‘Open URI’ or ‘CLI’." >&2
return 1
fi
command obsidian “$@”
}
```
The function:
1. Creates/refreshes the symlink from sandbox path → expected path
2. Verifies the socket exists (Obsidian is running with CLI enabled)
3. Delegates to the real `obsidian` binary
**Prerequisite:** Obsidian’s CLI must be enabled in the app. Go to Settings → search “CLI” or “URI” and enable it.
### 3. Headless systemd service
Runs Obsidian without a visible window via `xvfb-run`, keeping the CLI always available.
**Service:** `~/.config/systemd/user/obsidian-headless.service`
```ini
[Unit]
Description=Obsidian (headless, for CLI)
After=graphical-session.target
PartOf=graphical-session.target
[Service]
Type=simple
ExecStart=/usr/bin/xvfb-run -a -s “-screen 0 1920x1080x24 -ac” /usr/bin/flatpak run md.obsidian.Obsidian
Restart=on-failure
RestartSec=5
[Install]
WantedBy=graphical-session.target
```
`xvfb-run` creates a virtual X11 framebuffer (`Xvfb :99`) that satisfies Electron’s display requirement, so Obsidian initializes fully and creates the CLI socket — but no window appears on the desktop.
**How it works:**
- Flatpak Obsidian has `sockets=x11` permission
- `xvfb-run -a` auto-assigns a free display number
- `-screen 0 1920x1080x24` creates a 24-bit color virtual screen
- `-ac` disables X11 access control (required for flatpak sandbox)
**Management:**
```bash
# Enable auto-start on login
systemctl --user enable obsidian-headless.service
# Start/stop manually
systemctl --user start obsidian-headless
systemctl --user stop obsidian-headless
# Check status
systemctl --user status obsidian-headless
# View logs
journalctl --user -u obsidian-headless -f
```
**Conflict:** Only one Obsidian instance can run at a time. Stop the headless service before opening the GUI (`systemctl --user stop obsidian-headless`), or the GUI will fail to start.