[Play1 1.4.x] Systemd script for starting/stopping Play1 app on Ubuntu

267 views
Skip to first unread message

Johan Vosloo

unread,
Sep 9, 2016, 8:07:52 AM9/9/16
to Play Framework
Hi guys

I've been running Play1 happilly on Ubuntu 12.04 and 14.04 using Upstart scripts.
Now I'm going to Ubuntu 16.04 and Upstart has been replaced by systemd as the default init script manager.

I'm trying to come up with a systemd script for Play1 and this is what I've got so far:

[Unit]
Description=Play1 app
After=network.target

[Service]
Type=forking
PIDFile=/path/to/app/server.pid
ExecStartPre=/bin/sh -c 'cd /path/to/app ;/bin/rm server.pid
ExecStart=/path/to/app/bin/play -Dhttp.port=9000 -J-server // This is what it looks like in Play2
ExecStop=/bin/kill $MAINPID
ExecStopPost=/bin/rm /path/to/app/server.pid

ExecRestart=/bin/kill $MAINPID
Restart=true

[Install]
WantedBy=multi-user.target




I'm having trouble figuring what exactly should go in the ExecStart command.
Any help will be greatly appreciated!

Regards
Johan

javialeon

unread,
Sep 9, 2016, 10:03:34 AM9/9/16
to Play Framework
Johan

Why don't you just switch back from systemd to upstart?. Is it mandatory to you to use systemd now?
It's as simple as:

sudo apt-get install upstart-sysv
sudo apt-get remove ubuntu-standard systemd-sysv
sudo update-initramfs -u
sudo reboot

Johan Vosloo

unread,
Sep 9, 2016, 10:09:06 AM9/9/16
to Play Framework
That's a very good suggestion and probably my fallback position if I can't get systemd to work.
I like however to stick with the "defaults" as much as possible, because these components tend to get the most use and less have bugs ironed out quicker, be better documented and overtime are probably better maintained over the non-default stuff. 

Btw... I guess you could apply the same argument as to why I'm still sticking to Play1 as opposed to moving to Play2, but for me that's like asking me to switch out my zippy little sportscar for a (admittedly kitted out) RV :)

Thomas Szymanski

unread,
Sep 9, 2016, 11:26:28 AM9/9/16
to play-fr...@googlegroups.com

Hi Johan,


Not sure about how to use Play1 apps as I never used 1.x.

ExecStart= should have the command you would start by launching the app yourself, without considering service.

However, if the parent process of the command never ends when the app is started, you may not want to use Type=forking.

From systemd man:

If set to forking, it is expected that the process configured with ExecStart= will call fork() as part of its start-up. The parent process is expected to exit when start-up is complete [..].

If the main process of the app never ends, you may prefer Type=simple.


You can take a look at https://www.freedesktop.org/software/systemd/man/systemd.service.html and see the different options about the type of service and the ones related to pid file.

If you cannot manage to start the app, please join some infos about the problem, inputs, journal logs or the observed behaviour.

--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/13f06b94-afea-41db-9071-449ec4c00766%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Message has been deleted

Armandalic

unread,
Mar 30, 2017, 10:27:20 PM3/30/17
to Play Framework
Hi,
I've also started using systemd to run my 1.4.x apps, I can run it with no problem, it's just the stopping part that makes me worry, cause I still haven't completed it yet.
So here is what I do: I have separates shell scripts for starting, updating from repositories, and stopping the app. So I go with the forking, but I skip the fork() calling part.
I will send you all my scripts, I hope they help you. And you complete it for the stopping and restarting part :P (If I sit idle and don't continue to improve it maybe).
First the scripts that I put in the root of my play apps...
run.sh   it runs the app, also checks for play and downloads it if it doesn't exist. You should already have JRE and unzip installed on your Ubuntu.
VERSION="1.4.4"
PLAY_LOC="/usr/local/share"
PLAY_PATH="${PLAY_LOC}/play-${VERSION}"
PLAY_COMMAND="${PLAY_PATH}/play"

if [ ! -f $PLAY_COMMAND ] ;
then
  PLAY_ARCH="${PLAY_LOC}/play-${VERSION}.zip";
  wget -O $PLAY_ARCH $PLAY_URL;
  unzip $PLAY_ARCH -d $PLAY_LOC ;
fi

$PLAY_COMMAND stop . --%mania2

killall  java

$PLAY_COMMAND clean .

$PLAY_COMMAND start . -Xms2048M -Xmx4096M --%mania2


update.sh   this one checks for possible updates from repositories then runs the app. You should set git properly with deploy keys of course.
VERSION="1.4.4"
PLAY_LOC="/usr/local/share"
PLAY_PATH="${PLAY_LOC}/play-${VERSION}"
PLAY_COMMAND="${PLAY_PATH}/play"

if [ ! -f $PLAY_COMMAND ] ;
then
  PLAY_ARCH="${PLAY_LOC}/play-${VERSION}.zip";
  wget -O $PLAY_ARCH $PLAY_URL;
  unzip $PLAY_ARCH -d $PLAY_LOC ;
fi

$PLAY_COMMAND stop . --%mania2

killall java

$PLAY_COMMAND clean .

rm server.pid

git pull origin mania

$PLAY_COMMAND deps .

$PLAY_COMMAND start . -Xms4096M -Xmx4096M --%mania2


Stop script is also very easy
VERSION="1.4.4"
PLAY_LOC="/usr/local/share"
PLAY_PATH="${PLAY_LOC}/play-${VERSION}"
NOW=$(date +"%m-%Y")
LOG_FILE="./system-$NOW.log"
PLAY_COMMAND="${PLAY_PATH}/play"

if [ ! -f $PLAY_COMMAND ] ;
then
  PLAY_ARCH="${PLAY_LOC}/play-${VERSION}.zip";
  wget -O $PLAY_ARCH $PLAY_URL;
  unzip $PLAY_ARCH -d $PLAY_LOC ;
fi

$PLAY_COMMAND stop . --%mania2

killall java


Unfortunately I didn't have time to use another script for checking play and import it in all of them...  Just write another script like checkPlay.sh and import it at the top, so no more redundancy...
VERSION="1.4.4"
PLAY_LOC="/usr/local/share"
PLAY_PATH="${PLAY_LOC}/play-${VERSION}"
PLAY_COMMAND="${PLAY_PATH}/play"

if [ ! -f $PLAY_COMMAND ] ;
then
  PLAY_ARCH="${PLAY_LOC}/play-${VERSION}.zip";
  wget -O $PLAY_ARCH $PLAY_URL;
  unzip $PLAY_ARCH -d $PLAY_LOC ;
fi

if [ -f $PLAY_COMMAND ] ;
then
   echo 'play is good to go';
fi


 
OK now let's talk about the main problem of yours...
Also I had another major problem with systemd for setting nofile limit, but somehow I made it work at last (ugly solution though).

[Unit]

Description=runs pokermania


[Service]

Type=forking

RemainAfterExit=yes

WorkingDirectory=/var/www/playApp

ExecStart=/bin/sh -c 'ulimit -n 655350 ; cd /var/www/playApp ; ./update.sh'

#ExecStop=/bin/sh -c 'cd /var/www/playApp && ./stop.sh'


[Install]

WantedBy=multi-user.target


I've just started working for some days on it and I didn't have a lot of time to spend on perfecting it. But It will get done once I can spare my time for some days....
Don't forget to set ulimit settings in limits.conf and related minor settings, it's all over the net... You should both set it generally for linux and also use it when starting your app, I still haven't figured that Out.

Regards
Arman
Message has been deleted

Johan Vosloo

unread,
Mar 31, 2017, 4:15:55 AM3/31/17
to Play Framework
Thanks Arman

We've also gor separate scripts for build and deploy.... all I was after here was Systemd script replacement for the Upstart scripts to stop and start.
This is what we went with and it's working well:

env PLAY_BINARY=<path to play>
env HOME
=<path to app>
env USER
=playuser
env GROUP
=users
env PROFILE
=prod
env NEW_RELIC
=/home/playuser/newrelic/newrelic.jar


start on
(filesystem and net-device-up IFACE=lo) or runlevel [2345]
stop on runlevel
[!2345]

respawn
respawn limit
10 5
umask
022
expect fork

pre
-start script
        test
-x $PLAY_BINARY || { stop; exit 0; }
        test
-c /dev/null || { stop; exit 0; }
        chdir $
{HOME}
        rm $
{HOME}/server.pid || true
       
# $PLAY_BINARY dependencies $HOME
end script

pre
-stop script
       
exec $PLAY_BINARY stop $HOME
end script

post
-stop script
        rm $
{HOME}/server.pid || true
end script


script
exec start-stop-daemon --start --exec $PLAY_BINARY --chuid $USER:$GROUP -- start $HOME -Dprecompiled=true --%$PROFILE --http.port=9001 -javaagent:$NEW_RELIC
end script

Johan Vosloo

unread,
Mar 31, 2017, 10:28:20 AM3/31/17
to Play Framework
Whoops - that was the old Upstart script I posted before... here is the new Systemd script:

[Unit]
Description=<app description>
After=network.target


[Service]
Type=forking
PIDFile=<pid file location>
ExecStartPre=/bin/sh -c 'cd <path to app> ;/bin/rm server.pid
ExecStart=/bin/sh -c '
<play path>/play start <path to app> -Dprecompiled=true --%qa --http.port=9001 -javaagent:/home/playuser/newrelic/newrelic.jar'
ExecStop=/bin/kill $MAINPID
ExecStopPost=/bin/rm <path to app
>/server.pid
ExecRestart=/bin/kill $MAINPID
Restart=on-failure
User=playuser
Group=playuser


[Install]
WantedBy=multi-user.target

Arman

unread,
Mar 31, 2017, 12:08:30 PM3/31/17
to Play Framework
At first my script was working pretty well too, but I couldn't set "nofile" limit for my app.... then i got around it..... 
Now I really like to stop play properly not by killing the process.... Although it's a minority issue right now.
Good to here you've got around it :) , I suggest using the update from repository part, it really makes things easy.

Regards
Reply all
Reply to author
Forward
0 new messages