Как наиболее эффективно организовать контейнеры для тестовой и производственной среды?

Добрый день! У меня возникла проблема: <br/> в процессе использования GitLab CI/CD я собираю бэкенд проекта и деплою его в контейнерах в локальной сети. У меня есть два контейнера: один для продакшна, который собирается на ветке main, и второй - тестовый, собираемый на ветке development (тестовый контейнер имеет имя с окончанием _test). Шаги сборки включают: build - сборку контейнера (в данный момент тестовый и продакшн контейнеры собираются отдельно с разными названиями), затем push_to_local_registry, где также используются разные контейнеры, и, наконец, run_container. У меня есть ощущение, что данная организация неверная, и что должен существовать один контейнер с разными версиями. Однако, насколько я знаю, в Docker нельзя запустить несколько контейнеров с одинаковым именем, даже если они имеют разные версии. Мне необходимо, чтобы оба контейнера - продакшн и тест - работали одновременно. В связи с этим, я хотел бы уточнить, как правильно организовать тестовую и продакшн версии в контейнерах. Я немного запутался в том, как это должно выглядеть наилучшим образом, чтобы при переходе с теста на продакшен контейнер не создавался заново, а лишь запускался на продакшн портах и с соответствующими переменными окружения.
  • 10 марта 2025 г. 9:54
Ответы на вопрос 2
Для эффективной организации контейнеров для тестовой и производственной среды с использованием Docker и CI/CD, вам стоит учесть несколько важных моментов, которые помогут вам избежать дублирования и упростить управление версиями. Вот несколько рекомендаций:

### 1. Использование тегов для версий контейнеров
Вместо создания двух различных образов (production и test), вы можете использовать один и тот же образ и просто применять разные теги. Например, вы можете собирать образ с тегами `your-image:latest`, `your-image:development` и другими значениями (например, с указанием версии). Это позволяет вам использовать один и тот же репозиторий, и в зависимости от окружения (тестовое или продакшн) для запуска использовать конкретный тег.

### 2. Использование docker-compose
Если вы еще не используете `docker-compose`, рекомендуется рассмотреть его. С помощью него вы можете создать четкую структуру для управления как тестовым, так и производственным окружением, определяя разные сервисы в одном файле `docker-compose.yml`. Вы можете переопределять настройки (например, порты и переменные окружения) через дополнительные файлы конфигурации.

#### Пример `docker-compose.yml`:
```yaml
version: '3.8'

services:
  app:
    image: your-image:latest
    ports:
      - "80:80" # Для продакшна
    environment:
      - ENV=production

  app_test:
    image: your-image:latest
    ports:
      - "8080:80" # Для тестов
    environment:
      - ENV=development
```

Затем, вы можете запускать контейнеры с помощью `docker-compose up -d` для продакшн и `docker-compose -f docker-compose.test.yml up -d` для тестирования, если используете отдельную конфигурацию.

### 3. Управление средой с помощью переменных окружения
Настраивайте ваши контейнеры с помощью переменных окружения, чтобы контролировать их поведение: при запуске контейнеров задавайте разные окружения, чтобы они знали, в какой среде они работают. Это поможет избежать дублирования кода и настройки.

### 4. CI/CD pipeline в GitLab
Оптимизируйте ваш CI/CD pipeline, чтобы он мог осуществлять сборку и развертывание в зависимости от ветки:

```yaml
stages:
  - build
  - push
  - deploy

build:
  script:
    - docker build -t your-image:$CI_COMMIT_REF_NAME .

push:
  script:
    - docker push your-image:$CI_COMMIT_REF_NAME

deploy_prod:
  stage: deploy
  only:
    - main
  script:
    - docker run -d --name app -p 80:80 --env-file .env.prod your-image:main

deploy_test:
  stage: deploy
  only:
    - development
  script:
    - docker run -d --name app_test -p 8080:80 --env-file .env.dev your-image:development
```

### 5. Документация и автоматизация
Храните всю вашу документацию по сетапу и настройке окружений в репозитории, чтобы в случае необходимости другие участники команды могли быстро понять структуру и настройки.

### Вывод
Используя один образ с тегами, `docker-compose`, переменные окружения и CI/CD pipeline, вы сможете значительно упростить управление тестовой и продакшн средами, поддерживая возможность одновременного запуска как тестовых, так и производственных контейнеров. Это сделает вашу инфраструктуру более гибкой и удобной для разработки и деплоя.
Лучше для чего именно? Сейчас у вас всё работает нормально и проблем нет? Значит и нечего тут менять. Есть какая-то проблема? Тогда озвучивайте свою конкретную проблему и тогда уже можно будет думать как её решить с минимальными усилиями. 

я немного потерялся с тем, как это должно быть устроено "по уму" в идеале, чтобы при переходе с теста на прод, контейнер не создавался заново, а просто запускался на продакшн портах и с продакшн переменными окружения

При переходе где, откуда и куда? Остановить тестовый контейнер и запустить продакшен? Ну так у вас же уже есть два отдельных контейнера - просто заранее делаете сборку, а уже потом запускаете что надо и когда надо. В целом логика обычно такая: делается базовый контейнер с нужными зависимостями, далее на базе этого контейнера собираются остальные - тестовый, стэйж, прод со своими отдельными зависимостями. Далее уже зависит от логики вашего приложения и его особенностей - к контейнеру монтируется внешний каталог с ресурсами или приложением, либо собирается финальный контейнер вместе с вашим приложением полностью внутри него.
Похожие вопросы