As a relatively brief note, this seems to be the correct way to start a Play Framework application as a service on an Ubuntu 16.04 system.
A shell script to start your Play application
First, you need to create a little Unix shell script that runs the startup command for your Play Framework application. I created a Play application for a website named kbhr.co, so I cd
into the directory for that website:
$ cd /var/www/kbhr.co
With my Play application zip file unzipped under this directory, I now create a shell script in this directory named StartServer.sh, with these contents:
#!/bin/bash
ROOT_DIR=/var/www/kbhr.co
${ROOT_DIR}/kbhr-1.0/bin/kbhr \
-Dplay.http.secret.key='SUPER-SECRET-KEY-HERE' \
-Dhttp.port=9000 \
-J-Xms128M \
-J-Xmx256m \
-J-server \
-Dconfig.file=${ROOT_DIR}/kbhr.conf
Note that my Play application is in the kbhr-1.0 directory that’s inside this directory.
Now make this shell script executable (with chmod +x
), and run it to confirm that it works as desired. Very importantly, be sure to stop the application after you confirm that it works.
Setting up the Ubuntu 16.04 service
To set up the Ubuntu 16.04 service for your application, first become the root user:
$ su -
Then cd
to the Ubuntu directory for system services:
# cd /etc/systemd/system
Then create a “service” file that defines the characteristics of your Play application. Because my app is for kbhr.co, I name my file kbhr.service:
# vi kbhr.service
Put these contents in that file:
# A Play Framework application systemd service file
[Unit]
Description=My KBHR Play Framework app
# `After` tells systemd when the script should be run.
# (`network.target` or `mysql.service` seems best)
After=mysql.service
[Install]
# `WantedBy` is what boot target the systemd unit should be installed into
# (should probably be `default.target` or `multi-user.target`)
WantedBy=multi-user.target
[Service]
User=alvin
Group=alvin
ExecStart=/var/www/kbhr.co/bin/StartService.sh
I think those are the correct attributes for an application like this (and if they’re not 100% correct, I at least know that they work). Note that I tell the system what Linux user and group the application should be started as, and I specify the path to the shell script I created earlier as the ExecStart
parameter.
Now you just need to run a few commands to load this file into the Ubuntu systemd system. First, make sure your file has the right permissions:
# chmod 644 kbhr.service
Then tell the system to find your new service:
# systemctl daemon-reload
Now tell the system to enable your service; this command creates a symbolic link:
# systemctl enable kbhr.service
Created symlink from /etc/systemd/system/multi-user.target.wants/kbhr.service
to /etc/systemd/system/kbhr.service.
Finally, start your service:
# systemctl start kbhr.service
Now you should be able to run a ps
command like this and see that your Play Framework application is running:
# ps auxw | grep java | grep kbhr
You should see a very long line of output that begins with a java
command, like this:
java -Duser.dir=/var/www/kbhr.co/kbhr-1.0...
This tells you that your application has been started. You can now test it with your browser or a curl
command.
If everything is running as expected, this is a great time to reboot it to make sure that your service is started after the reboot.
More information
There are many more configuration variables you can add to your service. For example, here’s the mysql.service file from the /etc/systemd/system/multi-user.target.wants directory on my Ubuntu 16.04 system:
# MySQL systemd service file
[Unit]
Description=MySQL Community Server
After=network.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
PermissionsStartOnly=true
ExecStartPre=/usr/share/mysql/mysql-systemd-start pre
ExecStart=/usr/sbin/mysqld
ExecStartPost=/usr/share/mysql/mysql-systemd-start post
TimeoutSec=600
Restart=on-failure
RuntimeDirectory=mysqld
RuntimeDirectoryMode=755
Here’s the nginx.service file from that same directory:
[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed
[Install]
WantedBy=multi-user.target
I didn’t specify ways to stop or reload my application, so the Nginx file is particularly useful as an example of how to do that. For much more information on this process, run this man
command on your system:
man systemd.service
This tutorial was also helpful:
Summary
In summary, if you wanted to see how to start a Play Framework application as a service on an Ubuntu 16.04 system, I hope this example is helpful.