在Docker容器启动中运行多个命令

时间:2018-10-05 21:40:34

标签: docker ubuntu ejabberd

我有一个简单的docker映像,它基于CMD为"/sbin/ejabberdctl foreground"的dockerfile在ubuntu 16.04上运行。为了使Docker容器一旦启动就保持活动状态,我曾经在前台运行ejabberd服务器。但是,在启动容器和/sbin/ejabberdctl之后,一旦ejabberdctl已经运行(例如ejabberdctl list_cluster),我就需要执行另一个命令。 试图将两个命令都添加到bash脚本中,但是它不起作用。尝试运行/sbin/ejbberdctl start &,但也没有用。 哪种挖掘方式?

3 个答案:

答案 0 :(得分:1)

选项A: 创建一个运行容器和list_cluster的简单bash脚本,而无需修改ejabberd docker映像的入口点。

#!/bin/bash
if [ "${1}" = "remove_old" ]; then
    echo "removing old ejabberd container"
    docker rm -f ejabberd
fi
    docker run --rm --name ejabberd -d -p 5222:5222 ejabberd/ecs
    sleep 5
    echo -e "*******list_cluster******"
    docker exec -it ejabberd ash -c "/home/ejabberd/bin/ejabberdctl list_cluster"

enter image description here 选项B

在选项B中,您需要修改ejabberd官方映像入口点,因为它不允许您在启动时运行多个脚本。因此,在稍加修改的情况下在启动时添加脚本。

https://github.com/processone/docker-ejabberd/blob/master/ecs/Dockerfile

我建议使用ejabberd仅 30 MB 的官方高山映像,而不要使用Ubuntu。 https://hub.docker.com/r/ejabberd/ecs/

这里也可以为Ubuntu修改该演示,但这已针对高山ejabberd官方映像进行了测试。

使用 ejabberd官方映像作为基本映像,如果您对群集感兴趣,则ENV MASTER_NODE=ejabberd@ec2-10.0.0.1用于主节点。

From ejabberd/ecs:latest
USER root
RUN whoami
COPY supervisord.conf  /etc/supervisord.conf
RUN apk add supervisor
RUN mkdir -p /etc/supervisord.d 
COPY pm2.conf  /etc/supervisord.d/ejabberd.conf
COPY start.sh  /opt/ejabberd/start.sh
RUN chmod +x /opt/ejabberd/start.sh
ENV MASTER_NODE=ejabberd@ec2-10.0.0.1
ENTRYPOINT ["supervisord", "--nodaemon", "--configuration", "/etc/supervisord.conf"]

现在创建 supervisors config 文件

[unix_http_server]
file = /tmp/supervisor.sock
chmod = 0777
chown= nobody:nogroup

[supervisord]
logfile = /tmp/supervisord.log
logfile_maxbytes = 50MB
logfile_backups=10
loglevel = info
pidfile = /tmp/supervisord.pid
nodaemon = true
umask = 022
identifier = supervisor

[supervisorctl]
serverurl = unix:///tmp/supervisor.sock

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[include]
files = /etc/supervisord.d/*.conf

现在创建 ejabberd.conf 以使用 supervisorsd 启动ejabberd。请注意,如果您想加入集群,这里的join cluster参数用于加入集群。如果不需要,请将其删除。

[supervisord]
nodaemon=true
[program:list_cluster]
command: /opt/ejabberd/start.sh join_cluster
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0

[program:ejabberd]
command=/home/ejabberd/bin/ejabberdctl foreground
autostart=true
priority=1
autorestart=true
username=ejabberd
exitcodes=0 , 4

一个/opt/ejabberd/start.sh bash脚本,一旦ejabberd启动,它将 list_cluster ,并且如果在调用脚本时传递了参数,也可以 join_cluster

#!/bin/sh
until nc -vzw 2 localhost 5222; do sleep 2 ;echo -e "Ejabberd is booting....."; done

if [ $? -eq 0 ]; then

########## Once ejabberd is up then list the cluster ##########
    echo -e "***************List_Cluster start***********" 
    /home/ejabberd/bin/ejabberdctl list_cluster
    echo -e "***************List_Cluster End***********" 
########## If you want to join cluster once up as pass the master node as ENV then pass first param like join_cluster ##########
    if [ "${1}" == "join_cluster" ]; then
    echo -e "***************Joining_Cluster start***********" 
    /home/ejabberd/bin/ejabberdctl join_cluster ejabberd@$MASTER_NODE
    echo -e "***************Joining_Cluster End***********" 
    fi
else
    echo -e "**********Ejabberd  is down************";
fi

运行docker容器

docker build -t ejabberd .
docker run --name ejabberd --rm -it ejabberd

enter image description here

答案 1 :(得分:0)

Docker设计为一次仅运行一个命令。有多种方法可以解决该限制,但是默认设计是使一个容器=一个命令。 您可能需要查看其他设计不同的容器框架,并允许多个命令同时运行。

答案 2 :(得分:0)

您要搜索的内容称为supervisord。在official docker documentation中,您可以找到一些使用方法的示例。

请注意,除非绝对必要,否则不要在同一容器中运行多个服务。