我已经对我正在使用的较旧的系统进行了docker化。我有一个docker compose文件,它引用了一个基于postgres的图像和一个基于tomcat的图像。此撰写文件对于启动和停止应用程序的测试版本运行良好。
services:
db:
image: mypostgres
container_name: db
networks:
- mynetwork
tomcat:
image: mytomcat
container_name: tomcat
networks:
- mynetwork
environment:
- myhost=localhost
volumes:
- "mydata:/mydata"
depends_on:
- db
我还有一些其他命令行任务,我想在系统上执行。其中一些任务是计算密集型的。这些任务对mydata卷中的文件进行操作。
当前,我使用以下命令在tomcat容器中运行此任务。
docker exec tomcat /bin/my-script.sh param
我认为创建一个单独的容器来运行此任务可能很有意义。如果我将其定义为服务,则如下所示。
mycli:
image: mytomcat
networks:
- mynetwork
environment:
- myhost=tomcat
volumes:
- "mydata:/mydata"
depends_on:
- db
- mycli
entrypoint: /bin/myscript.sh
command:
- param
这种配置的最佳实践是什么?
docker-compose run
运行任务,则执行后退出的任务似乎仍然无处不在。答案 0 :(得分:1)
可以使用docker-compose定义这些任务吗?
否; docker-compose.yml
文件仅定义了长期运行的“服务”容器。无法定义在已经启动的容器上运行的其他docker exec
类型任务。原则上,您可以定义执行其工作单元并立即退出的其他“服务”,但是每次运行docker-compose up
时,它都希望重新运行所有这些服务。
数据初始化任务
如果您有一些需要在首次启动(例如预加载数据)或每次启动(例如数据库迁移)时运行的容器,则可以对容器进行结构设计,使其在主应用程序启动之前运行。我倾向于在入口点脚本中执行此类操作;它以容器的命令作为命令行参数,因此有机会根据正在运行的命令做出决定,进行所需的设置,然后实际启动命令。
#!/bin/sh
if [ "$1" = "theapp" ]; then
# Hypothetically: if we're starting theapp, run its migrations
# first before running the service itself
theapp migrate
fi
# Now do whatever the command is
exec "$@"
此模式的一个特别涉及的示例是mysql image's entrypoint:如果它正在启动数据库,并且数据目录不存在,则它将进行所有首次设置,并启动一个临时数据库服务器做到这一点。
我想执行的其他[...]任务
您可能会看到是否可以在受保护的“管理员” URL路径上或未在外部发布的单独端口上添加触发它们的网络调用。这样可以避免需要获得root shell来执行日常维护任务的问题。
否则,使用shell脚本自动执行任务及其参数将至少为您节省键入和存储的时间。