Setup a Mojolicious local::lib installation using cpanm

Setup Mojolicious local::lib installation

It is better to run Mojolicious apps as dedicated user than root.

Here I present a short guide on how acheive this.

The following dependencies are needed:

The actual package names varies from distro to distro.

First create a user that somehow describes your application (as root and replace coolmojo with what you feel like):

useradd -s /bin/bash -d /opt/coolmojo -m -c"Cool mojo user for my mojo project" coolmojo

Now su to your new user:

su - coolmojo

First off, ensure that you have direct access to the internet, if you use a proxy you need to export proxy setting first.

If proxy then:

export https_proxy=http://proxy-something:3128 http_proxy=http://proxy-something:3128 ftp_proxy=http://proxy-something:3128

With this is in place install cpanm and mojolicious still using your newly created user (skip the cpanm part if your distro provides cpanm and you wish to use that version):

wget -O- https://cpanmin.us | perl - -l $HOME/perl5 App::cpanminus local::lib && echo 'eval `perl -I $HOME/perl5/lib/perl5 -Mlocal::lib`' >> $HOME/.bash_profile && echo 'export MANPATH=$HOME/perl5/man:$MANPATH' >> $HOME/.bash_profile
. .bash_profile
cpanm Data::Dumper Compress::Raw::Zlib Digest::MD5 Digest::SHA IO::Compress::Gzip Mojolicious

Now you are ready to begin developing your Mojolicious application.

mojo generate CoolMojo

Nginx reverse proxy with https

Here is a template example for reverse proxying using https to your Mojolicious applicaton:

upstream UPSTREAMNAME {
    server 127.0.0.1:PORT;
}

server {
    listen 80;
    server_name SERVICEFQDN;
    return 301 https://SERVICEFQDN;
}

server {
    listen   443 ssl http2;
    server_name SERVICEFQDN;
    error_log /var/log/nginx/SERVICEFQDN-error.log warn;
    access_log /var/log/nginx/SERVICEFQDN-access.log;
    ssl    on;
    ssl_certificate    SSLCRTPATH;
    ssl_certificate_key    SSLKEYPATH;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_dhparam DHPARAMPATH;
    location / {
      proxy_pass http://UPSTREAMNAME;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Copy/paste above code to, let's say, coolmojo.conf.

Search and replace the CAPS with your values:

sed -i 's|UPSTREAMNAME|coolmojo|g
s|PORT|4777|g
s|SERVICEFQDN|coolmojo.example.com|g
s|SSLCRTPATH|/etc/letsencrypt/coolmojo.example.com/live/fullchain.pem|g
s|SSLKEYPATH|/etc/letsencrypt/coolmojo.example.com/live/privkey.pem|g
s|DHPARAMPATH|/etc/ssl/certs/dhparam.pem|g' coolmojo.conf

Now copy the nginx conf to nginx conf.d:

cp coolmojo.conf /etc/nginx/conf.d/ && systemctl restart nginx

Test if you base application works by:

su - coolmojo
cd cool_mojo
morbo -l http://*:4777 script/cool_mojo

Navigate the url of your app in your favorite browser and see if it works.

Systemd unit for your app

Here is a template you can use for a systemd unit for your local::lib Mojolicious app with hypnotoad enabled:

[Unit]
Description=APPNAME mojolicious start script
Requires=network.target
After=network.target

[Service]
User=USERNAME
Environment="PATH=/opt/USERNAME/perl5/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
Environment="PERL5LIB='/opt/USERNAME/perl5/lib/perl5:/opt/USERNAME/perl5/lib/perl5/x86_64-linux-thread-multi:/usr/local/lib64/perl5:/usr/local/share/perl5:/usr/lib64/perl5/vendor_perl:/usr/share/perl5/vendor_perl:/usr/lib64/perl5:/usr/share/perl5'"
Environment="PERL_LOCAL_LIB_ROOT=\"/opt/USERNAME/perl5${PERL_LOCAL_LIB_ROOT+:}${PERL_LOCAL_LIB_ROOT}\""
Environment="PERL_MB_OPT='--install_base \"/opt/USERNAME/perl5\"'"
Environment="PERL_MM_OPT='INSTALL_BASE=/opt/USERNAME/perl5'"
Type=simple
RemainAfterExit=yes
SyslogIdentifier=APPNAME
PIDFile=/opt/USERNAME/APPNAME/pid/APPNAME.pid
ExecStart=/opt/USERNAME/perl5/bin/hypnotoad /opt/USERNAME/APPNAME/script/APPNAME -f
ExecStop=/opt/USERNAME/perl5/bin/hypnotoad -s /opt/USERNAME/APPNAME/script/APPNAME
ExecReload=/opt/USERNAME/perl5/bin/hypnotoad /opt/USERNAME/APPNAME/script/APPNAME

[Install]
WantedBy=multi-user.target

Copy/paste above to cool_mojo.service

And do some more sed work:

sed -i 's|USERNAME|coolmojo|g;s|APPNAME|cool_mojo|g' cool_mojo.service

As root do:

cp cool_mojo.service /usr/lib/systemd/system/ && systemctl daemon-reload

Finally

All the above should of course be accomodated to fit your needs. The responsibility is yours.