location /guacamole/ { proxy_pass http://localhost:8090/guacamole/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;
}
location /guacamole/ { proxy_pass http://localhost:8090/guacamole/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;
}
location /guacamole/ { proxy_pass http://localhost:8090/guacamole/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;
}
Lesson: On headless mini PCs, just buy the HDMI dummy plug.
It costs less than the time you'll spend on Xvfb configs.
Lesson: On headless mini PCs, just buy the HDMI dummy plug.
It costs less than the time you'll spend on Xvfb configs.
Lesson: On headless mini PCs, just buy the HDMI dummy plug.
It costs less than the time you'll spend on Xvfb configs.
[Unit]
Description=x11vnc VNC server
After=graphical.target network.target [Service]
Type=simple
ExecStart=/usr/bin/x11vnc -display :0 -auth /run/user/1000/gdm/Xauthority \ -nopw -loop -noxdamage -repeat -rfbport 5900 -shared -forever
Restart=on-failure
RestartSec=5s
User=your-username [Install]
WantedBy=multi-user.target
[Unit]
Description=x11vnc VNC server
After=graphical.target network.target [Service]
Type=simple
ExecStart=/usr/bin/x11vnc -display :0 -auth /run/user/1000/gdm/Xauthority \ -nopw -loop -noxdamage -repeat -rfbport 5900 -shared -forever
Restart=on-failure
RestartSec=5s
User=your-username [Install]
WantedBy=multi-user.target
[Unit]
Description=x11vnc VNC server
After=graphical.target network.target [Service]
Type=simple
ExecStart=/usr/bin/x11vnc -display :0 -auth /run/user/1000/gdm/Xauthority \ -nopw -loop -noxdamage -repeat -rfbport 5900 -shared -forever
Restart=on-failure
RestartSec=5s
User=your-username [Install]
WantedBy=multi-user.target
192.168.x.x remote.local
192.168.x.x remote.local
192.168.x.x remote.local - guacd — the daemon that speaks VNC/RDP/SSH protocols
- guacamole — the web app (Tomcat-based)
- postgres — user/connection config persistence - VNC (shared desktop) — shares the physical display (:0). This is the x11vnc connection. You see whatever is on screen in real time, shared with anyone else who connects.
- RDP (private XFCE session) — creates an independent XFCE desktop session via xrdp. This is isolated per-user, doesn't share or disturb the physical display. Good for headless work.
- SSH — terminal-only, fast, for when I just need a shell. - Boot with a monitor plugged in, or plug in after boot — Xorg starts normally against real hardware
- Then unplug the monitor. x11vnc keeps the display alive
- On the next cold headless boot, you need the monitor briefly again - Skip VNC entirely if you don't need the physical display. RDP via xrdp is cleaner — isolated sessions, no headless display drama.
- Buy the dummy plug before you need it. Seriously.
- Guacamole's Docker networking needs attention. The guacd container needs to reach the host's VNC/RDP ports. Either use network_mode: host for guacd, or explicitly map the host's loopback ports. The default bridge mode has the guacd container connecting to 172.17.0.1 (Docker host), not 127.0.0.1 — easy to mix up.
- Postgres init scripts are fiddly. Guacamole needs its schema initialized before first run. The official image has an initdb.d mechanism but it only fires on first volume creation. If you delete and recreate the volume (or the container), you'll need to re-init.