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

在docker容器启动中运行多个命令,docker,ubuntu,ejabberd,Docker,Ubuntu,Ejabberd,我在ubuntu 16.04上运行了一个简单的docker映像,它基于dockerfile,CMD是“/sbin/ejabberdctl foreground”。为了在docker容器启动后保持其活动状态,我使用在前台运行ejabberd服务器。但是,在启动容器和/sbin/ejabberdctl之后,一旦ejabberdctl已经运行,我需要执行另一个命令(例如ejabberdctl list_cluster)。 尝试将这两个命令都添加到bash脚本,但无效。试图运行/sbin/ejbberd

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

你要搜索的东西叫什么。在中,您可以找到一些如何使用它的示例

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

选项A: 创建一个简单的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"
选项B

在选项B中,您需要修改ejabberd官方图像入口点,因为它不允许您在启动时运行多个脚本。因此,在启动时添加脚本,同时进行一些修改

我建议只使用ejabberd的官方阿尔卑斯山图像30MB,而不是Ubuntu。

这里的演示也可以针对Ubuntu进行修改,但这是针对alpine ejabberd官方图片进行的测试

使用ejabberd官方图像作为基础图像
ENV MASTER_节点=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"]
现在创建管理器配置文件

[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启动,它将列出集群,并且如果在调用脚本时传递参数,它还能够加入集群

#!/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

感谢您的详细回答。事实上,您是对的,我对自动聚集感兴趣,所以一旦ejabberd成员容器启动,它就必须连接到给定的根节点,该节点是由env变量预定义的。这里的要点是,我没有使用ejabberd的官方形象,因为它不符合我的需要。我有自己的ejabberd映像,我正在使用它运行kubernetes中的ejabberd集群。如果我根据你的回答在我自己的ejabberd图像中做了所有适当的更改,你认为这在kubernetes中也会起作用吗?我认为不会。你不需要任何特殊更改,只有根节点docker不需要加入任何集群,而其余的将加入env中的根节点过程。对于ubuntu,您需要更改ejabberd的路径,或者可能需要更改#/垃圾箱/垃圾箱至#/bin/bash That s itejabberd图像与平台无关,因此无论您想在何处运行,behivour都将保持不变。感谢您的回复,我们将尝试使用此图像并在此更新谢谢。将尝试解决该问题并在此处更新