docker-compose启动容器后执行脚本或命令不退出 | 运行内部程序 - Marathon-Davis

时间:2024-03-12 13:46:23

docker-compose启动容器后执行脚本或命令不退出 | 运行内部程序

说下我的需求,就是在使用 docker-compose 启动server容器后,执行命令或者执行脚本运行容器内部的进程。

容器是个基于django框架的web server,通过uwsgi启动,我是这样操作的:

  • 1.在docker-compose.yaml文件中,在容器设置部分加入entrypoint: /root/path/xxx.sh,另外也编辑command: bash

  • 2.启动服务,docker-compose up -d,后台进程启动服务,

  • 3.查看服务,docker-compose ps,发现容器处于Restarting,换句话说,容器启动有问题,

  • 4.先停止服务,docker-compose stop

于是,我注释掉docker-composeentrypoint部分,然后docker-compose up -d,查看服务docker-compose ps,容器处于up状态,于是我通过exec命令在容器中执行相关命令,如下图:

可以看到uwsgi进程是起来了,本地测试web server的接口,

显然,这与我们的初衷不符,在 docker-compose 的时候,通常希望通过docker-compose up -d起来容器后,容器内部的应用程序就起来了,如果我们还需要通过exec,这种操作未免多余。

好在,docker还有个特别之处,我们可以通过 docker build 读取到 Dockerfile中的指令后,在构建新镜像再起容器的时候,可以直接执行脚本文件运行容器内部应用程序,同时不退出容器。

Dockerfile的设置:

# dockerfile to build image for docker-compose
FROM xxxxx/xxxserver-ubuntu16.04:1.0

MAINTAINER xxx@google.com.cn

ENV PYTHON 2.7

ENV DJANGO 1.11.5

LABEL version=1.1

WORKDIR /opt/big_factory/xxxserver

EXPOSE 9443

# 此处设置ENTRYPOINT,在创建容器的时候会运行此命令,执行脚本,起应用服务
ENTRYPOINT ["sh","/root/xxxserver/uwsgi_run.sh"] 

在对应的脚本文件中,这样设置:

#!/bin/bash

# run itpserver with uwsgi
/usr/local/bin/uwsgi -d --ini /opt/big_factory/xxxserver/xxxapi_uwsgi.ini

# never exit,此处是为了运行完上条应用服务后,有对应的前台进程
tail -f /dev/null

本文中的脚本文件用的是 tail 命令,当然也可以用其他的命令,如ping, top, sleep等,只不过tail相对系统开销小,而且/dev/null是个黑洞,啥都可以往里扔,也不显示。

接下来看看效果怎样。

docker build新镜像后,同样docker-compose up -d启动容器服务,查看容器状态docker-compose ps,进入容器并查看进程:

事实证明,确实有效。

上述操作,解决了 docker-compose 启动容器时,运行脚本文件来起容器内部的应用程序,且容器正常运行up的需求。

总结
如果我们通过 docker-compose 运行容器,并运行内部应用服务的话,可以按照以下设置进行操作:

  • 1.编写Dockerfile,在文件中设置ENTRYPOINT指令,一般可以执行启动应用的脚本文件,脚本文件最后应该有不退出的命令,如tail/top/ping等,然后通过docker build -t name:tag .创建新的镜像

  • 2.编写docker-compose.yml/yaml文件,内部指定基于Dockerfile创建的镜像

  • 3.通过 docker-compose up -d启动容器

---------------------------------------------------------------------------------
此处对于 CMD | commandENTRYPOINT | entrypoint 在 dockerfile 和 docker-compose 并未详细涉及,详情请看以下博文:
docker容器之dockerfile&docker-compose CMD/entrypoint详解