Às vezes, é útil trabalhar com o Selenium em Python dentro de um contêiner Docker. Isso levanta dúvidas sobre os benefícios dessa abordagem, a compatibilidade entre o ChromeDriver e o Chromium, e as particularidades de sua implementação. Neste artigo, abordaremos os principais pontos e apresentaremos soluções para os problemas mais comuns.
Executar o Selenium em um contêiner traz várias vantagens:
🧩 Portabilidade – Permite transferir facilmente o ambiente entre diferentes máquinas, evitando conflitos de versão e dependências específicas do sistema operacional.
🧱 Isolamento – O contêiner Selenium pode ser atualizado ou substituído rapidamente, sem afetar outros componentes do servidor.
Antes de começar, verifique se o Docker e o Docker Compose estão instalados:
docker --version && docker compose version
💡 Em algumas versões, o comando é docker-compose (com hífen) em vez de docker compose.
Se as ferramentas estiverem instaladas, as versões serão exibidas. Caso contrário, siga o guia de instalação correspondente.
Ao usar o Selenium em contêineres Docker, leve em consideração a arquitetura do host, os requisitos funcionais e o desempenho.
As imagens oficiais selenium/standalone-* foram projetadas para CPUs AMD64 (x86_64), enquanto as imagens seleniarm/standalone-* são adaptadas para arquiteturas ARM (como Apple Silicon ou servidores ARM64).
Crie um arquivo docker-compose.yml na raiz do projeto:
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
Escolha a imagem correta para a sua arquitetura descomentando a linha apropriada. O serviço app executará o seu código Python.
Crie um Dockerfile para definir esse serviço:
# 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"]
Esse Dockerfile usa uma imagem leve de Python e instala automaticamente as dependências necessárias.
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
Para iniciar os contêineres:
docker compose up -d
O Docker construirá e iniciará os contêineres em segundo plano.
Verifique o status com:
docker compose ps
Se dois contêineres estiverem ativos, tudo está funcionando corretamente — você pode interagir com sites diretamente via Selenium.
Nas imagens oficiais do Selenium (como selenium/standalone-chrome ou seleniarm/standalone-chromium), o acesso direto ao Chrome DevTools Protocol (CDP) é gerenciado pelo Selenium Grid. Cada sessão gera uma nova porta WebSocket, o que torna impossível o acesso direto de fora do contêiner.
Argumentos como --remote-debugging-port=9229 são ignorados ou substituídos. Por isso, essas imagens oferecem suporte VNC integrado (Virtual Network Computing), semelhante a TeamViewer ou AnyDesk.
⚠️ O modo headless deve estar desativado, pois o VNC transmite a tela real — e se ela estiver vazia, nada será exibido.
Acesse a interface web do VNC em:
http://<server_ip>:7900
Ao conectar, será solicitado um senha. Para criá-la, entre no contêiner Selenium:
docker exec -it selenium-container bash
x11vnc -storepasswd
Digite e confirme a senha. Em seguida, use-a na interface web do VNC para acessar o navegador controlado pelo Selenium. A partir daí, é possível abrir as DevTools, inspecionar elementos DOM e depurar solicitações de rede.
Executar o Selenium em contêineres Docker simplifica a portabilidade do ambiente e elimina conflitos de versão. Além disso, permite depuração visual via VNC, quando necessário.
Certifique-se apenas de:
escolher a imagem correta (AMD64 ou ARM64),
e desativar o modo headless se desejar usar uma interface gráfica.
Essa abordagem oferece uma infraestrutura de testes flexível, estável e facilmente integrável a pipelines CI/CD.