You should run the service with an unprivilidged user e.g. joe
Please be careful that non root users can not bind port numbers from 1 to 1024


Firt make sure you some prerequisite modules installed
You can install them using e.g. the cpanm utility

	# First  install the cpanm itself
	curl -L --insecure https://cpanmin.us | perl - App::cpanminus
	
	# The rest modules
	cpanm Data::Dumper
	cpanm XML::Hash::XS
	cpanm JSON::XS
	cpanm YAML::XS
	cpanm Moo
	cpanm Plack
	cpanm Plack::Middleware::Deflater
	cpanm Starman
	cpanm Dancer2
	cpanm Dancer2::Plugin::WebService

or for every modules

	tar xvzf ....tar.gz
	cd ...
	perl Makefile.PL
	make
	make test
	make install
	
Assuming that you will start the application as a non privileged user e.g. joe
Create the user if not exists

	getent group  joe >/dev/null || groupadd joe
	getent passwd joe >/dev/null || useradd -g joe --no-log-init -c "Dancer2-Plugin-WebService user" -s /sbin/nologin joe
	lslogins -o USER,GROUP,UID,SHELL joe

Create the application e.g TestService inside e.g. the /opt folder

	cd /opt
	dancer2 gen --application TestService

Give ownership to joe

	mkdir            /var/log/TestService
	mkdir            /usr/local/sessions
	chown -R joe:joe /opt/TestService
	chown -R joe:joe /var/log/TestService
	chown -R joe:joe /usr/local/sessions

	chown -R joe:joe /usr/share/perl5/site_perl/Dancer2/Plugin/scripts

	chmod u+x /usr/share/perl5/site_perl/Dancer2/Plugin/scripts/LinuxOS/AuthUser.pl
	chmod u+x /usr/share/perl5/site_perl/Dancer2/Plugin/scripts/HttpBasic/users.pl
	chmod u+x /usr/share/perl5/site_perl/Dancer2/Plugin/scripts/HttpBasic/admins.pl





Use logrotate to housekeeping the log files
vi /etc/logrotate.d/TestService

/var/log/TestService/*.log
{
create 640 joe joe
compress
missingok
notifempty
daily
rotate 7
}





If you want your routes ro provide geop ip information install the GeoIP package

At archlinux        pacman -S geoip geoip-database geoip-database-extra
At debian           apt-get install geoip-bin
At fedora, redhat   yum install geoip
At CentOS 5         rpm -Uvh http://mirrors.kernel.org/fedora-epel/5/i386/epel-release-5-4.noarch.rpm
At CentOS 6         rpm -Uvh http://mirrors.kernel.org/fedora-epel/6/i386/epel-release-6-8.noarch.rpm
                    yum repolist
                    yum install geoip







If you want compressed replies
vi /opt/TestService/bin/app.psgi

	#!/usr/bin/perl
	use FindBin;
	use lib "$FindBin::Bin/../lib";
	use TestService;
	use Plack::Builder;
	builder { enable 'Deflater'; TestService->to_app }

Or if you have slow CPU use uncompressed replies
vi /opt/TestService/bin/app.psgi
	
	#!/usr/bin/perl
	use FindBin;
	use lib "$FindBin::Bin/../lib";
	use TestService;	
	TestService->to_app;


Configure the production enviroment
vi /opt/TestService/environments/production.yml


show_errors      : 1
startup_info     : 1
warnings         : 1 
no_server_tokens : 0
log              : "core"
logger           : "file"
engines          :
  logger         :
    File         :
      log_dir    : "/var/log/TestService"
      file_name  : "activity.log"






Configure your application settings
vi /opt/TestService/config.yml



appname      : TestService
environment  : production
plugins      :
  WebService :
    Version             : 1.0.4
    Owner               : Joe Lunchbucket, Joe.Lunchbucket@example.com
    Session directory   : /usr/local/sessions
    Session idle timout : 3600
    Default format      : json
    Command sudo        : /usr/bin/sudo
    Command rm          : /usr/bin/rm
    Routes              :
      test1             : public
      test2             : public
      test3             : private
      
    Allowed hosts:

      - 127.*
      - 10.*
      - 192.168.1.23
      - 172.20.*
      - 32.??.34.4?
      - 4.?.?.??
      - ????:????:????:6d00:20c:29ff:*:ffa3
      - "*"

    User must belong to one or more of the groups:

      - power
      - storage
      - network

    Authentication method:
      Always allow login for testing:
        Command  : MODULE_INSTALL_DIR/scripts/AlwaysOk/AlwaysOk.sh
        Active   : no
        Use sudo : no
      Linux native users:
        Command  : MODULE_INSTALL_DIR/scripts/LinuxOS/AuthUser.pl
        Active   : yes
        Use sudo : yes
      Basic Apache auth for simple users:
        Command  : MODULE_INSTALL_DIR/scripts/HttpBasic/users.pl
        Active   : no
        Use sudo : no
      Basic Apache auth for admins:
        Command  : MODULE_INSTALL_DIR/scripts/HttpBasic/admins.pl
        Active   : no
        Use sudo : no
      Active directory:
        Command  : MODULE_INSTALL_DIR/scripts/Active Directory/Active Directory.pl
        Active   : no
        Use sudo : no
      LDAP:
        Command  : MODULE_INSTALL_DIR/scripts/LDAP/LDAP.pl
        Active   : no
        Use sudo : no






Write your real code e.g.
vi /opt/TestService/lib/TestService.pm




package TestService;
use     strict;
use     warnings;
use     Dancer2;
use     Dancer2::Plugin::WebService;
our     $VERSION = setting('plugins')->{WebService}->{Version};

any '/test_mirror'      => sub { RestReply('DATA_USER_SEND') };
any '/test_get_one_key' => sub { RestReply('k1') };

any '/test_get_data'    => sub {
my ($var1, $var2) = get_data_user('k1', 'k2');
RestReply( Total => ($var1 + $var2), Thought => 'Lets add !' )
};

any '/test_new_data'    => sub { 
my %data = 
set_data_user( new1 => 'N1', new2 => 'N2' );
set_data_user( new3 => 'N3', new4 => 'N4' );
del_data_user( 'new1' , 'new4' );
RestReply('DATA_USER_ALL')
};

setting('plugins')->{'WebService'}->{'Routes'}->{'test_session'} = 'private';

any '/test_session' => sub {
my ($v1, $v2) = get_data_user('k1', 'k2');
	          set_data_session(s1 =>'L1', s2=>'L2', s3=>['L3a', 'L3b']);
	          del_data_session('s7', 's8');
my @Some      = get_data_session('s1', 's2', 's3', 's7');
my %All       = get_data_session();
RestReply(k1=>$v1, k2=>$v2, SesData_A => $Some[2], SesData_b=> [ @Some[0..1] ], SesData_all=> { %All } )
};

dance;









If you are using nginx web server to reverse proxy you service 
from port 80 or for adding https protection ( port 443 )
Add at your nginx.conf something similar to

	...
	upstream TestService { server 127.0.0.1:65535 fail_timeout=0; keepalive 1024; }
	...
	server
	{
	server_name      anotherdimension.mooo.com;
	listen           80;
	listen           443 ssl;
	root             /tmp;
	proxy_redirect   off;
	proxy_set_header Host      $host;
	proxy_set_header X-Real-IP $remote_addr; # needed for real client IP pass as server enviroment variable HTTP_X_REAL_IP

	    location /
	    {
	    fastcgi_param REMOTE_ADDR X-Real-IP;
	    proxy_pass http://TestService;
	    } 
	}





It is a good idea tou start your application as Linux service
We bind at port 127.0.0.1 because we usually publish such services
using the the nginx as reverse proxy

vi /usr/lib/systemd/system/testservice.service




[Unit]
Description=Perl Dancer2 restful web service
Documentation=https://metacpan.org/pod/Dancer2
After=network.target
ConditionPathExists=/usr/bin/site_perl/plackup

[Service]
Type=simple
User=joe
Group=joe
ExecStart=/usr/bin/site_perl/plackup --host 127.0.0.1 --port 65535 --server Starman --workers=10 --env production -a /opt/TestService/bin/app.psgi
ExecStop=/bin/kill -s QUIT $MAINPID
WorkingDirectory=/opt/TestService
KillMode=mixed
KillSignal=QUIT
StandardOutput=journal
StandardError=inherit 
NoNewPrivileges=true
PrivateTmp=true
LimitNOFILE=infinity
RestartPreventExitStatus=255
Restart=on-failure
RestartSec=60s
NotifyAccess=all

[Install]
WantedBy=multi-user.target





start the service

	systemctl enable testservice.service
	systemctl cat    testservice
	systemctl start  testservice
	systemctl show --property=ActiveState testservice
	systemctl status testservice
	journalctl -xeu  testservice | less

to delete the service

	systemctl stop    testservice
	systemctl disable testservice.service
	rm /usr/lib/systemd/system/testservice.service

start the application manual

	cd /opt/TestService; sudo -u joe /usr/bin/site_perl/plackup --host 127.0.0.1 --port 65535 --server Starman --workers=10 --env production -a /opt/TestService/bin/app.psgi

or during development

	cd /opt/TestService; sudo -u joe /usr/bin/site_perl/plackup --port 65535 -a /opt/TestService/bin/app.psgi --Reload /opt/TestService/lib,/opt/TestService/config.yml,/usr/share/perl5/site_perl/Dancer2/Plugin
	cd /opt/TestService; sudo -u joe /usr/bin/site_perl/plackup --port 65535 -a /opt/TestService/bin/app.psgi

or without Plack

	sudo -u joe  perl /opt/TestService/bin/app.psgi

quick test

	netstat -anp | grep :65535
	curl -X GET http://localhost:65535/info?to=human