Тесты которые проходят локально но падают в CI чаще всего это не баги в тестах: причина в несоответствии окружений между версиями Node, сборками браузера или отсутствующими системными зависимостями. Docker-контейнер решает это упаковывая Playwright, его браузерные бинарники и все зависимости в единый образ который запускается идентично на ноутбуке, машине коллеги и CI. Здесь разобрано написание Dockerfile для Playwright, запуск тестов в контейнере локально, интеграция с GitHub Actions и использование Docker Compose когда тестам нужны приложение и база данных рядом.
Зачем QA-инженеру Docker
Без Docker
- Тесты проходят локально на Node 20, падают в CI на Node 18
- Версия Chrome в CI отличается от версии на ноутбуке
- Переменные окружения настроены по-разному на каждой машине
- Новый член команды тратит день на то чтобы запустить тесты
С Docker
Тесты запускаются в одном контейнере локально и в CI. Все используют одни версии Node, Chrome и зависимостей. Новый член команды: docker compose up, тесты запускаются за 2 минуты.
Основные концепции
Image (образ)
Образ: шаблон, read-only снимок файловой системы с установленным ПО. Как класс в коде.
mcr.microsoft.com/playwright:latest : образ с предустановленными Playwright и браузерами
node:20-alpine : Node.js 20 на минимальном Alpine LinuxContainer (контейнер)
Контейнер: запущенный экземпляр образа. Из одного образа можно запустить несколько контейнеров одновременно. Как создание нескольких объектов из одного класса.
Dockerfile
Инструкции для создания собственного образа. Начинаешь с базового образа и добавляешь свои файлы и конфигурацию.
Docker Compose
Инструмент для запуска нескольких контейнеров вместе. Тестам может понадобиться работающий веб-сервер и база данных: Compose запускает всё это одной командой.
Первый Playwright Dockerfile
Playwright предоставляет официальные Docker-образы с предустановленными браузерами:
# Dockerfile
FROM mcr.microsoft.com/playwright:v1.44.0-jammy
# Рабочая директория внутри контейнера
WORKDIR /app
# Сначала копируем файлы зависимостей (оптимизация кеширования)
COPY package.json package-lock.json ./
# Устанавливаем Node-зависимости
RUN npm ci
# Копируем остальную часть проекта
COPY . .
# Команда по умолчанию: запуск всех тестов
CMD ["npx", "playwright", "test"]Собрать образ
docker build -t my-playwright-tests .Запустить тесты
docker run my-playwright-testsChrome, Firefox и WebKit уже внутри контейнера. Устанавливать браузеры на хост-машине не нужно.
Запуск тестов с Docker
Базовый запуск
# Запустить все тесты
docker run my-playwright-tests
# Запустить конкретный тестовый файл
docker run my-playwright-tests npx playwright test tests/login.spec.ts
# Запустить с переменной окружения
docker run -e BASE_URL=https://staging.myapp.com my-playwright-tests
# Примонтировать локальную директорию (чтобы видеть результаты тестов)
docker run -v $(pwd)/playwright-report:/app/playwright-report my-playwright-testsСохранение результатов тестов
Файловая система контейнера исчезает при его остановке. Используй монтирование томов для сохранения отчётов:
docker run \
-v $(pwd)/playwright-report:/app/playwright-report \
-v $(pwd)/test-results:/app/test-results \
my-playwright-testsПосле прогона playwright-report/ появится на локальной машине.
Docker Compose для полного стека
Реальное тестирование часто требует чтобы тестируемое приложение тоже работало. Compose запускает всё вместе.
# docker-compose.yml
version: '3.8'
services:
# Тестируемое приложение
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
# База данных
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
# Playwright-тесты
tests:
build: .
environment:
- BASE_URL=http://app:3000
depends_on:
- app
volumes:
- ./playwright-report:/app/playwright-report
- ./test-results:/app/test-resultsЗапустить всё
docker compose up --exit-code-from testsЗапускает базу данных, ждёт пока она станет готовой, запускает приложение, прогоняет тесты, возвращает код выхода тестов (чтобы CI знал прошли или нет). --exit-code-from tests выходит с кодом выхода контейнера тестов.
Оптимизация Dockerfile
Кеширование слоёв ускоряет пересборку. Ключевое правило: то что меняется редко ставь выше.
FROM mcr.microsoft.com/playwright:v1.44.0-jammy
WORKDIR /app
# 1. Копируем файлы зависимостей (меняются редко)
COPY package.json package-lock.json ./
# Этот слой кешируется пока не изменится package.json
RUN npm ci
# 2. Копируем остальное (меняется с каждым коммитом)
COPY . .
CMD ["npx", "playwright", "test"]Если изменились только тестовые файлы, Docker переиспользует слой npm ci из кеша. Время сборки: секунды вместо минут.
Интеграция с 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: Build test image
run: docker build -t playwright-tests .
- name: Run tests
run: |
docker run \
-v ${{ github.workspace }}/playwright-report:/app/playwright-report \
-e BASE_URL=${{ secrets.STAGING_URL }} \
playwright-tests
- name: Upload report
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/Полезные Docker-команды для QA
# Список запущенных контейнеров
docker ps
# Список всех образов
docker images
# Остановить все запущенные контейнеры
docker stop $(docker ps -q)
# Удалить все остановленные контейнеры
docker container prune
# Удалить неиспользуемые образы
docker image prune
# Следить за логами контейнера
docker logs -f <container-id>
# Открыть shell внутри запущенного контейнера (полезно для отладки)
docker exec -it <container-id> /bin/bash
# Запустить контейнер в интерактивном режиме
docker run -it my-playwright-tests /bin/bashОтладка внутри контейнера
Когда тесты падают только в контейнере:
# Запустить контейнер с shell вместо тестов
docker run -it my-playwright-tests /bin/bash
# Теперь ты внутри контейнера
# Проверить что установлено
node --version
npx playwright --version
# Запустить тесты вручную
npx playwright test tests/login.spec.ts --headed --debug
# Проверить переменные окружения
env | grep BASE_URLЧастые проблемы: BASE_URL указывает на localhost (работает на хосте, падает в контейнере: используй имя сервиса); отсутствующие переменные окружения; права на файлы (файлы созданные вне контейнера могут принадлежать root внутри).
Официальный Docker-образ Playwright
# Скачать последний образ Playwright
docker pull mcr.microsoft.com/playwright:v1.44.0-jammy
# Посмотреть что внутри
docker run -it mcr.microsoft.com/playwright:v1.44.0-jammy /bin/bash
# Проверить установленные браузеры
npx playwright install --listТеги которые нужно знать: v1.44.0-jammy (конкретная версия Playwright на Ubuntu 22.04) и latest (последняя версия, может ломаться при обновлении). Всегда фиксируй конкретную версию в production.
Сводная таблица
| Концепция | Что это |
|-----------|---------|
| Image (образ) | Шаблон с предустановленным ПО |
| Container (контейнер) | Запущенный экземпляр образа |
| Dockerfile | Инструкции для создания образа |
| Docker Compose | Запуск нескольких контейнеров вместе |
| Volume mount | Общий доступ к файлам между хостом и контейнером |
Для Playwright конкретно:
1. Используй mcr.microsoft.com/playwright как базовый образ: браузеры уже включены
2. Монтируй директории с отчётами чтобы результаты не исчезали при остановке контейнера
3. Используй Compose для совместного запуска приложения и тестов
4. Фиксируй версии образов: latest приводит к неожиданным поломкам
Docker превращает «работает на моей машине» в «работает везде». Для QA это означает что тесты реально тестируют ПО, а не борются с различиями окружений.
→ See also: Docker для тестировщиков: запуск Playwright в контейнерах | CI/CD для QA: сравнение GitHub Actions, Jenkins и GitLab | GitHub Actions для тестов Playwright: полная настройка (2026)