run multiple commands in docker container start

10,817

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"

enter image description here Option B

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

enter image description here

Share:
10,817
Ahnenerbe
Author by

Ahnenerbe

Beginner in python

Updated on June 05, 2022

Comments

  • Ahnenerbe
    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
    Ahnenerbe over 5 years
    Thanks 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
    Adiii over 5 years
    I 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
    Adiii over 5 years
    ejabberd image is platform indenpendent so no matter where you want to run the behivour will remain same.
  • Ahnenerbe
    Ahnenerbe over 5 years
    Thank you for your reply, will try to use this and update here
  • Adiii
    Adiii over 5 years
    sure. please accept once u resolve the issue or let me update here
  • Ahnenerbe
    Ahnenerbe over 5 years
    I'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
    Ahnenerbe over 5 years
    Sorry, 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
    Ahnenerbe over 5 years
    Once 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
    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
    Adiii over 5 years
    why you are not using offical image? it best choice modified that accordingly. lot of bug fixes
  • Ahnenerbe
    Ahnenerbe over 5 years
    agree 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
    Ahnenerbe over 5 years
    When I'm running the same image in kubernetes I'm getting this issues
  • Ahnenerbe
    Ahnenerbe over 5 years
    I just reproduce the errors I was talking about pastebin.com/raw/Eq6JDEp9
  • Adiii
    Adiii over 5 years
    run 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
    Ahnenerbe over 5 years
    Actually 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
    Adiii over 5 years
    put 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
    Adiii over 5 years
    its look like your mnesia database is corrupt. www1.erlang.org/doc/man/mnesia.html
  • Ahnenerbe
    Ahnenerbe over 5 years
    Thanks. Will try to solve that issue and update here