Add on-demand Xvfb + x11vnc socket activation
This commit is contained in:
@@ -0,0 +1,233 @@
|
|||||||
|
# Xvfb + x11vnc On-Demand Setup
|
||||||
|
|
||||||
|
Run X11 server **only when needed** — zero overhead when idle.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
```
|
||||||
|
No one using X11
|
||||||
|
↓
|
||||||
|
Xvfb is STOPPED (no resources)
|
||||||
|
|
||||||
|
VNC client connects (or app needs X11)
|
||||||
|
↓
|
||||||
|
Systemd socket activation
|
||||||
|
↓
|
||||||
|
Xvfb starts automatically
|
||||||
|
↓
|
||||||
|
x11vnc connects to it
|
||||||
|
↓
|
||||||
|
You can use X11 apps or remote desktop
|
||||||
|
|
||||||
|
When done / no activity for N minutes
|
||||||
|
↓
|
||||||
|
Xvfb stops (auto)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### 1. Install Packages
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y x11vnc xvfb
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Install Systemd Services
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo cp /workspace/second-brain/xvfb.socket /etc/systemd/system/
|
||||||
|
sudo cp /workspace/second-brain/xvfb.service /etc/systemd/system/
|
||||||
|
sudo cp /workspace/second-brain/x11vnc.service /etc/systemd/system/
|
||||||
|
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Enable Socket Activation (for Xvfb)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl enable xvfb.socket
|
||||||
|
sudo systemctl start xvfb.socket
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Enable VNC Service
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl enable x11vnc.service
|
||||||
|
# Don't start yet — it will start when xvfb.socket gets activity
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Verify Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Socket should be listening
|
||||||
|
sudo systemctl status xvfb.socket
|
||||||
|
|
||||||
|
# Services should be inactive initially
|
||||||
|
sudo systemctl status xvfb.service
|
||||||
|
sudo systemctl status x11vnc.service
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Start On-Demand
|
||||||
|
|
||||||
|
**Option A: VNC Connection Triggers It**
|
||||||
|
```bash
|
||||||
|
# From another machine, connect to VNC
|
||||||
|
vnc-viewer 192.168.x.x:5900
|
||||||
|
# → x11vnc and Xvfb start automatically
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option B: Manual Start**
|
||||||
|
```bash
|
||||||
|
# If you want to start without VNC connection
|
||||||
|
sudo systemctl start xvfb.service
|
||||||
|
sudo systemctl start x11vnc.service
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option C: Any App Needing X11**
|
||||||
|
```bash
|
||||||
|
# Any X11 app trying to connect to :99 will trigger it
|
||||||
|
DISPLAY=:99 firefox &
|
||||||
|
# → Xvfb starts automatically
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitoring
|
||||||
|
|
||||||
|
### Watch Activation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# See when services start/stop
|
||||||
|
sudo journalctl -fu xvfb
|
||||||
|
sudo journalctl -fu x11vnc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Check Current Status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Is Xvfb running?
|
||||||
|
ps aux | grep Xvfb
|
||||||
|
|
||||||
|
# Is VNC listening?
|
||||||
|
netstat -tlnp | grep 5900
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Change VNC Port
|
||||||
|
|
||||||
|
Edit `/etc/systemd/system/x11vnc.service`:
|
||||||
|
```
|
||||||
|
ExecStart=/usr/bin/x11vnc -display :99 -forever -nopw -rfbport 5901
|
||||||
|
```
|
||||||
|
|
||||||
|
Then reload:
|
||||||
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl restart x11vnc.service
|
||||||
|
```
|
||||||
|
|
||||||
|
### Allow Remote Connections
|
||||||
|
|
||||||
|
Edit `/etc/systemd/system/x11vnc.service`:
|
||||||
|
```
|
||||||
|
# Change -localhost to -listen 0.0.0.0
|
||||||
|
ExecStart=/usr/bin/x11vnc -display :99 -forever -nopw -listen 0.0.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add VNC Password
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate password
|
||||||
|
x11vnc -storepasswd
|
||||||
|
|
||||||
|
# Update service to use it
|
||||||
|
ExecStart=/usr/bin/x11vnc -display :99 -forever -listen localhost -usepw
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adjust Display Resolution
|
||||||
|
|
||||||
|
Edit `/etc/systemd/system/xvfb.service`:
|
||||||
|
```
|
||||||
|
# Change 1920x1080x24 to your desired resolution
|
||||||
|
ExecStart=/usr/bin/Xvfb :99 -screen 0 2560x1440x24
|
||||||
|
```
|
||||||
|
|
||||||
|
## Auto-Stop (Inactivity)
|
||||||
|
|
||||||
|
To stop Xvfb after no activity (optional):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install x-idle-logout if available
|
||||||
|
# Or use a watchdog script
|
||||||
|
|
||||||
|
cat > /usr/local/bin/xvfb-watchdog.sh << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
# Stop Xvfb after 30 minutes of inactivity
|
||||||
|
while true; do
|
||||||
|
if ! pgrep -x Xvfb > /dev/null; then
|
||||||
|
sleep 300
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if anyone is using the display
|
||||||
|
xset -display :99 -q 2>/dev/null && IDLE=$(xset -display :99 q | grep "DPMS" | grep -oP '\d+m \d+s' | head -1)
|
||||||
|
|
||||||
|
if [ -z "$IDLE" ]; then
|
||||||
|
# 30 minutes of inactivity
|
||||||
|
sudo systemctl stop xvfb.service
|
||||||
|
echo "Stopped Xvfb due to inactivity"
|
||||||
|
sleep 600
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 60
|
||||||
|
done
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x /usr/local/bin/xvfb-watchdog.sh
|
||||||
|
|
||||||
|
# Add to systemd (optional)
|
||||||
|
sudo systemctl enable xvfb-watchdog.service
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Xvfb won't start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo journalctl -u xvfb.service -n 20
|
||||||
|
# Look for errors, usually permission or display binding issues
|
||||||
|
```
|
||||||
|
|
||||||
|
### Can't connect to VNC
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check if x11vnc is running
|
||||||
|
ps aux | grep x11vnc
|
||||||
|
|
||||||
|
# Check if port 5900 is listening
|
||||||
|
sudo lsof -i :5900
|
||||||
|
|
||||||
|
# Check logs
|
||||||
|
sudo journalctl -u x11vnc.service -n 20
|
||||||
|
```
|
||||||
|
|
||||||
|
### Permissions error
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Make sure x11vnc can access the display
|
||||||
|
sudo chown -R intense:intense /tmp/.X11-unix/
|
||||||
|
sudo chmod 1777 /tmp/.X11-unix/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Idle overhead:** <1MB RAM (Xvfb stopped)
|
||||||
|
- **Running Xvfb:** ~100-200MB RAM
|
||||||
|
- **With VNC client:** +50-100MB
|
||||||
|
- **CPU:** Only when rendering, otherwise idle
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Created: 2026-04-26
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=X11 VNC Server (On-Demand)
|
||||||
|
After=network.target xvfb.service
|
||||||
|
Requires=xvfb.service
|
||||||
|
Documentation=http://www.karlrunge.com/x11vnc/
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=intense
|
||||||
|
Environment="DISPLAY=:99"
|
||||||
|
|
||||||
|
# Start x11vnc connected to Xvfb display :99
|
||||||
|
# -forever: keep running
|
||||||
|
# -nopw: no password required (can change)
|
||||||
|
# -localhost: only local connections (can change to 0.0.0.0 for remote)
|
||||||
|
ExecStart=/usr/bin/x11vnc -display :99 -forever -nopw -localhost -listen localhost
|
||||||
|
|
||||||
|
# Wait for display to be ready
|
||||||
|
ExecStartPost=/bin/bash -c 'sleep 2 && echo "✓ VNC ready on :5900"'
|
||||||
|
|
||||||
|
# Restart on failure
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
MemoryLimit=256M
|
||||||
|
CPUQuota=30%
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
SyslogIdentifier=x11vnc
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=X Virtual Framebuffer (On-Demand)
|
||||||
|
After=network.target
|
||||||
|
Documentation=https://www.x.org/wiki/
|
||||||
|
|
||||||
|
# Socket activation: starts only when x11vnc tries to connect
|
||||||
|
Requires=xvfb.socket
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=intense
|
||||||
|
Environment="DISPLAY=:99"
|
||||||
|
ExecStart=/usr/bin/Xvfb :99 -screen 0 1920x1080x24 -listen tcp
|
||||||
|
|
||||||
|
# Restart on failure
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
MemoryLimit=512M
|
||||||
|
CPUQuota=50%
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
SyslogIdentifier=xvfb
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=X Virtual Framebuffer Socket (Activation)
|
||||||
|
Documentation=https://www.x.org/wiki/
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream=6000
|
||||||
|
ListenUnix=/tmp/.X11-unix/X99
|
||||||
|
|
||||||
|
# Accept incoming connections and start xvfb.service
|
||||||
|
Accept=no
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=sockets.target
|
||||||
Reference in New Issue
Block a user