Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Docker в CI: сборка и тестирование
docker_basics_ci

Docker в CI: сборка и тестирование

Сборка Docker-образов в пайплайне, тестирование контейнеризованных приложений.

Docker в CI: сборка и тестирование

Интеграция Docker в CI-пайплайны позволяет создавать воспроизводимые окружения для сборки и тестирования. Изучите основы работы с Docker в GitHub Actions и GitLab CI.

#Зачем Docker в CI?

Docker в CI-пайплайнах решает ключевые проблемы:

  • Воспроизводимость — одинаковое окружение на всех этапах pipeline
  • Изоляция — тесты не влияют на runner и друг на друга
  • Портативность — образы работают одинаково локально и в CI
  • Консистентность — тестовое окружение идентично production
┌─────────────────────────────────────────────────────────────┐
│                    CI Pipeline                               │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐              │
│  │  Build   │ →  │  Test    │ →  │  Deploy  │              │
│  │  Docker  │    │  in      │    │  Image   │              │
│  │  Image   │    │  Container│   │  to      │              │
│  │          │    │          │    │  Registry│              │
│  └──────────┘    └──────────┘    └──────────┘              │
└─────────────────────────────────────────────────────────────┘

#Базовые команды Docker в CI

#Сборка образа

# Базовая сборка docker build -t myapp:latest . # Сборка с указанием Dockerfile docker build -f Dockerfile.prod -t myapp:prod . # Сборка с build-arg docker build --build-arg ENV=production -t myapp:prod . # Сборка без кэша (для воспроизводимости) docker build --no-cache -t myapp:latest .

#Запуск контейнера для тестов

# Запуск с автoудалением docker run --rm myapp:latest npm test # Запуск с переменными окружения docker run --rm -e DB_HOST=localhost -e DB_PORT=5432 myapp:latest pytest # Запуск с монтированием volume docker run --rm -v $(pwd)/tests:/app/tests myapp:latest pytest # Запуск с сетью для интеграционных тестов docker run --rm --network=host myapp:latest pytest

#Очистка ресурсов

# Удаление всех остановленных контейнеров docker container prune -f # Удаление неиспользуемых образов docker image prune -f # Полная очистка (включая build cache) docker system prune -f --volumes # Очистка buildx cache docker buildx prune -f

#Docker в GitHub Actions

#Базовый workflow со сборкой

name: Docker Build and Test on: push: branches: [main] pull_request: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Build Docker image run: docker build -t myapp:${{ github.sha }} . - name: Run tests in container run: docker run --rm myapp:${{ github.sha }} npm test - name: Cleanup if: always() run: docker system prune -f

#Использование Docker Compose для тестов

name: Docker Compose Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Start services with Docker Compose run: docker compose up -d - name: Wait for services to be ready run: | echo "Waiting for database..." sleep 10 - name: Run integration tests run: docker compose exec -T app pytest tests/integration/ - name: Show logs on failure if: failure() run: docker compose logs - name: Cleanup if: always() run: docker compose down -v

#Пример docker-compose.yml для тестов

version: '3.8' services: app: build: . environment: - DB_HOST=db - DB_PORT=5432 - DB_NAME=testdb depends_on: db: condition: service_healthy command: pytest tests/ db: image: postgres:15-alpine environment: - POSTGRES_DB=testdb - POSTGRES_USER=test - POSTGRES_PASSWORD=test healthcheck: test: ["CMD-SHELL", "pg_isready -U test"] interval: 5s timeout: 5s retries: 5

#Сборка с Docker Buildx

name: Build with Buildx on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build image uses: docker/build-push-action@v5 with: context: . tags: myapp:${{ github.sha }} load: true # Загрузить в локальный Docker - name: Run tests run: docker run --rm myapp:${{ github.sha }} npm test

#Docker в GitLab CI

#Базовая конфигурация .gitlab-ci.yml

stages: - build - test - deploy variables: IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA build: stage: build image: docker:24-dind services: - docker:24-dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $IMAGE_NAME . - docker push $IMAGE_NAME test: stage: test image: docker:24-dind services: - docker:24-dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker pull $IMAGE_NAME - docker run --rm $IMAGE_NAME npm test needs: ["build"]

#Использование Docker-in-Docker (dind)

# Для сложных сценариев с Docker Compose test: stage: test image: name: docker:24-dind services: - name: docker:24-dind command: ["--experimental"] variables: DOCKER_HOST: tcp://docker:2375 DOCKER_TLS_CERTDIR: "" script: - docker compose up -d - sleep 10 - docker compose exec -T app pytest - docker compose down -v

#Кэширование Docker-слоёв в GitLab CI

build: stage: build image: docker:24-dind services: - docker:24-dind variables: DOCKER_TLS_CERTDIR: "" script: # Пытаемся загрузить кэшированный образ - docker pull $CI_REGISTRY_IMAGE:cache || true # Собираем с кэшем - > docker build --cache-from $CI_REGISTRY_IMAGE:cache -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -t $CI_REGISTRY_IMAGE:cache . - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - docker push $CI_REGISTRY_IMAGE:cache

#Тестирование в Docker-контейнерах

#Unit-тесты в контейнере

# Dockerfile FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . # Запуск тестов по умолчанию CMD ["pytest", "tests/"]
# GitHub Actions - name: Run unit tests run: docker run --rm myapp:latest pytest tests/unit/ -v

#Интеграционные тесты с базами данных

# docker-compose.test.yml version: '3.8' services: app: build: context: . dockerfile: Dockerfile environment: - DATABASE_URL=postgresql://test:test@db:5432/testdb - REDIS_URL=redis://redis:6379/0 depends_on: - db - redis command: pytest tests/integration/ db: image: postgres:15-alpine environment: - POSTGRES_DB=testdb - POSTGRES_USER=test - POSTGRES_PASSWORD=test redis: image: redis:7-alpine
# Workflow - name: Run integration tests run: docker compose -f docker-compose.test.yml up --abort-on-container-exit

#End-to-End тесты с Selenium

# docker-compose.e2e.yml version: '3.8' services: app: build: . ports: - "8000:8000" environment: - DEBUG=true selenium: image: selenium/standalone-chrome:latest ports: - "4444:4444" shm_size: 2gb e2e-tests: build: context: . dockerfile: Dockerfile.e2e depends_on: - app - selenium environment: - BASE_URL=http://app:8000 - SELENIUM_URL=http://selenium:4444/wd/hub

#Работа с Docker-сетями в CI

#Создание изолированной сети для тестов

# Создать сеть docker network create test-network # Запустить контейнеры в сети docker run -d --network=test-network --name=db postgres:15 docker run --rm --network=test-network -e DB_HOST=db myapp:latest pytest

#В GitHub Actions

- name: Create test network run: docker network create test-net - name: Start database run: docker run -d --network=test-net --name=db -e POSTGRES_PASSWORD=test postgres:15 - name: Run tests run: docker run --rm --network=test-net -e DB_HOST=db myapp:latest pytest - name: Cleanup if: always() run: | docker stop db docker network rm test-net

#Отладка сбоев в CI

#Сохранение логов при неудаче

- name: Run tests id: tests run: docker run --rm myapp:latest pytest - name: Show container logs on failure if: failure() run: docker logs $(docker ps -aq --filter "ancestor=myapp:latest") | head -100

#Интерактивная отладка (для self-hosted runners)

- name: Debug on failure if: failure() run: | echo "Test failed. Container info:" docker ps -a --filter "ancestor=myapp:latest" docker logs $(docker ps -q --filter "ancestor=myapp:latest" | head -1)

#Best Practices

#1. Используйте конкретные теги базовых образов

# Плохо — тег может измениться FROM python:latest # Хорошо — фиксированная версия FROM python:3.11.7-slim # Лучше — SHA256 для полной воспроизводимости FROM python@sha256:abc123def456...

#2. Минимизируйте размер образов для тестов

# Используйте slim-образы для тестов FROM python:3.11-slim # Устанавливайте только необходимые зависимости RUN apt-get update && apt-get install -y --no-install-recommends \ gcc \ && rm -rf /var/lib/apt/lists/*

#3. Очищайте ресурсы после тестов

- name: Cleanup Docker if: always() run: | docker stop $(docker ps -aq) || true docker system prune -f --volumes

#4. Кэшируйте слои Docker

# Копируйте зависимости первыми для кэширования COPY requirements.txt . RUN pip install -r requirements.txt # Затем копируйте код COPY . .

#5. Используйте .dockerignore

# .dockerignore
.git
.gitignore
__pycache__
*.pyc
.pytest_cache
.coverage
htmlcov/
.env
.venv
node_modules

Далее: Работа с реестрами образов