Dockerfile,制作多个命令(CMD)但等待数据库提示?

Posted

技术标签:

【中文标题】Dockerfile,制作多个命令(CMD)但等待数据库提示?【英文标题】:Dockerfile, make multiple commands (CMD) but waiting for DB prompt? 【发布时间】:2019-11-10 00:56:42 【问题描述】:

所以我正在制作一个 dockerfile,我希望它设置一个项目并在此之后导入一个数据库。我正在使用 XAMPP 和包含的 MariaDB。我知道我需要使用 CMD 进行导入,因为 XAMPP 必须运行。我正在尝试通过运行在 DB 提示符中执行该工作的 sql 脚本来导入数据库。

我尝试使用 && 和 ;用于在单行中链接命令,但它不起作用,因为它会在等待 MariaDB 提示之前尝试在终端提示上运行所有命令。有什么想法吗?

这是我的 docker 文件,最后一行是我尝试导入数据库:

FROM cswl/xampp

COPY . /opt/lampp/htdocs/

WORKDIR /opt/lampp/htdocs/

RUN curl -sS https://getcomposer.org/installer | /opt/lampp/bin/php &&\
  /opt/lampp/bin/php composer.phar install

RUN curl https://s3.amazonaws.com/careers-picpay/lista_relevancia_1.txt --output db/lista_relevancia_1.txt &&\
  curl http://s3.amazonaws.com/careers-picpay/lista_relevancia_2.txt --output db/lista_relevancia_2.txt &&\
  curl https://s3.amazonaws.com/careers-picpay/users.csv.gz --output db/users.csv.gz

RUN gzip -d db/users.csv.gz

CMD /opt/lampp/bin/mysql -u root && source ./initdb.sql

更新: 因此,我还尝试用 MariaDB -e 选项替换我的两个命令,以便在登录后执行一行……没有用,没有创建数据库,我不知道为什么。这是命令:

CMD /opt/lampp/bin/mysql -u root -e "source ./initdb.sql"

【问题讨论】:

通常您会在一个容器中运行数据库,而在另一个容器中运行使用它的应用程序 (XAMPP)。这被认为是不好的做法,并且在单个容器中运行多个进程是有问题的。根据我的经验,在容器中协调数据库初始化也很有挑战性。我怀疑您的 CMD 正在启动 mysql 进程并且没有进一步的进展。 【参考方案1】:

已编辑

使用 MariaDB 官方镜像,只需复制目录 /docker-entrypoint-initdb.d 中的初始化脚本 (initdb.sql)。 见MariaDB Docker Quick Reference。该目录中的文件在创建和初始化容器时按字母顺序执行。

对于 XAMPP 映像,您似乎必须手动执行此操作。这绝对不是一个优雅的解决方案,但它应该可以工作。

用这个替换图片的ENTRYPOINT脚本:

#!/bin/bash

/opt/lampp/lampp start

# wait for mysql to be ready
while ! /opt/lampp/bin//mysql --protocol TCP  -e "show databases;"; do sleep 2; done

# initialize the database
/opt/lampp/bin/mysql -u root -e "source /init.sql"

## Run tail so we don't exit
/usr/bin/tail -f /opt/lampp/logs/php_error_log

这将等待mysql 准备就绪,然后再执行source 命令。

Dockerfile下面添加复制初始化sql脚本并覆盖ENTRYPOINT

FROM cswl/xampp
...

COPY init.sql /init.sql

COPY init.sh /init.sh
RUN chmod +x /init.sh

ENTRYPOINT  ["/init.sh"]

【讨论】:

这仅适用于 MariaDB 官方镜像。正如您在我的 Dockerfile 中看到的,我使用的是非官方 XAMPP 映像。 我不知何故错过了这一点。这不是一个真正有用的答案,我对其进行了编辑。【参考方案2】:

您可以使用wait-for-it.sh 将其添加到CMD 以检查DB 是否已启动:

CMD ["path/to/wait-for-it.sh", "localhost:3306", "-t", "6000", "--", "YOUR ACTUAL COMMAND"]

您可以先将脚本复制到您的容器中。

这里是more info

【讨论】:

以上是关于Dockerfile,制作多个命令(CMD)但等待数据库提示?的主要内容,如果未能解决你的问题,请参考以下文章

dockerfile CMD执行多条命令且需要支持环境变量

dockerfile指令汇总

云原生-Dockerdocker镜像制作上传dockerfile命令解析

docker中entrypoint 和 CMD的执行总结

Docker镜像制作!

Docker镜像制作!