【问题标题】:How to run cron and web application in same container?如何在同一个容器中运行 cron 和 Web 应用程序?
【发布时间】:2021-01-18 20:14:30
【问题描述】:

我是 docker 新手。我几乎没有将我的 php 应用程序容器化以在 Web 界面中运行它。但我有一些 cron 可以运行它。我学会了如何创建单独的 cron 映像并从 How to run a cron job inside a docker container? 运行它。但我的用例不同。 我需要使用我的 php 应用程序容器中的 php 文件,这在我看来是不可能的。我尝试如下创建 docker-compose.yml 以查看它是否可以工作

docker-compose.yml:

    version: "3"
    
    services:
        app:
          build:
            context: ./docker/php
    container_name: 'app'
    restart: 'always'
    ports:
       - "80:80"
       - "443:443"
    links:
       - db
    volumes:
       - ${DOCUMENT_ROOT-./src}:/var/www/html
       - ${PHP_INI-./docker/php/php.ini}:/usr/local/etc/php/php.ini
       - ${VHOSTS_DIR-./docker/apache2/vhosts}:/etc/apache2/sites-enabled
       - ${LOG_DIR-./docker/logs/apache2}:/var/log/apache2
    extra_hosts:
       - "test.local:127.0.0.1"
    hostname: cloudservice.local
    domainname: local
    #entrypoint: sh /var/www/html/cron.sh

正如我在这里评论的入口点,如果我做 docker-compose up,一切正常,我的 Dockerfile 如下

Dockerfile:

    FROM php:7.2.27-apache
    
    RUN apt-get update
    RUN apt-get install -y cron
    RUN apt-get -y update --fix-missing
    RUN apt-get upgrade -y
    
    # Install useful tools
    RUN apt-get -y install apt-utils nano wget dialog
    
    # Install important libraries
    RUN apt-get -y install --fix-missing apt-utils build-essential git curl libcurl4 libcurl4-openssl-dev zip
    
    # Composer
    RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
    
    # Install xdebug
    #RUN pecl install xdebug-2.5.0
    #RUN docker-php-ext-enable xdebug
    
    # Other PHP7 Extensions
    
    RUN apt-get -y install libsqlite3-dev libsqlite3-0 default-mysql-client
    RUN docker-php-ext-install pdo_mysql 
    RUN docker-php-ext-install pdo_sqlite
    RUN docker-php-ext-install mysqli
    
    RUN docker-php-ext-install curl
    RUN docker-php-ext-install tokenizer
    RUN docker-php-ext-install json
    
    RUN apt-get -y install zlib1g-dev
    RUN docker-php-ext-install zip
    
    RUN apt-get -y install libicu-dev
    RUN docker-php-ext-install -j$(nproc) intl
    
    RUN docker-php-ext-install mbstring
    
    RUN apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev
    RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ 
    RUN docker-php-ext-install -j$(nproc) gd
    
    RUN pecl install redis-5.1.1 \
        && docker-php-ext-enable redis
    
    # Enable apache modules
    RUN a2enmod rewrite headers

我的 cron.sh 文件如下

#!/usr/bin/env bash

# Ensure the log file exists
touch /var/www/html/logs/crontab.log

# Ensure permission on the command
chmod a+x /var/www/html/cron-local/hn-shc-rapid-daily.sh

# Added a cronjob in a new crontab
echo "* * * * * bash /var/www/html/cron-local/hn-shc-rapid-daily.sh >> /var/www/html/logs/crontab.log 2>&1" > /etc/crontab

# Registering the new crontab
crontab /etc/crontab

# Starting the cron
/usr/sbin/service cron start

# Displaying logs
# Useful when executing docker-compose logs mycron
tail -f /var/www/html/logs/crontab.log

但是在入口点被注释后,我无法运行 cron。如果我不评论入口点,那么 cron 会运行,我的 Web 应用程序不会。有没有办法解决这个问题?

谢谢

【问题讨论】:

    标签: php docker docker-compose cron dockerfile


    【解决方案1】:

    我认为如果在 docker-compose 文件中指定入口点而不在其前面添加“sh”,会更好。请记住,在 docker-compose 文件中声明新的入口点会覆盖 dockerfile 中的入口点。 Link

    我建议您创建自己的入口点脚本,它将在容器 CMD ["/entrypoint.sh"] 中执行您的 crons

    例子:

    创建一个文件并命名为“entrypoint.sh”或其他名称,并将其保存在 Dockerfile 所在的同一文件夹中。在此文件中,从您的 cron.sh 推送您的内容。

    RUN apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev
    RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ 
    RUN docker-php-ext-install -j$(nproc) gd
    
    RUN pecl install redis-5.1.1 \
            && docker-php-ext-enable redis
        
    # Enable apache modules
    RUN a2enmod rewrite headers
    
    COPY entrypoint.sh /
        
    RUN chmod +x /entrypoint.sh
    
    CMD ["/entrypoint.sh"]
    

    但您也可以直接在 docker 文件中添加您的 cron。

    ...
    # Enable apache modules
    RUN a2enmod rewrite headers
    
    COPY your-cron.cron /
        
    RUN crontab /your-cron.cron 
    ...
    

    【讨论】:

    • 感谢您的建议,但我不知道该怎么做。但我尝试在 dockerfile 末尾添加 CMD sh /var/www/html/cron.sh && /usr/sbin/apache2ctl -D FOREGROUND 但只有 cron 正在运行
    • 是的,我对你的回答做了一些调整,我能够让它工作。非常感谢
    • 你能解释一下你必须改变什么吗?
    • 我已经在下面发布了我的答案。
    【解决方案2】:

    在 docker 文件的末尾,我在删除后添加了以下代码

    运行 a2enmod 重写标头

        # Copy hello-cron file to the cron.d directory
        COPY hello-cron /etc/cron.d/hello-cron #just any name
    
        # Give execution rights on the cron job
        RUN chmod 0644 /etc/cron.d/hello-cron
    
        # Apply cron job
        RUN crontab /etc/cron.d/hello-cron
    
        # Create the log file to be able to run tail
        RUN touch /var/log/cron.log
    
        # Enable apache modules
        RUN a2enmod rewrite headers
        
        CMD cron && /usr/sbin/apache2ctl -D FOREGROUND
    

    而 cron.sh 改为

        * * * * * echo "hello world" >> /var/www/html/logs/crontab.log 2>&1
    

    这对我有用。我不需要在 docker-compose 和 docker 文件上添加条目,但我猜 entry 也可以。 我不知道这是否是正确的做法。如果有人能给我更高级的想法,我很乐意尝试一下。 谢谢

    【讨论】:

    • 我也面临同样的问题!!你能把你的 yml、dockerfile 和 cron.sh 文件连同它们的位置一起发布吗?我知道有很多问题要问,但我认为你真的可以提供帮助!!。
    • 它已经发布在这里,或者您可以将实时编辑器链接发送给我,我会将所有内容粘贴到那里。谢谢
    猜你喜欢
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多