Los tests que pasan localmente pero fallan en CI a menudo no son bugs en los tests: son diferencias de entorno entre versiones de Node, builds del navegador o dependencias del sistema que faltan. Un contenedor Docker corrige esto empaquetando Playwright, sus binarios de navegador y todas las dependencias en una sola imagen que corre de forma idéntica en una laptop, en la computadora de un compañero y en CI. Esta guía cubre cómo escribir un Dockerfile para Playwright, ejecutar tests en un contenedor localmente, integrar con GitHub Actions, y usar Docker Compose cuando los tests necesitan la aplicación y una base de datos corriendo junto a ellos.

Por qué los ingenieros QA necesitan Docker

Sin Docker

  • Tus tests pasan localmente con Node 20, fallan en CI con Node 18
  • La versión de Chrome en CI difiere de la de tu laptop
  • Las variables de entorno están configuradas diferente en cada máquina
  • Un nuevo integrante del equipo pasa un día entero para que los tests corran

Con Docker

Los tests corren en el mismo contenedor localmente y en CI. Todos usan las mismas versiones de Node, Chrome y dependencias. Para un nuevo integrante, docker compose up es suficiente: los tests corren en 2 minutos.

Conceptos clave

Imagen

Una imagen es un plano: una instantánea de solo lectura de un sistema de archivos con software instalado. Piénsala como una clase en código.

playwright/playwright:latest — una imagen con Playwright y navegadores preinstalados
node:20-alpine — Node.js 20 sobre Alpine Linux minimal

Contenedor

Un contenedor es una instancia en ejecución de una imagen. Múltiples contenedores pueden correr desde la misma imagen simultáneamente. Como crear múltiples objetos a partir de la misma clase.

Dockerfile

Instrucciones para construir una imagen personalizada. Partes de una imagen base y le agregas tus archivos y configuración.

Docker Compose

Una herramienta para ejecutar múltiples contenedores juntos. Tus tests pueden necesitar un servidor web y una base de datos corriendo: Compose los inicia a todos con un solo comando.

Tu primer Dockerfile para Playwright

Playwright provee imágenes Docker oficiales con navegadores preinstalados:

# Dockerfile
FROM mcr.microsoft.com/playwright:v1.44.0-jammy

# Establecer el directorio de trabajo dentro del contenedor
WORKDIR /app

# Copiar los archivos de dependencias primero (optimización de caché)
COPY package.json package-lock.json ./

# Instalar dependencias de Node
RUN npm ci

# Copiar el resto del proyecto
COPY . .

# Comando por defecto: ejecutar todos los tests
CMD ["npx", "playwright", "test"]

Construir la imagen

docker build -t my-playwright-tests .

Ejecutar los tests

docker run my-playwright-tests

Chrome, Firefox y WebKit están todos dentro del contenedor. No se necesita instalar ningún navegador en la máquina host.

Ejecutar tests con Docker

Ejecución básica

# Ejecutar todos los tests
docker run my-playwright-tests

# Ejecutar un archivo de test específico
docker run my-playwright-tests npx playwright test tests/login.spec.ts

# Ejecutar con variable de entorno
docker run -e BASE_URL=https://staging.myapp.com my-playwright-tests

# Montar directorio local (para ver los resultados de los tests)
docker run -v $(pwd)/playwright-report:/app/playwright-report my-playwright-tests

Guardar los resultados de los tests

El sistema de archivos del contenedor desaparece cuando el contenedor se detiene. Usa volúmenes montados para guardar los reportes:

docker run \
  -v $(pwd)/playwright-report:/app/playwright-report \
  -v $(pwd)/test-results:/app/test-results \
  my-playwright-tests

Después de la ejecución, playwright-report/ aparece en tu máquina local.

Docker Compose para testing full stack

El testing real a menudo significa que la aplicación bajo prueba también necesita estar corriendo. Compose inicia todo junto.

# docker-compose.yml
version: '3.8'

services:
  # La aplicación que estás testeando
  app:
    image: myapp:latest
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=test
      - DATABASE_URL=postgresql://postgres:postgres@db:5432/testdb
    depends_on:
      db:
        condition: service_healthy

  # Base de datos
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: testdb
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  # Tests de Playwright
  tests:
    build: .
    environment:
      - BASE_URL=http://app:3000
    depends_on:
      - app
    volumes:
      - ./playwright-report:/app/playwright-report
      - ./test-results:/app/test-results

Ejecutar todo

docker compose up --exit-code-from tests

Esto inicia la base de datos, espera a que esté sana, inicia la aplicación, ejecuta los tests, devuelve el código de salida de los tests (para que CI sepa si pasaron o fallaron) y para los contenedores.

Optimizar el Dockerfile

El caché de capas hace que las reconstrucciones sean rápidas. La regla clave: pones lo que cambia con menos frecuencia arriba.

FROM mcr.microsoft.com/playwright:v1.44.0-jammy

WORKDIR /app

# 1. Copiar archivos de dependencias (cambian raramente)
COPY package.json package-lock.json ./
# Esta capa queda en caché hasta que cambia package.json
RUN npm ci

# 2. Copiar el resto (cambia en cada commit)
COPY . .

CMD ["npx", "playwright", "test"]

Si solo cambiaste archivos de tests, Docker reutiliza la capa npm ci del caché. Tiempo de build: segundos en lugar de minutos.

Integración con CI/CD

GitHub Actions

# .github/workflows/playwright.yml
name: Playwright Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Construir imagen de tests
        run: docker build -t playwright-tests .

      - name: Ejecutar tests
        run: |
          docker run \
            -v ${{ github.workspace }}/playwright-report:/app/playwright-report \
            -e BASE_URL=${{ secrets.STAGING_URL }} \
            playwright-tests

      - name: Subir reporte
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/

GitLab CI

# .gitlab-ci.yml
test:
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t tests .
    - docker run
        -v $(pwd)/playwright-report:/app/playwright-report
        -e BASE_URL=$STAGING_URL
        tests
  artifacts:
    when: always
    paths:
      - playwright-report/

Comandos Docker útiles para QA

# Listar contenedores en ejecución
docker ps

# Listar todas las imágenes
docker images

# Detener todos los contenedores en ejecución
docker stop $(docker ps -q)

# Eliminar todos los contenedores detenidos
docker container prune

# Eliminar imágenes no usadas
docker image prune

# Ver los logs de un contenedor en tiempo real
docker logs -f <container-id>

# Abrir una shell dentro de un contenedor en ejecución (ideal para depuración)
docker exec -it <container-id> /bin/bash

# Ejecutar un contenedor de forma interactiva
docker run -it my-playwright-tests /bin/bash

Depurar dentro de un contenedor

Cuando los tests solo fallan dentro del contenedor:

# Iniciar el contenedor con shell en lugar de tests
docker run -it my-playwright-tests /bin/bash

# Ahora estás dentro del contenedor
# Verificar qué está instalado
node --version
npx playwright --version

# Ejecutar tests manualmente
npx playwright test tests/login.spec.ts --headed --debug

# Verificar variables de entorno
env | grep BASE_URL

Los problemas más frecuentes son BASE_URL apuntando a localhost (funciona en el host, falla en el contenedor: usa el nombre del servicio en su lugar), variables de entorno faltantes, y permisos de archivos cuando los archivos creados fuera del contenedor son propiedad de root dentro de él.

La imagen Docker oficial de Playwright

# Descargar la imagen oficial de Playwright
docker pull mcr.microsoft.com/playwright:v1.44.0-jammy

# Ver qué tiene adentro
docker run -it mcr.microsoft.com/playwright:v1.44.0-jammy /bin/bash

# Verificar los navegadores instalados
npx playwright install --list

v1.44.0-jammy corresponde a una versión específica de Playwright sobre Ubuntu 22.04 (Jammy). latest es la última versión pero puede romperse cuando Playwright se actualiza. Siempre fija una versión específica en producción.

Resumen

| Concepto | Qué es |

|----------|--------|

| Imagen | Plano con software preinstalado |

| Contenedor | Instancia en ejecución de una imagen |

| Dockerfile | Instrucciones para construir una imagen personalizada |

| Docker Compose | Ejecutar múltiples contenedores juntos |

| Volumen montado | Compartir archivos entre host y contenedor |

Para Playwright específicamente:

1. Usa mcr.microsoft.com/playwright como imagen base: incluye los navegadores

2. Monta los directorios de reportes para que los resultados sobrevivan cuando el contenedor se detenga

3. Usa Compose para iniciar la aplicación y los tests juntos

4. Fija versiones de imagen: latest causa roturas inesperadas

→ See also: Docker para Testers: Ejecutando Playwright en Contenedores | CI/CD para QA: GitHub Actions, Jenkins y GitLab Comparados | GitHub Actions para Tests de Playwright: La Configuración Completa (2026)