Как создать Docker-контейнер для проекта на Yii2, который будет поддерживать выполнение задач cron?

У меня есть проект на Yii2, который организован по контейнерам (например, backend, frontend и т. д.), и я хочу раз в сутки запускать консольную команду, например, <code class="bash">php yii cron/midnight</code>. Для этого мне нужно добавить в мой docker-compose новый микросервис в виде отдельного контейнера, который будет подхватывать файл с описанием cron-сценариев, хранящийся в репозитории проекта, и обрабатывать их внутри себя. <br/> <br/> Однако, несмотря на то что задача кажется простой, мне трудно добиться логирования выполнения заданий по cron. Несмотря на то что контейнер с cron запускается, ожидаемых результатов от его работы нет. <br/> <br/> Можете ли вы подсказать простую реализацию такого cron-контейнера, который мог бы выполнять задания в php yii по расписанию?
  • 21 марта 2025 г. 10:15
Ответы на вопрос 2
Конечно! Для реализации cron-контейнера в Docker для проекта на Yii2, вы можете следовать следующему плану. В данном примере мы создадим новый контейнер, который будет использовать `cron` в Linux для выполнения команды `php yii cron/midnight`.

Вот шаги, которые помогут вам добиться работы cron-системы:

1. **Создайте Dockerfile для cron-контейнера**: 

Создайте файл `Dockerfile.cron` в корне вашего проекта:

```dockerfile
FROM php:8.0-cli

# Установка необходимых расширений и утилит
RUN apt-get update && apt-get install -y \
    cron \
    && docker-php-ext-install pdo pdo_mysql

# Копируем проект и конфиг файл cron
COPY ./ /app
WORKDIR /app

# Копируем crontab файл
COPY ./crontab /etc/cron.d/my-cron

# Устанавливаем права
RUN chmod 0644 /etc/cron.d/my-cron

# Применяем crontab
RUN crontab /etc/cron.d/my-cron

# Создаем директорию для логирования
RUN touch /var/log/cron.log

# Запускаем cron в фоновом режиме и сохраняем логи
CMD cron && tail -f /var/log/cron.log
```

2. **Создайте файл crontab**:

Создайте файл `crontab` в корне вашего проекта:

```
# Каждую ночь в полночь
0 0 * * * php /app/yii cron/midnight >> /var/log/cron.log 2>&1
```

Каждая строка в этом файле это отдельное задание cron. Здесь указано, что команда будет запускаться каждый день в полночь. Логирование будет происходить в файл `/var/log/cron.log`, что позволит вам отслеживать выполнение задач.

3. **Измените docker-compose.yml**:

Теперь обновите ваш файл `docker-compose.yml`, чтобы добавить новый контейнер для cron:

```yaml
version: '3.7'

services:
  backend:
    build:
      context: .
      dockerfile: Dockerfile
    # ваши настройки...

  frontend:
    build:
      context: .
      dockerfile: Dockerfile.frontend
    # ваши настройки...

  cron:
    build:
      context: .
      dockerfile: Dockerfile.cron
    volumes:
      - ./:/app
    # можно добавить другие настройки, такие как network или environment, если нужно
```

4. **Запустите контейнеры**:

Теперь вы можете запустить ваши контейнеры с помощью команды:

```bash
docker-compose up -d
```

5. **Проверка логов**:

После запуска контейнера, вы можете проверить логи, выполнив следующую команду:

```bash
docker-compose logs -f cron
```

Это позволит вам увидеть, что происходит в процессе выполнения заданий cron.

### Дополнительные советы:
- Убедитесь, что все зависимости вашего проекта (например, базы данных) доступны для cron-контейнера.
- Если ваши задачи требуют определенных переменных окружения, не забудьте передать их в `docker-compose.yml`.
- В случае проблем с выполнением команд, вы можете отлаживать, добавляя временные команды или тесты, чтобы проверить доступность необходимых компонентов (базы данных, PHP-скриптов и т.д.).

С помощью указанного подхода, вы сможете организовать и управлять задачами cron в вашем проекте на Yii2 в контейнерах Docker.
Как вариант настроить кронтаб в хостовой системе, который в контейнере докера будет дергать команду. 
Что-то вроде:

docker exec -i <backend docker container> bash -c "php yii cron/midnight"
Похожие вопросы