How to Run a Daemon Service in the Foreground
How to Run a Daemon Service in the Foreground
Sometimes, you simply need to run a Daemon process in the foreground. Why? How? Find out in this article from Denny Zhang.
Join the DZone community and get the full member experience.Join For Free
In response to accelerated release cycles, a new set of testing capabilities is now required to deliver quality at speed. This is why there is a shake-up in the testing tools landscape—and a new leader has emerged in the just released Gartner Magic Quadrant for Software Test Automation.
Usually, we don’t do so, but running processes in Daemon mode gives us a lot of benefits. Service can be easily managed. Remember service XXX start and chkconfig XXX on? When the terminal disconnects, this process remains.
However, sometimes services just fail to start. In these cases, we may need to run the process in foreground mode. For example, you may encounter duplicated global ENVs, incorrect CONF files, missing folders, access being denied, etc. (For some related reading, check out How to Check Linux Process Deeply With Common Sense.)
In container ENVs, each container will usually host one and only one process. One useful trick is to lower the operation cost. When containers start, the service automatically starts. When service stops, the container automatically stops. To achieve this, we would like to find a way that we can run the process in foreground, and then change the entry point to the start command.
Take the Redis container, for example.
docker run -t -d --name my-nginx nginx /bin/sh # Start containers, then start process docker exec -it my-nginx bash service nginx start
docker stop my-nginx; docker rm my-nginx # When container starts, start process inside docker run -t -d --name my-nginx nginx \ /usr/sbin/nginx -g "daemon off;" docker exec -it my-nginx bash ps -ef | grep nginx
You must figure out the start command in order to run in the foreground.
(Note: Daemon Service = Binary + Configuration + Initscript.)
To run the process in the foreground, we just need these two ingredients:
- Binary: bash -x /etc/init.d/XXX start.
Here, -x instructs shell to display verbose output. Should be easy to figure out binary path. Another trick is _”ps -ef | grep $PROCESS_PATTERN”_.
- Configuration: Typically speaking, we can dig out from console output of bash -x. Sometimes, it’s just too long to read. Figure out the process ID and the list environment from cat /proc/$pid/environ.
A lot of decent services refuse to run as root because of security concerns. Here is how to impersonate other users with root.
su -l elasticsearch -c "java XXX"
Sample output of bash -x /etc/init.d/jenkins start:
root@denny:/# bash -x /etc/init.d/jenkins start bash -x /etc/init.d/jenkins start + PATH=/bin:/usr/bin:/sbin:/usr/sbin + DESC='Jenkins Continuous Integration Server' + NAME=jenkins + SCRIPTNAME=/etc/init.d/jenkins + '[' -r /etc/default/jenkins ']' + . /etc/default/jenkins ++ NAME=jenkins ++ JAVA=/usr/bin/java ++ JAVA_ARGS=-Djava.awt.headless=true ... ... + '[' no '!=' no ']' + ulimit -n 8192 + '[' -n '' ']' + /bin/su -l jenkins --shell=/bin/bash -c '/usr/bin/daemon --name=jenkins --inherit --env=JENKINS_HOME=/var/lib/jenkins --output=/var/log/jenkins/jenkins.log --pidfile=/var/run/jenkins/jenkins.pid -- /usr/bin/java -Dhudson.diyChunking=false -Djenkins.install.runSetupWizard=false -jar /usr/share/jenkins/jenkins.war --webroot=/var/cache/jenkins/war --httpPort=18080' + START_STATUS=0 + do_check_started_ok 0 + sleep 1 + '[' 0 -ne 0 ']' + get_running ++ grep -c . ++ egrep -e '(java|daemon)' ++ ps -U jenkins --no-headers -f ... ... + return 0 + exit 0
How to Run Apache, Jenkins, or MySQL in the Foreground
Using the above technique, we can find start commands running popular services in the foreground.
cd /etc/apache2/ && \ apachectl -d /etc/apache2 -e info -DFOREGROUND
Run Jenkins in the foreground:
/bin/su -l jenkins --shell=/bin/bash \ -c '/usr/bin/daemon --name=jenkins \ --inherit --env=JENKINS_HOME=/var/lib/jenkins \ --output=/var/log/jenkins/jenkins.log \ --pidfile=/var/run/jenkins/jenkins.pid -- \ /usr/bin/java -Dhudson.diyChunking=false \ -Djenkins.install.runSetupWizard=false -jar \ /usr/share/jenkins/jenkins.war \ --webroot=/var/cache/jenkins/war \ --httpPort=18080'
Run mySQL in the foreground:
And finally, run Nginx in the foreground:
/usr/sbin/nginx -g "daemon off;"
Published at DZone with permission of Denny Zhang , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.