Docker踩坑记录:docker-compose启动容器,容器自动退出完整解决方案
问题
现在项目部署的时候一般会使用docker构建容器并进行部署。
之前的项目是直接docker run启动对应的镜像,然后进容器配置相关参数,或者直接挂载本地磁盘目录。但是最近一个项目甲方不会运维,要求能够一键启动,就想到用docker-compose来配置启动参数。
项目一共用到4个容器,前端(nginx)、后端(jdk)、数据库(mysql)、AI模型(python),但是在用docker-compose启动的时候,AI模型启动后会直接停止运行,添加restart=always参数后就一直重启,其他三个容器就没有这样的问题。
问题原因
我去网上翻了很多博客,最多的是让在yaml里面加tty=true,解释是用docker-compose启动的时候,如果容器主进程退出,就会导致容器退出。虽然添加参数后并没有解决我的问题,但是确实提供了解决思路。
我的模型用Flask写的接口,用gunicorn启动的,顺着网上的思路,一开始去掉了-D参数,改成前台阻塞运行,照理说如果是上述原因,应该已经可以解决了的,但是不得行。
然后去看了dockerhub上官方构建的配置,发现他们都会在最后开一个交互式命令行,阻塞在那里,我也学着在自己的Dockerfile里加了这个命令,同时搭配tty: true,最终解决了问题。
保持疑问
虽然解决了问题,但是还有两个疑问。
- 整体解决思路就是阻塞容器主进程,不让其退出。但是gunicorn去掉-D也是前台阻塞运行,为什么还是退了?
- 有解释说docker-compose里的command会覆盖dockerfile里的CMD,但是我jdk容器也写了command,而且还是nohup &执行的,为什么jdk的就可以,python的就不行
如果有懂的大佬,欢迎在评论区发言解决,非常感谢!
解决方案
code文件夹里面是我的代码
原版错误配置
FROM python:3.8.16
RUN mkdir /opt/code
ADD code /opt/code/
WORKDIR /opt/code
RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirement.txt
CMD gunicorn -b 0.0.0.0:8080 app:app
正确配置
关键是用python3进入交互式命令
FROM python:3.8.16
RUN mkdir /opt/code
ADD code /opt/code/
WORKDIR /opt/code
RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirement.txt
CMD gunicorn -b 0.0.0.0:8080 -D app:app && python3
关键yaml部分
version: '3'
services:
product-ai:
hostname: product-ai
restart: always
container_name: product-ai