我想基于最新映像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。
如果这不可能,那么也许还有另一种方法来计划任务?目的是执行数据库的脚本。
答案 0 :(得分:2)
详细介绍@ k0pernikus的评论,我建议使用运行cron的单独容器。然后,该容器中的cronjobs可以与您的mysql数据库一起使用。
这是我的处理方式:
您可以非常简单地设置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';"
确保将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在生成时不执行任何操作,但是 指定用于图像的命令。