Search code examples
dockerubuntuejabberd

run multiple commands in docker container start


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?


Solution

  • 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