run multiple commands in docker container start
Option A: Create a simple bash script that runs container and list_cluster with out modifying entry point of ejabberd docker image.
#!/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"
In option B you need to modify ejabberd official image entry point as it does not allow you to run multiple scripts on bootup. So add your script on boot up while a bit modification.
https://github.com/processone/docker-ejabberd/blob/master/ecs/Dockerfile
I will suggest using an official alpine image of 30 MB only of ejabberd instead of Ubuntu. https://hub.docker.com/r/ejabberd/ecs/
The demo is here can be modified for Ubuntu too but this is tested against the alpine ejabberd official image.
Use ejabberd official image as a base image and ENV [email protected]
is for the master node if you are interested in a cluster.
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 [email protected]
ENTRYPOINT ["supervisord", "--nodaemon", "--configuration", "/etc/supervisord.conf"]
Now create supervisors config file
[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
Now create ejabberd.conf to start ejabberd using supervisorsd. Note here join cluster argument is used to join cluster if you want to join the cluster. remove it if not needed.
[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
A /opt/ejabberd/start.sh
bash script that will list_cluster once ejabberd is up and also capable to join_cluster if an argument is passed while calling the script.
#!/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
Run docker container
docker build -t ejabberd .
docker run --name ejabberd --rm -it ejabberd
Comments
-
Ahnenerbe about 2 years
I have a simple docker image running on ubuntu 16.04 based on a dockerfile which CMD is
"/sbin/ejabberdctl foreground"
. to keep the docker container alive once it started I used to run ejabberd server in foreground. However after starting the container and/sbin/ejabberdctl
I need to execute another command once ejabberdctl is already running (e.g.ejabberdctl list_cluster
). Tried to add both commands to bash script, but it doesn't work. tried to run/sbin/ejbberdctl start &
, it didn't work either. Which way to dig? -
Ahnenerbe over 5 yearsThanks for your detailed answer. Actually you get it right, I'm interested in autoclustering, so once the ejabberd member container is up it must join to given root node which is predefined by env variable. The main point here is that I'm not using ejabberd's official image as it doesn't fit my needs. I've my own ejabberd image and I'm using it to run the ejabberd cluster in kubernetes. Do you think this will work in kubernetes also if I make all the appropriate changes in my own ejabberd image according to your answer?
-
Adiii over 5 yearsI think no. you dont need any special changes and only the root noode docker will not need to join any cluster while the rest will join the root node pass in env. for ubuntu you need to change path of ejabberd or might need to change #!/bin/sh to #!/bin/bash thats it
-
Adiii over 5 yearsejabberd image is platform indenpendent so no matter where you want to run the behivour will remain same.
-
Ahnenerbe over 5 yearsThank you for your reply, will try to use this and update here
-
Adiii over 5 yearssure. please accept once u resolve the issue or let me update here
-
Ahnenerbe over 5 yearsI've tried according to your answer, everything works as expected, but not the join_cluster part. After cluster listing I'm getting this "INFO exited: list_cluster (exit status 0; expected)" and nothing happens after. As I am getting right this is log of supervisord. and after listing the cluster the start.sh script exits with 0 and it's normal. Maybe I'm missing smth?
-
Ahnenerbe over 5 yearsSorry, my fault. forgot to change /bin/sh to /bin/bash. Actually this worked on docker environment, but in kubernetes it crashes ejabberd application and throws an ejabberd error.
-
Ahnenerbe over 5 yearsOnce the ejabberd join_cluster command run I was getting error regarding mnesia db. unfortunately currently I can't reproduce that error (don't know why this error gone now), but the situation is the same just no error logs apart from this:
-
Ahnenerbe over 5 years<0.38.0>@ejabberd_listener:stop_listener:357 Stop accepting TCP connections at 0.0.0.0:5269 for ejabberd_s2s_in <0.38.0>@ejabberd_app:stop:86 ejabberd 18.06 is stopped in the node '[email protected]ter.local' <0.7.0> Application ejabberd exited with reason: stopped <0.7.0> Application mnesia exited with reason: stopped <0.7.0> Application mnesia started on node '[email protected]ter.local' <0.416.0>@ejabberd_cluster_mnesia:wait_for_sync:123 Waiting for Mnesia synchronization to complete
-
Adiii over 5 yearswhy you are not using offical image? it best choice modified that accordingly. lot of bug fixes
-
Ahnenerbe over 5 yearsagree with you, but there is no option to enable riak in official 18.06 image. I forked and make changes to be able to enable riak, but got into other troubles and didn't get support from them. So I created my image which was working fine before supervisord added. I mean containers ran correctly in kubernetes and the main issue there was join_cluster was manually, but worked. Using your configuration it works perfectly in docker env (I run 2 containers in the same network - one root with static hostname and one member with generated hostname). member connected to root automatically.
-
Ahnenerbe over 5 yearsWhen I'm running the same image in kubernetes I'm getting this issues
-
Ahnenerbe over 5 yearsI just reproduce the errors I was talking about pastebin.com/raw/Eq6JDEp9
-
Adiii over 5 yearsrun command inside container. stop ejabberd process using supervisor and then start ejabberd /opt/home/ejabberd/bin/ejabberdctl live and check for error. reset db and remove db file. issue from mnesia
-
Ahnenerbe over 5 yearsActually I didn't get you. Can you please describe more detailed. P.S. When I'm running start.sh script without join_cluster arg so that cluster join command doesn't run. it runs correctly and I'm able to to exec inside the running container and run join_cluster command successfully.
-
Adiii over 5 yearsput sleep will be the best option i think at joining cluster command or check logs why its failing. I cant reproduce your problem. and may be you need to modifiy join cluster command in start script
-
Adiii over 5 yearsits look like your mnesia database is corrupt. www1.erlang.org/doc/man/mnesia.html
-
Ahnenerbe over 5 yearsThanks. Will try to solve that issue and update here