Iniciar sesión
Iniciar sesión

Ejecutar Selenium con Chrome en Docker

Ejecutar Selenium con Chrome en Docker
Hostman Team
Redactor técnico
Entorno Docker
30.10.2025
Reading time: 6 min

A veces resulta útil trabajar con Selenium en Python dentro de un contenedor Docker. Esto plantea preguntas sobre los beneficios de esta práctica, la compatibilidad entre ChromeDriver y Chromium, y las particularidades de su implementación. En este artículo abordaremos los puntos clave y ofreceremos soluciones a los problemas más comunes.

¿Por qué ejecutar Selenium en Docker?

Ejecutar Selenium dentro de un contenedor ofrece varias ventajas:

  • 🧩 Portabilidad – Permite trasladar fácilmente el entorno entre diferentes máquinas, evitando conflictos de versiones y dependencias específicas del sistema operativo.

  • 🧱 Aislamiento – El contenedor Selenium puede actualizarse o reemplazarse rápidamente sin afectar otros componentes del servidor.

  • ⚙️ Compatibilidad con CI/CD – Selenium en contenedores encaja perfectamente en pipelines de CI/CD, ya que es posible crear un entorno de pruebas limpio desde cero cada vez que se ejecutan los tests.

Preparar un servidor Ubuntu para Selenium con Docker

Antes de comenzar, asegúrate de que Docker y Docker Compose estén instalados:

docker --version && docker compose version

💡 En algunas versiones, el comando se escribe docker-compose (con guion) en lugar de docker compose.

Si las herramientas están instaladas, verás sus versiones. Si no, instálalas antes de continuar.

Ejemplo: Selenium en Docker

Al implementar Selenium dentro de contenedores Docker, considera los siguientes aspectos:

  • la arquitectura del host,

  • los requisitos funcionales,

  • y el rendimiento esperado.

Las imágenes oficiales selenium/standalone-* están diseñadas para CPUs AMD64 (x86_64), mientras que seleniarm/standalone-* están adaptadas para arquitecturas ARM (como Apple Silicon o servidores ARM64).

Crea un archivo docker-compose.yml en la raíz del proyecto:

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

Selecciona la imagen adecuada para tu sistema descomentando la línea correspondiente. El servicio app ejecutará tu código principal en Python.
 
A continuación, define el servicio en un 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"]

Este Dockerfile usa una imagen ligera de Python e instala automáticamente las dependencias necesarias.

Script principal (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

Iniciar los contenedores

Ejecuta los contenedores con:

docker compose up -d

Docker construirá las imágenes y las iniciará en segundo plano.

Comprueba el estado con:

docker compose ps

Si aparecen dos contenedores en ejecución, todo está funcionando correctamente. Ya puedes interactuar con sitios web usando Selenium.

Depuración de Selenium en Docker con VNC

En las imágenes oficiales de Selenium (como selenium/standalone-chrome o seleniarm/standalone-chromium), el acceso directo al Chrome DevTools Protocol (CDP) está gestionado por Selenium Grid. Cada sesión genera un nuevo puerto WebSocket, lo que impide el acceso directo desde fuera del contenedor.

Parámetros como --remote-debugging-port=9229 son ignorados o sobrescritos. En su lugar, estas imágenes incluyen VNC (Virtual Network Computing) integrado, similar a TeamViewer o AnyDesk.

⚠️ El modo headless debe estar desactivado, ya que VNC transmite la pantalla real, y si no hay interfaz visible, no se mostrará nada.

Accede a la interfaz web de VNC en:

http://<server_ip>:7900

Al conectar, se te pedirá una contraseña. Para generarla, accede al contenedor Selenium:

docker exec -it selenium-container bash
x11vnc -storepasswd

Introduce y confirma la contraseña. Luego, ingrésala en la interfaz web de VNC para acceder al navegador controlado por Selenium dentro del contenedor. Desde ahí puedes abrir DevTools, inspeccionar el DOM o depurar solicitudes de red.

Conclusión

Ejecutar Selenium dentro de contenedores Docker simplifica la portabilidad del entorno y elimina conflictos de versiones. Además, permite realizar depuración visual mediante VNC cuando sea necesario.

Solo asegúrate de:

  • elegir la imagen correcta para tu arquitectura (AMD64 o ARM64),

  • y desactivar el modo headless si necesitas una interfaz gráfica.

Esta configuración ofrece una infraestructura de pruebas flexible, estable y perfectamente integrada en pipelines de CI/CD.

Entorno Docker
30.10.2025
Reading time: 6 min

Similares

Entorno Docker

Configuración de registros Docker externos

Cuando trabajas con Docker, utilizas imágenes: archivos ejecutables que contienen todo lo necesario para ejecutar una aplicación, incluido el código fuente, las bibliotecas y las dependencias. Estas imágenes se almacenan en repositorios especializados llamados registros, que pueden ser privados o públicos. El registro público más conocido es Docker Hub, donde puedes encontrar muchas imágenes oficiales como Nginx, PostgreSQL, Alpine, Ubuntu, Node o MongoDB.Los usuarios pueden registrarse en Docker Hub y almacenar sus propias imágenes: por defecto, cuentan con un registro público y tres registros privados. Docker Hub es el registro predeterminado que Docker utiliza para descargar (pull) imágenes. Esta guía explica cómo cambiar el registro predeterminado de Docker por otro alternativo. Uso de registros Docker externos Una forma sencilla de usar registros externos es aprovechar los servicios ofrecidos por proveedores como Google o Amazon.  A continuación se muestra una lista de registros públicos que puedes utilizar: URL del registro Propietario https://mirror.gcr.io Google https://public.ecr.aws Amazon https://quay.io Red Hat https://registry.access.redhat.com Red Hat https://registry.redhat.io Red Hat ⚠️ Nota: el uso de registros externos puede implicar riesgos de seguridad. Utilízalos con precaución. Sigue los pasos siguientes para sustituir Docker Hub por otro registro predeterminado. Configuración en Linux Abre el archivo daemon.json con un editor de texto. Si Docker está instalado fuera del modo rootless, el archivo se encuentra en: /etc/docker/daemon.json Si no existe, créalo con: nano /etc/docker/daemon.json Para Docker en modo rootless, el archivo se ubica en el directorio personal del usuario: ~/.config/docker/daemon.json Créalo si es necesario: nano ~/.config/docker/daemon.json Agrega el siguiente parámetro para definir un nuevo registro predeterminado (en este ejemplo, el espejo de Google): {   "registry-mirrors": ["https://mirror.gcr.io"] } Guarda y cierra el archivo. Reinicia el servicio de Docker para aplicar los cambios: systemctl reload docker A partir de ahora, Docker usará el nuevo registro para descargar imágenes. Por ejemplo, para obtener la imagen Alpine desde el registro de Google: docker pull mirror.gcr.io/alpine También puedes especificar una versión concreta: docker pull mirror.gcr.io/nginx:1.25.2 Configuración en Windows (Docker Desktop) Abre el archivo daemon.json, ubicado en: C:\Users\<tu_usuario>\.docker\daemon.json Agrega el parámetro: {   "registry-mirrors": ["https://mirror.gcr.io"] } Guarda el archivo y reinicia Docker. Haz clic derecho en el icono de Docker en la bandeja del sistema y selecciona Restart. También puedes realizar esta configuración desde la interfaz de Docker Desktop:ve a Settings → Docker Engine y añade lo siguiente: {   "registry-mirrors": ["https://mirror.gcr.io"] } Haz clic en Apply & Restart para aplicar los cambios y reiniciar Docker. Tras el reinicio, Docker usará el nuevo registro para las descargas. Por ejemplo, descarga una imagen de curl: docker pull mirror.gcr.io/curlimages/curl O una versión específica: docker pull mirror.gcr.io/node:21-alpine Uso de Nexus como registro Docker También puedes usar Nexus para gestionar imágenes Docker. Nexus admite repositorios proxy, que almacenan en caché las imágenes obtenidas de registros externos como Docker Hub. Esto permite que Nexus actúe como un registro proxy en caché, muy útil si los registros externos dejan de estar disponibles temporalmente. Configuración de un repositorio proxy en Nexus Inicia sesión en Nexus con un usuario administrador o un usuario con permisos para crear repositorios. Ve a Server Administration and Configuration → Repositories. Haz clic en Create repository y selecciona el tipo docker (proxy) Completa los siguientes campos: Name: asigna un nombre único al repositorio. Online: marca esta opción para habilitar el repositorio. Proxy server: si Nexus está detrás de un proxy (como Nginx), no será necesario usar puertos de autenticación.Si no hay proxy, asigna un puerto único para HTTP o HTTPS. Allow anonymous docker pull: si está activado, no será necesario iniciar sesión para descargar imágenes.Si está desactivado, deberás autenticarte antes de hacer pull. Remote storage: especifica la URL del registro externo, por ejemplo https://registry-1.docker.io para Docker Hub. Una vez creado el repositorio, inicia sesión (si es necesario) con: docker login <direccion_registro_nexus> Para descargar una imagen: docker pull <direccion_registro_nexus>/nombre_imagen:tag Ejemplo: descargar una imagen de Python con el tag 3.8.19-alpine: docker pull nexus-repo.com/python:3.8.19-alpine ⚠️ Consejo de seguridad: evita usar la etiqueta latest, ya que podría contener errores o vulnerabilidades. Conclusión En este artículo se han presentado varios métodos para descargar y almacenar imágenes Docker. El uso de registros externos puede ser útil cuando Docker Hub no está disponible. Si no confías en los registros públicos, siempre puedes configurar tu propio registro Docker, ya sea privado o público, utilizando herramientas como Nexus o Harbor.
05 November 2025 · 5 min to read

¿Tienes preguntas,
comentarios o inquietudes?

Nuestros profesionales están disponibles para asistirte en cualquier momento,
ya sea que necesites ayuda o no sepas por dónde empezar.
Hostman's Support