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.