Quick answer: Set SDL_VIDEODRIVER=dummy before importing pygame. Or skip pygame.init() and only initialize the modules you need (mixer, font). Headless CI and dedicated servers don’t need a display.
CI runs your pygame-based unit tests. Failure: “No available video device.” SDL tries to open a window on a headless container.
The Symptom
pygame.init() or pygame.display.set_mode() raises pygame.error on a server, in CI, or in Docker. Same code works on a developer machine with a desktop.
The Fix
Pattern 1: SDL dummy video driver.
import os
os.environ["SDL_VIDEODRIVER"] = "dummy"
import pygame
pygame.init()
# or
pygame.mixer.init()
Set the env var BEFORE importing pygame. SDL reads it during initialization. The dummy driver pretends to have a display.
Pattern 2: CI environment.
# GitHub Actions
env:
SDL_VIDEODRIVER: dummy
# Dockerfile
ENV SDL_VIDEODRIVER=dummy
Pattern 3: Init only what you need.
import pygame
pygame.mixer.init()
pygame.font.init()
# skip display, video, joystick if not needed
Each pygame module has its own init. pygame.init() initializes everything; selective init avoids touching unavailable subsystems.
Server-Side Game Logic
For dedicated server processes that share game logic with a client, factor out everything that uses pygame.display into a separate module. The server imports the logic and skips the rendering, eliminating the need for video at all.
Verifying
Run on a headless container without DISPLAY set. With SDL_VIDEODRIVER=dummy: pygame init succeeds, tests run. Without: error before any test runs.
“Dummy driver. Selective init. Headless servers happy.”
Related Issues
For Pygame fullscreen surface lost, see fullscreen surface. For Clock.tick CPU, see tick CPU.
SDL_VIDEODRIVER=dummy. Servers run.