A volte è utile lavorare con Selenium in Python all’interno di un container Docker. Questo solleva alcune domande sui vantaggi di questa configurazione, sulla compatibilità tra ChromeDriver e Chromium, e sui dettagli della loro implementazione. In questo articolo analizzeremo i punti fondamentali e forniremo soluzioni ai problemi più comuni.
Eseguire Selenium in un container offre diversi vantaggi:
🧩 Portabilità – L’ambiente può essere facilmente trasferito tra diverse macchine, evitando conflitti di versione e dipendenze specifiche del sistema operativo.
🧱 Isolamento – Il container Selenium può essere aggiornato o sostituito rapidamente senza influire su altri componenti del server.
Prima di iniziare, assicurati che Docker e Docker Compose siano installati:
docker --version && docker compose version
💡 In alcune versioni, il comando si scrive docker-compose (con trattino) invece di docker compose.
Se gli strumenti sono installati, verranno visualizzate le versioni. In caso contrario, segui la guida di installazione per aggiungerli al sistema.
Quando si implementa Selenium all’interno di container Docker, è importante considerare:
l’architettura dell’host,
i requisiti funzionali,
e le prestazioni.
Le immagini ufficiali selenium/standalone-* sono progettate per CPU AMD64 (x86_64), mentre seleniarm/standalone-* sono ottimizzate per architetture ARM (come Apple Silicon o server ARM64).
Crea un file docker-compose.yml nella directory principale del progetto:
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
Scegli l’immagine corretta per la tua architettura commentando o decommentando la riga appropriata. Il servizio app eseguirà il codice Python principale.
Definiscilo in un Dockerfile come segue:
# 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"]
Questo Dockerfile utilizza una base Python leggera e installa automaticamente le dipendenze richieste.
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
Avvia i container con:
docker compose up -d
Docker costruirà e avvierà i container in background. Verifica lo stato con:
docker compose ps
Se entrambi i container risultano attivi, l’ambiente è stato avviato correttamente. Puoi ora utilizzare Selenium per interagire con i siti web.
Nelle immagini ufficiali di Selenium (come selenium/standalone-chrome o seleniarm/standalone-chromium), l’accesso diretto al Chrome DevTools Protocol (CDP) viene gestito da Selenium Grid. Ogni sessione crea una nuova porta WebSocket, impedendo l’accesso esterno diretto.
Le opzioni come --remote-debugging-port=9229 vengono ignorate o sovrascritte. Per questo motivo, queste immagini includono un server VNC (Virtual Network Computing) integrato, simile a TeamViewer o AnyDesk.
⚠️ La modalità headless deve essere disattivata, poiché il VNC trasmette lo schermo reale, e senza interfaccia visiva non verrà mostrato nulla.
Accedi all’interfaccia web VNC su:
http://<server_ip>:7900
Alla connessione verrà richiesta una password. Per crearla, accedi al container Selenium:
docker exec -it selenium-container bash
x11vnc -storepasswd
Inserisci e conferma la password. Successivamente, utilizza la password nella pagina VNC per accedere al browser controllato da Selenium. Da qui puoi aprire DevTools, ispezionare elementi DOM o analizzare le richieste di rete.
Eseguire Selenium in container Docker semplifica la portabilità dell’ambiente e riduce i conflitti di versione tra strumenti. Inoltre, consente di eseguire il debug visivo tramite VNC quando necessario.
Ricorda di:
scegliere l’immagine corretta in base all’architettura (AMD64 o ARM64);
disattivare la modalità headless se desideri visualizzare l’interfaccia grafica.
Questa configurazione fornisce un’infrastruttura di test flessibile, stabile e facilmente integrabile nelle pipeline CI/CD, ottimizzando i flussi di lavoro di test automatizzati con Selenium.