I would like start a service during the Docker build. I do not need this service to continue running after the build process has finished necessarily (or I know I can use the CMD command for that), however I do need it running long enough to execute a second command which relies on this service being up and running.
To be more precise I am trying to write a Dockerfile for the ejabberd XMPP Server, which also installs a module for this server. I am trying to start the ejabberd server with ejabberdctl start and then install the module with the ejabberdctl module_install utility, which depends on the node being up and running. It looks like this:
RUN ejabberdctl start && ejabberdctl modules_update_specs && ejabberdctl module_install ejabberd_auth_http
Now I have run into a problem, and I came up with two possible causes. The problem is that my build does not work from this line on, because the node is down when the second command is trying to execute. I get the following error, which is a typical one when you try to use the ejabberdctl utility, without the node actually being up:
Failed RPC connection to the node ejabberd@localhost
The command '/bin/sh -c ejabberdctl start && ejabberdctl modules_update_specs && ejabberdctl module_install ejabberd_auth_http' returned a non-zero code: 3
This could be either because the starting of the service takes a little, longer than it takes for the second command to get executed, so the second command runs into a node which is just starting up. Not sure how likely this is. The second cause could be that a starting of a service which depends on init.d just doesnt work in Docker during the build process.
I build the container up until that line that causes the problem, entered the container and executed the commands manually and everything worked as it should.
So to summarize I would like to start the ejabberd server during the build and then use its control utility to install some stuff. A last option would be to install the module manually without the server running, however I would prefer doing it with the ejabberdctl control utility.
These *ctl programs usually come in with a few utilities to start / stop / monitor the status of the service.
If your case I think the best idea is to have a simple bash script you can run at build time that does this:
Look at this:
root@158479dec020:/# ejabberdctl status Failed RPC connection to the node ejabberd@158479dec020: nodedown root@158479dec020:/# echo $? 3 root@158479dec020:/# ejabberdctl start root@158479dec020:/# echo $? 0 root@158479dec020:/# ejabberdctl status The node ejabberd@158479dec020 is started with status: started ejabberd 16.01 is running in that node root@158479dec020:/# echo $? 0 root@158479dec020:/# ejabberdctl stop root@158479dec020:/# echo $? 0 root@158479dec020:/# ejabberdctl status Failed RPC connection to the node ejabberd@158479dec020: nodedown root@158479dec020:/# echo $? 3
So this tells us that if you run a ejabberd status and the daemon is not running you receive exit code 3, 0 if it's up and running instead.
There you go with your bash script:
function run() {
ejabberdctl start # Repeating just in case...
ejabberdctl status &>/dev/null
if [ $? -eq 0 ]; then
echo "Do some magic here, ejabberd is running..."
exit 0
fi
echo "Ejabberd still down..."
}
while true; do run; sleep 1; done
And this is what you'd get at the CLI:
root@158479dec020:/# ./check.sh Ejabberd still down... Do some magic here, ejabberd is running... root@158479dec020:/# ejabberdctl stop root@158479dec020:/# ./check.sh Ejabberd still down... Ejabberd still down... Do some magic here, ejabberd is running...