Manchmal ist es hilfreich, Selenium in Python innerhalb eines Docker-Containers zu verwenden. Dabei stellen sich Fragen zu den Vorteilen dieser Methode, zur Versionskompatibilität zwischen ChromeDriver und Chromium sowie zu den technischen Feinheiten der Implementierung. In diesem Artikel werden die wichtigsten Aspekte erklärt und typische Probleme mit ihren Lösungen behandelt.
Das Ausführen von Selenium in einem Container bietet mehrere Vorteile:
🧩 Portabilität:
Die Umgebung kann leicht zwischen verschiedenen Maschinen übertragen werden, ohne Versionskonflikte oder betriebssystemspezifische Abhängigkeiten.
🧱 Isolation:
Der Selenium-Container kann unabhängig von anderen Komponenten schnell ersetzt oder aktualisiert werden.
Compose installiert sind:
docker --version && docker compose version
Hinweis: In einigen Docker-Compose-Versionen lautet der Befehl docker-compose (mit Bindestrich) anstelle von docker compose.
Wenn die Tools installiert sind, werden ihre Versionen angezeigt. Falls nicht, folge der entsprechenden Installationsanleitung.
Beim Ausführen von Selenium in Docker-Containern sollte man die Host-Architektur, Funktionsanforderungen und Performance berücksichtigen.
Die offiziellen Images selenium/standalone-* sind für AMD64 (x86_64)-Prozessoren optimiert, während die seleniarm/standalone-*-Images für ARM-Architekturen (z. B. Apple Silicon, ARM64-Server) gedacht sind.
Erstelle zunächst im Projektstamm eine Datei docker-compose.yml mit folgendem Inhalt:
version: "3"
services:
app:
build: .
restart: always
volumes:
- .:/app
depends_on:
- selenium
platform: linux/amd64
selenium:
image: selenium/standalone-chromium:latest # For AMD64
# image: seleniarm/standalone-chromium:latest # For ARM64
container_name: selenium-container
restart: unless-stopped
shm_size: 2g
ports:
- "4444:4444" # Selenium WebDriver API
- "7900:7900" # VNC Viewer
environment:
- SE_NODE_MAX_SESSIONS=1
- SE_NODE_OVERRIDE_MAX_SESSIONS=true
- SE_NODE_SESSION_TIMEOUT=300
- SE_NODE_GRID_URL=http://localhost:4444
- SE_NODE_DETECT_DRIVERS=false
Wähle das richtige Image für deine Architektur, indem du die entsprechende Zeile aktivierst.
Der Service app führt deinen Python-Code aus. Definiere dafür eine Dockerfile:
# Use a minimal Python image
FROM python:3.11-slim
# Set working directory
WORKDIR /app
# Install Python dependencies
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
# Copy project files
COPY . /app/
# Set environment variables (Chromium is in a separate container)
ENV SELENIUM_REMOTE_URL="http://selenium:4444/wd/hub"
# Run Python script
CMD ["python", "main.py"]
Diese Dockerfile verwendet ein leichtes Python-Image und installiert automatisch alle Abhängigkeiten.
Beispielskript – main.py
import time # Used to create a delay for checking browser functionality
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
# WebDriver settings
chrome_options = Options()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--disable-webrtc")
chrome_options.add_argument("--hide-scrollbars")
chrome_options.add_argument("--disable-notifications")
chrome_options.add_argument("--start-maximized")
SELENIUM_REMOTE_URL = os.getenv("SELENIUM_REMOTE_URL", "http://selenium:4444/wd/hub")
driver = webdriver.Remote(
command_executor=SELENIUM_REMOTE_URL,
options=chrome_options
)
# Open a test page
driver.get("https://www.hostman.com")
time.sleep(9999)
# Shut down WebDriver
driver.quit()
requirements.txt
attrs==25.1.0
certifi==2025.1.31
h11==0.14.0
idna==3.10
outcome==1.3.0.post0
PySocks==1.7.1
selenium==4.28.1
sniffio==1.3.1
sortedcontainers==2.4.0
trio==0.28.0
trio-websocket==0.11.1
typing_extensions==4.12.2
urllib3==2.3.0
websocket-client==1.8.0
wsproto==1.2.0
Starte die Container mit:
docker compose up -d
Docker baut die Images und startet sie im Hintergrund.
Überprüfe den Status:
docker compose ps
Wenn zwei Container laufen, ist alles korrekt eingerichtet – du kannst jetzt mit Selenium auf beliebige Websites zugreifen.
In offiziellen Selenium-Docker-Images (z. B. selenium/standalone-chrome oder seleniarm/standalone-chromium) wird der direkte Zugriff auf das Chrome DevTools Protocol (CDP) von Selenium Grid überschrieben.
Parameter wie --remote-debugging-port=9229 werden ignoriert oder von Selenium neu zugewiesen. Daher ist direkter Zugriff von außen nicht möglich.
Stattdessen bieten diese Images integrierten VNC-Zugriff (Virtual Network Computing) – ähnlich wie TeamViewer oder AnyDesk, aber auf Container-Ebene.
⚠️ VNC funktioniert nur, wenn der Headless-Modus deaktiviert ist, da es den echten Bildschirminhalt überträgt.
Du kannst die VNC-Weboberfläche öffnen unter:
http://<server_ip>:7900
Beim ersten Zugriff wird ein Passwort verlangt. Erstelle es direkt im Container:
docker exec -it selenium-container bash
x11vnc -storepasswd
Gib ein Passwort ein, bestätige es, und verwende es dann auf der VNC-Webseite, um Zugriff auf den laufenden Chrome-Browser im Container zu erhalten. Dort kannst du die Chrome DevTools öffnen und Netzwerkaktivitäten oder DOM-Elemente untersuchen.
Das Ausführen von Selenium in Docker-Containern erhöht die Portabilität, beseitigt Versionskonflikte und erleichtert die Integration in CI/CD-Pipelines. Dank der integrierten VNC-Unterstützung kannst du Tests visuell debuggen und bei Bedarf mit grafischer Oberfläche arbeiten.
Achte lediglich darauf:
das passende Image (AMD64 oder ARM64) zu verwenden
und den Headless-Modus zu deaktivieren, wenn du den Browser sehen möchtest.
So erhältst du eine flexible, stabile und reproduzierbare Testumgebung für automatisierte Browser-Tests mit Selenium und Docker.