Запуск команд Makefile в качестве cronjob в Windows Docker Desktop, а не на сервере Linux Fedora.

Вопрос или проблема

Я создаю несколько крон-задач, которые используют команду “make” для выполнения скриптов на python. Эти крон-задачи выполняются внутри контейнера Docker. Я могу запускать свои крон-задачи с помощью команды make внутри своего контейнера, когда использую Docker Desktop на своем ноутбуке с Windows, и команды вроде * * * * * cd /code && make help возвращают ожидаемый вывод, который является эхо-выводом всех доступных команд make для моего проекта. Я протестировал эти крон-задачи и на Mac, где они также сработали. Однако, когда я пытаюсь запустить ту же крон-задачу на ноутбуке с Linux, работающем на “Fedora Server”, у меня не получается заставить “make” работать правильно (это физический компьютер, а не виртуальная машина).

Крон-задачи запускаются из директории “/etc/crontabs/root” внутри контейнера. Крон-задача * * * * * cd /code && make help, выполняемая внутри моего контейнера Docker на установке Linux, дает ответ crond: USER root pid 132 cmd cd /code && make help '. Stop. No rule to make target 'help.

Основные крон-задачи, такие как * * * * * echo 'Hello world', выводят ожидаемый ответ на обеих машинах. Я также могу вручную запускать команды make на любом компьютере в директории “/code”, такие как make help.

Я экспортирую папку проекта с ноутбука с Windows в директорию “notroot@localhost:~/compose”, которая принадлежит непользователю root на моем ноутбуке с Linux, используя клиент FileZilla (любые советы по лучшим способам это сделать будут очень приветствоваться). Я использую “docker compose” для создания и запуска своих контейнеров из директории “notroot@localhost:~/compose/xcron”.

Структура моего проекта выглядит следующим образом:

/xcron
 - .env
 - requirements.txt
 - Makefile
 - /api
   - /spotify
      - ...
   - /leetcode
      - ...
 - ...

Мой файл compose, docker-compose.yml:

services:
  xcron-app:
    container_name: xcronapp
    restart: always
    build: .
    networks:
      - xcron_db_network
      - xcron_web_network
    volumes:
      - xcronvol:/code
  db:
    container_name: xcronpostgres
    image: postgres
    restart: always
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: ${DB_NAME}
    volumes:
      - postgresvolume:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME} -d ${DB_NAME}"]
      interval: 10s
      retries: 5
      start_period: 30s
      timeout: 10s
    networks:
      - xcron_db_network
networks:
  xcron_db_network:
    driver: bridge
  xcron_web_network:
    driver: bridge
volumes:
  xcronvol:
  postgresvolume:

Dockerfile, используемый в моем проекте, представлен ниже. Есть некоторые файлы, которые не копируются из проектных файлов, такие как папка python venv, которая никогда не предназначалась для использования внутри контейнеров. Dockerfile:

FROM alpine:latest

COPY config/cronjobs /etc/crontabs/root

COPY requirements.txt /etc/requirements/requirements.txt

ENV PYTHONUNBUFFERED=1
RUN apk add --update --no-cache python3 py3-pip make bash util-linux vim && ln -sf python3 /usr/bin/python

COPY .env /code/.env
COPY api /code/api
COPY auth /code/auth
COPY migrations/down /code/migrations/down
COPY migrations/up /code/migrations/up
COPY migrations/down.py /code/migrations/down.py
COPY migrations/up.py /code/migrations/up.py
COPY tweets /code/tweets
COPY Makefile /code/Makefile

RUN python3 -m venv /opt/venv

ENV PATH="/opt/venv/bin:$PATH"

RUN pip install -r /etc/requirements/requirements.txt

RUN chmod 777 /etc/crontabs/root

WORKDIR /code

CMD ["crond", "-f", "-d", "8"]

После запуска ‘docker compose up’, мои файлы внутри контейнера Docker структурированы так же, как и раньше (за исключением файлов, которые были проигнорированы в Dockerfile), но базовая папка теперь называется “code”.

/code
 - .env
 - Makefile
 - /api
   - /spotify
      - ...
   - /leetcode
      - ...
 - ...

Я пробовал добавлять права доступа внутри моего контейнера Docker к моим файлам, используя chmod 777 <имя_файла> на моем “code/Makefile”, “code/.env” файле, “/etc/crontabs/root”. Я пробовал изменять мою крон-задачу с абсолютными путями, такими как /usr/bin/make -C /code help“, а также множество вариаций флагов “-C” и “-f”. Я пробовал запускать команды в своей рабочей директории cd /code && make -f /code/Makefile help и выходить из “root”, откуда, как я полагал, запускались мои крон-задачи cd .. && make -f /code/Makefile -C /code help.

Я пытался запускать крон-задачи через bash явно /bin/bash -c 'cd /code && make help'.

Результаты вывода этих крон-задач остаются прежними crond: USER root pid 123 cmd /usr/bin/make -C /code help '. Stop. No rule to make target 'help.

Ответ или решение

Решение проблемы выполнения команд Makefile в cronjob под Docker на Fedora Server

Ваша ситуация иллюстрирует распространённую проблему при работе с cronjob и Docker, особенно в контексте различий между ОС. Вы описали, что команда make help работает безупречно в Docker на Windows и macOS, но выдаёт ошибку при выполнении на Fedora Server. Давайте разберемся, в чём может быть причина и как это можно исправить.

1. Проверка структуры Makefile

Первым делом убедитесь, что ваш Makefile действительно содержит цель help. Для этого откройте Makefile и проверьте наличие следующей записи:

help:
    @echo "Available commands:"
    @echo "  help"
    ...

Затем попробуйте выполнить команду make help вручную внутри вашего Docker-контейнера, чтобы убедиться, что всё работает правильно.

2. Путь к Makefile и рабочая директория

Проблема может быть связана с тем, как cron выполнит команды. Cron запускает команды в чистом окружении, и это может повлиять на то, где и как он ищет ваш Makefile. Убедитесь, что вы используете абсолютный путь к Makefile, а также укажите полный путь к директории /code.

Попробуйте изменить вашу строку cron на:

* * * * * cd /code && /usr/bin/make -f /code/Makefile help

Также можете использовать флаг -C:

* * * * * /usr/bin/make -C /code help

3. Проверка прав доступа

Проверьте, что все файлы и директории имеют необходимые права доступа. Вы уже применили chmod 777, но важно убедиться, что эта команда была выполнена успешно. Также проверьте, не происходит ли сбой из-за ограничений SELinux, который может блокировать доступ к файлам.

4. Запуск cron с отладкой

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

docker logs xcronapp

Это позволит вам увидеть любые ошибки, возникающие при выполнении cron job’ов.

5. Переменные окружения

Обратите внимание, что cron может не передавать переменные окружения, установленные в вашем контейнере. Если ваш Makefile полагается на какие-либо переменные окружения, это может вызвать проблему. Убедитесь, что все необходимые переменные окружения определены непосредственно в командной строке или в скрипте, который вызывает make.

6. Альтернативный способ работы с файлами

Если вы считаете, что использование FileZilla для передачи файлов не оптимально, вы можете использовать команду rsync для более быстрых и эффективных операций.

rsync -avz /path/to/source/ user@destination:/path/to/target/

Это может сократить время передачи и гарантировать целостность данных при перемещении файлов между системами.

Заключение

Следуя данным рекомендациям, вы сможете устранить проблему с выполнением команд Makefile в ваших cronjob под Docker на Fedora Server. Изучите структуру Makefile, убедитесь в корректности путей, проверьте права доступа и исследуйте логи для диагностики. Старайтесь поддерживать порядок в ваших cronjob’ах, используя явные пути и необходимые переменные окружения. Удачи в вашей работе!

Оцените материал
Добавить комментарий

Капча загружается...