I can't seem to find anything that does this exactly, and I've spent 2 hours on google trying to find a solution and I'm simply fed up. I'm sure it's a simple solution but I can't seem to find it.
I need to run a .php file located in /var/www/Game/Sockets/ChatServer.php as a Daemon. This file acts as a Socket Server for my chat system in my browser based game. However despite trying many different things, I can't get it to start on boot. I can use "service ChatServerDaemon start" to start the daemon, but on boot it doesn't work. The file I have located in init.d is:
#! /bin/sh
# Installation
# - Move this to /etc/init.d/myservice
# - chmod +x this
#
# Starting and stopping
# - Start: `service myservice start` or `/etc/init.d/myservice start`
# - Stop: `service myservice stop` or `/etc/init.d/myservice stop`
#ref http://till.klampaeckel.de/blog/archives/94-start-stop-daemon,-Gearman-and-a- little-PHP.html
#ref http://unix.stackexchange.com/questions/85033/use-start-stop-daemon-for-a-php- server/85570#85570
#ref http://serverfault.com/questions/229759/launching-a-php-daemon-from-an-lsb-init- script-w-start-stop-daemon
NAME=ChatServerDaemon
DESC="Chat Server Daemon for Taloren."
PIDFILE="/var/run/${NAME}.pid"
LOGFILE="/var/log/${NAME}.log"
DAEMON="/usr/bin/php"
DAEMON_OPTS="/var/www/Game/Sockets/ChatServer.php"
START_OPTS="--start --background --make-pidfile --pidfile ${PIDFILE} --exec ${DAEMON} ${DAEMON_OPTS}"
STOP_OPTS="--stop --pidfile ${PIDFILE}"
test -x $DAEMON || exit 0
set -e
case "$1" in
start)
echo -n "Starting ${DESC}: "
start-stop-daemon $START_OPTS >> $LOGFILE
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon $STOP_OPTS
echo "$NAME."
rm -f $PIDFILE
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon $STOP_OPTS
sleep 1
start-stop-daemon $START_OPTS >> $LOGFILE
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
I'm pissed off and tired of trying to get this to work. Please can someone help me with this. I'm sorry if the answer is obvious. :/
Simply placing the script in /etc/init.d/ is not sufficient to make it run at boot. One needs to specify at which runlevels the system should start or stop the service. On distributions that use classic SysV init system it is done by making symbolic links to the init script in special folders.
Here is who to determine the current run level:
$ who -r
run-level 2 Apr 9 10:39 last=S
For example, here is how the cups printing service was configured in order to be started in runlevel 2:
$ ls -l /etc/rc2.d/S20cups
lrwxrwxrwx 1 root root 14 Apr 6 01:24 /etc/rc2.d/S20cups -> ../init.d/cups
Everything that has to be started or stopped in run level 2 has a symbolic in /etc/rc2.d/, the symlinks' name start with S when the service must be started and K when the service has to be stopped, then there is a two digit priority.
It may be cumbersome to handle this by hand, so major distributions have tools to do this automatically. On Debian or Ubuntu it's update-rc.d. On RedHat it is chkconfig.
Also this SysV init system is being replaced by systemd (which still supports SysV init scripts). So it may be worth writing directly a configuration file for systemd. Or you can use an alternative service manager like supervisord or god. They're a lot easier to manage and they have nice features, like automatically restarting services when they fail.
Related
I am trying to run a php script to restore a state after the server crashed, got restarted or smth.
Because the php script needs the database to run I first tried running it by creating a file in init.d, which did not work, it just started whenever it wantend.
So right now I think it is the easiest way to run the script on apache2 startup like discribed here.
So currently I have added php -q /var/www/scripts/testing.php & ;; to do_start() in /etc/init.d/apache2 like this:
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
if pidofproc -p $PIDFILE "$DAEMON" > /dev/null 2>&1 ; then
return 1
fi
if apache_conftest ; then
$APACHE2CTL start
php -q /var/www/scripts/testing.php &
;;
apache_wait_start $?
return $?
else
APACHE2_INIT_MESSAGE="The apache2$DIR_SUFFIX configtest failed."
return 2
fi
}
But because this didn't work at all, I have also added this php execution to the restart) part as mentioned in the link. This looks like this:
restart)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop stop
case "$?" in
0|1)
do_start
case "$?" in
0)
log_end_msg 0
;;
1|*)
log_end_msg 1 # Old process is still or failed to running
print_error_msg
exit 1
;;
esac
;;
*)
# Failed to stop
log_end_msg 1
print_error_msg
exit 1
;;
php -q /var/www/scripts/testing.php &
;;
esac
;;
But still the script is not run. The php script looks like this:
<?php
file_put_contents('/var/www/html/log', "301,$timestamp,Recreating all connections after restart,N/A\n",FILE_APPEND);
?>
Because i wanted it to be as simple as possible, but the log file is still empty. I am open to any idea solving my problem.
p.s.: I have already tried to do this by a service in /etc/systemd/system/ but since I am starting a connection that is supposed to be persistent, I have to use either screen, nohup or disown. I have tried those three, but no of this worked, they just didn't start the script. (was bash back then, I switched to php to be able to run it from the apache2 file)
You should not use apache to start your script, but follow your first idea of using an own init-script unless your php script depends on the existence of apache.
Just place a shell script callmyphp into /etc/init.d that calls the php interpreter and passes your php script as an argument like:
#!/bin/sh
/usr/bin/php -q /path/to/myphp.php
Don't forget to make your calling script executabel with chmod 755 /etc/init.d/callmyphp.
Then add your calling script via symbolic links to the desired run levels, i.e. by running update-rc.d callmyphp defaults
See also https://debian-administration.org/article/28/Making_scripts_run_at_boot_time_with_Debian
I came across a couple of issues with my QNAP NAS TS-251+ whilst developing a new project these are:
1) There is no php alias and when I add one via command line it is removed on NAS Restart.
2) A similar thing happens for Composer except on restart it removes Composer as well from the system.
How can I stop this from happening or get around it so that when my NAS restarts the php and composer alias are already set.
I managed to resolve this issue by adding a new script that runs when my NAS starts up. QNAP have provided some basic instructions on how to add a startup script on their wiki page under Running Your Own Application at Startup. However I added a couple more steps t
These steps are fairly basic:
Login to your NAS Server via SSH.
Run the following command mount $(/sbin/hal_app --get_boot_pd port_id=0)6 /tmp/config (Running ls /tmp/config will give you something similar to below)
Run vi /tmp/config/autorun.sh this will allow you to edit/create a file called autorun.sh **
For me I wanted to keep this file as simple as possible so I didn't have to change it much, so the script is just called from with this Shell Script. So add the following to autorun.sh.
autorun.sh code example:
#!/bin/sh
# autorun script for Turbo NAS
/share/CACHEDEV1_DATA/.qpkg/autorun/autorun_startup.sh start
exit 0
You will notice a path of /share/CACHEDEV1_DATA/.qpkg/autorun/ this is where my new script that I want to run is contained, you don't have to have yours here if you don't want to however I know the script will not be removed if placed here. autorun_startup.sh this is the name of the script I want to be running, and start is the command in the script I want to be running.
Run chmod +x /tmp/config/autorun.sh to make sure that autorun.sh is actually runnable.
Save the file and run umount /tmp/config (Important).
Navigate to the folder you have put in the autorun.sh (script in my case /share/CACHEDEV1_DATA/.qpkg/autorun/) and create any folders along the way that you need.
Create your new shell file using vi and call it whatever you want (Again in my case it is called autorun_startup.sh) and add your script to the file. The script I added is below but you can add whatever you want to you startup script.
autorun_startup.sh code example:
#!/bin/sh
RETVAL=0
QPKG_NAME="autorun"
APACHE_ROOT=`/sbin/getcfg SHARE_DEF defWeb -d Qweb -f
/etc/config/def_share.info`
QPKG_DIR=$(/sbin/getcfg $QPKG_NAME Install_Path -f /etc/config/qpkg.conf)
addPHPAlias() {
/bin/cat /etc/profile | /bin/grep "php" | /bin/grep "/usr/local/apache/bin/php" 1>>/dev/null 2>>/dev/null
[ $? -ne 0 ] && /bin/echo "alias php='/usr/local/apache/bin/php'" >> /etc/profile
}
addComposerAlias() {
/bin/cat /etc/profile | /bin/grep "composer" | /bin/grep "/usr/local/bin/composer" 1>>/dev/null 2>>/dev/null
[ $? -ne 0 ] && /bin/echo "alias composer='/usr/local/bin/composer'" >> /etc/profile
}
addPHPComposerAlias() {
/bin/cat /etc/profile | /bin/grep "php-composer" | /bin/grep "/usr/local/apache/bin/php /usr/local/bin/composer" 1>>/dev/null 2>>/dev/null
[ $? -ne 0 ] && /bin/echo "alias php-composer='php /usr/local/bin/composer'" >> /etc/profile
}
download_composer() {
curl -sS https://getcomposer.org/installer | /usr/local/apache/bin/php -- --install-dir=/usr/local/bin --filename=composer
}
case "$1" in
start)
/bin/echo "Enable PHP alias..."
/sbin/log_tool -t 0 -a "Enable PHP alias..."
addPHPAlias
/bin/echo "Downloading Composer..."
/sbin/log_tool -t 0 -a "Downloading Composer..."
download_composer
/bin/echo "Enable composer alias..."
/sbin/log_tool -t 0 -a "Enable composer alias..."
addComposerAlias
/bin/echo "Adding php composer alias..."
/sbin/log_tool -t 0 -a "Adding php composer alias..."
addPHPComposerAlias
/bin/echo "Use it: php-composer"
/sbin/log_tool -t 0 -a "Use it: php-composer"
;;
stop)
;;
restart)
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit $RETVAL
Run chmod +x /share/CACHEDEV1_DATA/.qpkg/autorun/autorun_startup.sh to make sure your script is runnable.
Restart your NAS System to make sure the script has been run. After restart for my script I just did php -version via terminal to make sure that the php alias worked and it did.
(*) With steps 3 and 8 you can either do this via something like WinSCP or continue doing it via command line (SSH). For me I chose to do it via WinSCP but here is the command still for SSH
I am fairly new to server related stuff so if anyone has a better way cool.
I'm testing the logging the output of a simple php script being run via the start-stop daemon on Ubuntu.
The content of the test script, loop.php, is as follows:
<?php
while (true) {
error_log('Running at '.date('Y-m-d H:i:s').'...');
sleep(10);
}
When run from the command line, the output is logged as expected to /tmp/loop.log:
php loop.php >> /tmp/loop.log 2>&1
That works as expected, but now I want to run the script via the start-stop-demon.
I have used an example script as a template to set it up:
#! /bin/sh
# Installation
# - Move this to /etc/init.d/myservice
# - chmod +x this
#
# Starting and stopping
# - Start: `service myservice start` or `/etc/init.d/myservice start`
# - Stop: `service myservice stop` or `/etc/init.d/myservice stop`
#ref http://till.klampaeckel.de/blog/archives/94-start-stop-daemon,-Gearman-and-a-little-PHP.html
#ref http://unix.stackexchange.com/questions/85033/use-start-stop-daemon-for-a-php-server/85570#85570
#ref http://serverfault.com/questions/229759/launching-a-php-daemon-from-an-lsb-init-script-w-start-stop-daemon
NAME=myservice
DESC="MyService PHP CLI script daemon"
PIDFILE="/var/run/${NAME}.pid"
LOGFILE="/var/log/${NAME}.log"
DAEMON="/usr/bin/php"
DAEMON_OPTS="/home/me/loop.php"
START_OPTS="--start --background --make-pidfile --pidfile ${PIDFILE} --exec ${DAEMON} ${DAEMON_OPTS}"
STOP_OPTS="--stop --pidfile ${PIDFILE}"
test -x $DAEMON || exit 0
set -e
case "$1" in
start)
echo -n "Starting ${DESC}: "
start-stop-daemon $START_OPTS >> $LOGFILE 2>&1
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon $STOP_OPTS
echo "$NAME."
rm -f $PIDFILE
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon $STOP_OPTS
sleep 1
start-stop-daemon $START_OPTS >> $LOGFILE 2>&1
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
I can start and stop the daemon and everything works as expected, however nothing gets written to /var/log/myservice.log.
Why is the script output not being logged to the specified log file?
Why is the script output not being logged to the specified log file?
When a script is run as a daemon, it will be decoupled from the standard streams (stdin, stdout and stderr). Compare with "How can I log the stdout of a process started by start-stop-daemon?".
You use the standard streams for the logging which are not available in that case.
Instead for a deamon I suggest you directly log to the logfile instead of stderr.
You do not need to change much of your script for that, just remove the redirection when you call your script and at the top of your script set the error_log directive to the error log filename.
I have a Gitlab server (Ubuntu 14.04) where I am trying use it as both a host for my repositories as well as a testing server for my PHP projects. Ideally, I would like to have Gitlab/Git export the "release" branch to /var/www/git/<project-name> when that branch is updated.
My Question: How can I export a specific branch in Gitlab, to a specific directory on the localhost, when the branch is updated?
I am aware that there are webhooks available in Gitlab, but it seems unnecessary and wasteful to have the server POST to itself for a local operation.
I suppose you are running the community edition of gitlab.
Then, only the server administrator can configure hook scripts by copying the required scripts into the affected repositories.
gitlab itself is using the $GIT_DIR/hooks directory for its own scripts already. Fortunately they forward control to any hook script in the gitlab specific $GIT_DIR/custom_hooks directory. See also this question about how to run multiple hooks with the same type on gitlab.
The script itself could look like this:
#!/bin/bash
#
# Hook script to export current state of repo to a release area
#
# Always hardcode release area - if configured in the repo this might incur data loss
# or security issues
echo "Git hook: $0 running"
. $(dirname $0)/functions
git=git
release_root=/gitlab/release
# The above release directory must be accessible from the gitlab server
# and any client machines that want to access the exports. Please configure.
if [ $(git rev-parse --is-bare-repository) = true ]; then
group_name=$(basename $(dirname "$PWD"))
repo_name=$(basename "$PWD")
else
cd $(git rev-parse --show-toplevel)
group_name=$(basename $(readlink -nf "$PWD"/../..))
repo_name=$(basename $(readlink -nf "$PWD"/..))
fi
function do_release {
ref=$1
branch=$2
# Decide on name for release
release_date=$(git show -s --format=format:%ci $ref -- | cut -d' ' -f1-2 | tr -d -- -: | tr ' ' -)
if [[ ! "$release_date" =~ [0-9]{8}-[0-9]{6} ]]; then
echo "Could not determine release date for ref '$ref': '$release_date'"
exit 1
fi
dest_root="$release_root/$group_name/$repo_name"
dated_dir="dated/$release_date"
export_dir="$dest_root/$dated_dir"
# Protect against multiple releases in the same second
if [[ -e "$export_dir" ]]; then
export_dir="$export_dir-02"
dated_dir="$dated_dir-02"
while [[ -e "$export_dir" ]]; do
export_dir=$(echo $export_dir | perl -pe 'chomp; print ++$_')
dated_dir=$(echo $dated_dir | perl -pe 'chomp; print ++$_')
done
fi
# Create release area
if ! mkdir -pv "$export_dir"; then
echo 'Failed to create export directory: ' "$export_dir"
exit 1
fi
# Release
if ! git archive $branch | tar -x -C "$export_dir"; then
echo 'Failed to export!'
exit 1
fi
chmod a-w -R "$export_dir" # Not even me should change this dir after release
echo "Exported $branch to $export_dir"
( cd "$dest_root" && rm -f latest && ln -s "$dated_dir" latest )
echo "Adjusted $dest_root/latest pointer"
}
process_ref() {
oldrev=$(git rev-parse $1)
newrev=$(git rev-parse $2)
refname="$3"
set_change_type
set_rev_types
set_describe_tags
echo " Ref: $refname","$rev_type"
case "$refname","$rev_type" in
refs/heads/*,commit)
# branch
refname_type="branch"
function="branch"
short_refname=${refname##refs/heads/}
if [[ $short_refname == release ]]; then
echo " Push accepted. Releasing export for $group_name/$repo_name $short_refname"
do_release "$refname" "$short_refname"
else
echo " Push accepted. No releases done for $group_name/$repo_name $short_refname"
fi
;;
refs/tags/*,tag)
# annotated tag
refname_type="annotated tag"
function="atag"
short_refname=${refname##refs/tags/}
;;
esac
}
while read REF; do process_ref $REF; done
exit 0
The script was started based on this post-receive.send_email script which is already quoted on SO multiple times.
Configure a release area in the variable hardcoded in the script, or e.g. add a mechanism to read a config file in the repo. Maybe you want to give users control over this area. Depends on your security circumstances.
The release area must be accessible by the git#gitlab user, and of course by any client expecting the export.
The branch to export is hardcoded in the script.
The release area will be populated like this:
$release_root/$group_name/$repo_name/dated/$release_date
Plus a symbolic link latest pointing to the latest $release_date. The idea is that this is extensible to later be able to also export tags. If you expect to export different branches, a $branch should be included as a path component, too.
Access control of the gitlab server is not passed down to the directory structure. Currently I do this manually, and that is why I do not auto-populate all new repositories with this hook. I'd rather configure manually, and then adjust unix group permissions (and/or ACLs) on the $release_root/$groupname paths accordingly. This needs to be done only once per group and works because no one else is allowed to create new groups on my gitlab instance. This is very different from the default.
Anything else we can do for you? ;-)
i have a command that run normally in terminal :
php -f /home/roshd-user/Symfony/app/console video:convert
i want run this command as service in my server. create a vconvertor.conf in /etc/init/
.
this service run(start and stop) normally but not execute my command ?!
my command without service is run well and return my result but when use it into a service not execute ?!
vconvertor.conf contain this codes :
#info
description "Video Convertor PHP Worker"
author "Netroshd"
# Events
start on startup
stop on shutdown
# Automatically respawn
respawn
respawn limit 20 5
# Run the script!
# Note, in this example, if your PHP script returns
# the string "ERROR", the daemon will stop itself.
script
[ $( exec php -f /home/roshd-user/Symfony/app/console video:convert
) = 'ERROR' ] && ( stop; exit 1; )
end script
I would declare setuid and setgid in your config as the Apache usergroup ie www-data
and make your command run in the prod Symfony environment.
#info
description "Video Convertor PHP Worker"
author "Netroshd"
# Events
start on startup
stop on shutdown
# Automatically respawn
respawn
respawn limit 20 5
# Run as the www-data user and group (same as Apache is under in Ubuntu)
setuid www-data
setgid www-data
# Run the script!
exec php /home/roshd-user/Symfony/app/console video:convert -e prod --no-debug -q
If you still have issues, it might be worth installing the "wrep/daemonizable-command" with Composer and making your video convert command extend the Wrep\Daemonizable\Command\EndlessContainerAwareCommand. The library also provides an example of how to use it