我已经使用了一个我工作的旧系统 . 我有一个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
这些任务可以用docker-compose定义吗?
我认为创建一个单独的容器来运行此任务是有意义的 . 如果我将其定义为服务,它将如下所示 .
mycli:
image: mytomcat
networks:
- mynetwork
environment:
- myhost=tomcat
volumes:
- "mydata:/mydata"
depends_on:
- db
- mycli
entrypoint: /bin/myscript.sh
command:
- param
这种配置的最佳实践是什么?
将此添加到撰写文件似乎很好
-
长时间运行的任务在一个单独的容器中运行 .
-
很好地定义了任务的可用性 .
-
这可能是执行数据初始化任务的好方法 .
将此添加到撰写文件中似乎很糟糕
-
启动服务时必须执行某些操作 . 该操作完成后,容器处于退出状态 .
-
如果我使用
docker-compose run
运行任务,退出的任务似乎在执行后就会挂起 .
1 回答
没有;
docker-compose.yml
文件仅定义长时间运行的"service"容器 . 无法定义您在已启动容器上运行的其他docker exec
类型任务 . 您原则上可以定义执行其工作单元的其他"services"并立即退出,但每次运行docker-compose up
时,它都希望重新运行所有这些工作 .如果您有第一次启动时需要运行的东西(如预加载数据)或每次启动(可能是数据库迁移),您可以构建容器,使其在主应用程序启动之前运行 . 我倾向于在入口点脚本中做这种事情;它将容器的命令作为命令行参数,因此它有机会根据正在运行的命令做出决定,执行所需的设置,然后实际启动命令 .
这个模式的一个特别涉及的例子是mysql image's entrypoint:如果它已经存在,那么它会进行所有首次设置,在执行此操作时启动临时数据库服务器 .
您可能会看到是否可以添加触发它们的网络调用,可以是受保护的“admin”URL路径,也可以是未在外部发布的单独端口 . 这样可以避免需要root shell进行日常维护任务的问题 .
如果做不到这一点,用于自动执行任务及其参数的shell脚本至少可以节省一些打字和记忆 .