SPICE Server Setup¶
Configure SPICE display and agents in KVM/QEMU virtual machines.
QEMU Command Line¶
Basic SPICE Configuration¶
qemu-system-x86_64 \
-spice port=5900,disable-ticketing=on \
-device virtio-serial-pci \
-chardev spicevmc,id=vdagent,debug=0,name=vdagent \
-device virtserialport,chardev=vdagent,name=com.redhat.spice.0 \
...
With TLS¶
libvirt/virsh Configuration¶
Enable SPICE Display¶
Edit VM with virsh edit vm-name:
<graphics type='spice' autoport='yes' listen='127.0.0.1'>
<listen type='address' address='127.0.0.1'/>
<image compression='auto_glz'/>
<streaming mode='filter'/>
<zlib compression='auto'/>
</graphics>
SPICE with VNC Fallback¶
You can have both:
<graphics type='spice' autoport='yes'>
<listen type='address' address='0.0.0.0'/>
</graphics>
<graphics type='vnc' port='-1' autoport='yes'>
<listen type='address' address='0.0.0.0'/>
</graphics>
QXL Video Device¶
For best SPICE performance, use QXL video:
<video>
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</video>
Multiple monitors:
<video>
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='4' primary='yes'/>
</video>
SPICE Agent Channel¶
Required for clipboard, resolution changes:
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
USB Redirection¶
Enable USB passthrough via SPICE:
<controller type='usb' index='0' model='qemu-xhci'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</controller>
<redirdev bus='usb' type='spicevmc'>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
</redirdev>
Guest Agent Installation¶
Linux Guest¶
Windows Guest¶
- Download spice-guest-tools
- Run installer in Windows VM
- Reboot
Includes: - QXL display driver - SPICE agent - VirtIO serial driver
Verify Agent Running¶
Linux:
Windows: - Services > "SPICE Agent"
Complete libvirt Example¶
Full VM configuration with SPICE:
<domain type='kvm'>
<name>linux-spice-vm</name>
<memory unit='GiB'>4</memory>
<vcpu>4</vcpu>
<os>
<type arch='x86_64' machine='q35'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
</features>
<devices>
<!-- SPICE display -->
<graphics type='spice' autoport='yes'>
<listen type='address' address='0.0.0.0'/>
<image compression='auto_glz'/>
<streaming mode='filter'/>
</graphics>
<!-- QXL video -->
<video>
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1'/>
</video>
<!-- Virtio serial for agent -->
<controller type='virtio-serial' index='0'/>
<!-- SPICE agent channel -->
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
</channel>
<!-- USB controller for redirection -->
<controller type='usb' model='qemu-xhci'/>
<!-- USB redirection channels -->
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<!-- Audio -->
<sound model='ich9'>
<codec type='micro'/>
</sound>
<audio id='1' type='spice'/>
<!-- Other devices... -->
</devices>
</domain>
Network Binding¶
Localhost Only (Secure)¶
<graphics type='spice' autoport='yes' listen='127.0.0.1'>
<listen type='address' address='127.0.0.1'/>
</graphics>
Access via SSH tunnel or Tailscale with port forward.
All Interfaces¶
<graphics type='spice' port='5900' autoport='no' listen='0.0.0.0'>
<listen type='address' address='0.0.0.0'/>
</graphics>
Security
When binding to all interfaces, ensure firewall is configured.
With Password¶
<graphics type='spice' autoport='yes' passwd='your-password'>
<listen type='address' address='0.0.0.0'/>
</graphics>
Performance Tuning¶
Compression Settings¶
<graphics type='spice' autoport='yes'>
<!-- Image compression -->
<image compression='auto_glz'/> <!-- auto_glz, auto_lz, quic, glz, lz, off -->
<!-- Video streaming detection -->
<streaming mode='filter'/> <!-- filter, all, off -->
<!-- Zlib compression for data -->
<zlib compression='auto'/> <!-- auto, never, always -->
<!-- JPEG for lossy compression -->
<jpeg compression='auto'/> <!-- auto, never, always -->
<!-- Playback compression -->
<playback compression='on'/> <!-- on, off -->
</graphics>
For LAN (High Bandwidth)¶
For WAN (Low Bandwidth)¶
Audio Configuration¶
Enable SPICE Audio¶
PulseAudio Backend¶
USB Redirection¶
Enable in VM¶
<!-- USB 3.0 controller -->
<controller type='usb' index='0' model='qemu-xhci'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</controller>
<!-- Redirection channels (one per device) -->
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
<redirdev bus='usb' type='spicevmc'/>
Client-side Usage¶
In virt-viewer/remote-viewer: 1. File > USB device selection 2. Check devices to redirect 3. Devices appear in guest
Finding SPICE Port¶
# Get SPICE port for a VM
virsh domdisplay vm-name
# Output: spice://localhost:5900
# Or via dumpxml
virsh dumpxml vm-name | grep -A5 "graphics type='spice'"
Troubleshooting¶
No Display¶
- Check SPICE is configured:
virsh dumpxml vm | grep spice - Verify port:
ss -tlnp | grep qemu - Check QXL driver in guest
Agent Not Working¶
- Verify channel in VM config
- Check agent running in guest
- Restart agent:
systemctl restart spice-vdagent
Poor Performance¶
- Enable QXL driver in guest
- Adjust compression settings
- Check network bandwidth
- Verify video RAM settings
USB Redirection Fails¶
- Check
usbredirpackage installed on host - Verify USB controller in VM
- Check device permissions on host
virt-manager Setup¶
Using GUI¶
- Open VM settings
- Add Hardware > Graphics
- Type: SPICE server
- Address: All interfaces (or localhost)
- Apply
Enable USB Redirection¶
- Add Hardware > USB Redirector
- Add multiple for more devices
- Apply
Add QXL Video¶
- Remove existing video device
- Add Hardware > Video
- Model: QXL
- Configure RAM amounts
- Apply