如何在MariaDB容器中运行cron?

时间:2019-06-28 08:53:25

标签: docker docker-compose dockerfile

我想基于最新映像mariadb在MariaDB容器中包含cron任务,但我对此感到困惑。

由于无法同时启动MariaDB和Cron,我尝试了很多事情而没有成功。

这是我实际的dockerfile:

FROM mariadb:10.3

# DB settings
ENV MYSQL_DATABASE=beurre \
    MYSQL_ROOT_PASSWORD=beurette

COPY ./data /docker-entrypoint-initdb.d
COPY ./keys/keys.enc home/mdb/
COPY ./config/encryption.cnf /etc/mysql/conf.d/encryption.cnf

# Installations
RUN apt-get update && apt-get -y install python cron

# Cron
RUN touch /etc/cron.d/bp-cron
RUN printf '* * * * * root echo "Hello world" >> /var/log/cron.log 2>&1\n#' >> /etc/cron.d/bp-cron
RUN touch /var/log/cron.log
RUN chmod 0644 /etc/cron.d/bp-cron

RUN cron

使用其设置,数据库可以正确启动,但是“ Cron”未初始化。为了使其正常工作,我必须进入容器并执行“ Cron”命令,然后一切正常。

所以我正在寻找一种方法,可以从用于docker-compose的Dockerfile中启动db和cron。

如果这不可能,那么也许还有另一种方法来计划任务?目的是执行数据库的脚本。

2 个答案:

答案 0 :(得分:2)

详细介绍@ k0pernikus的评论,我建议使用运行cron的单独容器。然后,该容器中的cronjobs可以与您的mysql数据库一起使用。

这是我的处理方式:

1。创建一个Cron Docker容器

您可以非常简单地设置cron容器。这是应该执行此操作的示例Dockerfile:

FROM alpine
COPY ./crontab /etc/crontab
RUN crontab /etc/crontab
RUN touch /var/log/cron.log
CMD crond -f

只需将您的crontab放入该Dockerfile旁边的crontab文件中,您就应该有一个工作的cron容器。

示例crontab文件:

* * * * * mysql -h mysql --execute "INSERT INTO database.table VALUES 'v';"

2。将cron容器作为服务添加到您的docker-compose.yml

确保将cron容器添加到docker-compose.yml,并将其与mysql服务放置在同一网络中。

networks:
    my_network:
services:
    mysql:
        image: mariadb
        networks:
          - my_network
    cron:
        image: my_cron
        depends_on: 
          - mysql
        build:
            context: ./path/to/my/cron-docker-folder
        networks:
          - my_network

答案 1 :(得分:0)

我推荐solution provided by fjc。将其视为很容易理解的方法,以了解您的方法为何行不通。


Docker有RUN条命令仅在构建期间执行。不在容器启动时。

它还具有一个CMD(或ENTRYPOINT),用于执行特定的脚本。

由于您使用的是mariadb CMD,因此它是:

ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 3306
CMD ["mysqld"]

(您可以在dockerhub上找到指向实际dockerfles的链接。)

这告诉docker运行:

docker-entrypoint.sh mysqld

启动时。

您还必须覆盖其docker-entrypoint.sh才能启动cron作业。


See the relevant part of the Dockerfile for the CMD instruction

  

CMD CMD指令具有三种形式:

     

CMD [“ executable”,“ param1”,“ param2”](执行格式,这是首选   形式)CMD [“ param1”,“ param2”](作为ENTRYPOINT的默认参数)   CMD命令param1 param2(shell形式)只能有一个CMD   Dockerfile中的指令。如果您列出多个CMD,则仅   最后的CMD将生效。

     

CMD的主要目的是为执行提供默认值   容器。这些默认值可以包含可执行文件,也可以省略   可执行文件,在这种情况下,您必须指定一个ENTRYPOINT   指导。

     

注意:如果使用CMD为ENTRYPOINT提供默认参数   指令,CMD和ENTRYPOINT指令均应为   用JSON数组格式指定。

     

注意:exec表单被解析为JSON数组,这意味着您   必须在单词周围使用双引号(“),而不是单引号(')。

     

注意:与shell窗体不同,exec窗体不会调用命令   贝壳。这意味着正常的外壳处理不会发生。对于   例如,CMD [“ echo”,“ $ HOME”]不会在   $ HOME。如果要进行外壳处理,请使用外壳形式或   直接执行外壳程序,例如:CMD [“ sh”,“-c”,“ echo $ HOME”   ]。当使用exec表单并直接执行shell时,如   外壳形式的情况,就是外壳在做环境   变量扩展,而不是docker。

     

在shell或exec格式中使用时,CMD指令设置   运行图像时要执行的命令。

     

如果您使用CMD的外壳形式,则将执行   在/ bin / sh -c中:

     

FROM ubuntu CMD回声“这是一个测试。 | wc-如果您想运行    没有外壳,则必须将命令表示为JSON   数组并提供可执行文件的完整路径。该数组形式是   CMD的首选格式。任何其他参数必须是   分别表示为数组中的字符串:

     

FROM ubuntu CMD [“ / usr / bin / wc”,“-help”]如果您需要   容器每次都运行相同的可执行文件,那么您应该   考虑将ENTRYPOINT与CMD结合使用。请参阅ENTRYPOINT。

     

如果用户为docker run指定了参数,则它们将覆盖   CMD中指定的默认值。

     

注意:请勿将RUN与CMD混淆。 RUN实际上运行命令,   提交结果; CMD在生成时不执行任何操作,但是   指定用于图像的命令。