23 August, 2017

Deploying a Spring application as a Linux service behind nginx (Ubuntu Server 16.04)


1. Create, build and run locally the application

The application to deploy is a JPA Data with REST from the official spring docs. But, instead of the system wide gradle mentioned in the Spring documentation we'll be using the ./gradlew wrapper since this is the recommended way of doing things. The gradle wrapper is usually committed to the source control.



We are using Gradle, not Maven. A Gradle vs Maven comparison: https://dzone.com/articles/gradle-vs-maven and https://gradle.org/maven-vs-gradle/.

Clone the project and prepare:
git clone https://github.com/spring-guides/gs-accessing-data-rest.git

cd gs-accessing-data-rest/ 

# View current remotes
git remote -v

# remove remote:
git remote rm origin

We removed the remote github URL and became the sole owner of the project.

Next, let's have a look at the available gradle tasks and after that build and run the application locally:
cd complete/

./gradlew tasks

./gradlew build

java -jar build/libs/gs-accessing-data-rest-0.1.0.jar

#test if it is working:
curl http://localhost:8080






2. Upload the jar and register the application as a service

Now we will upload the jar file to the remote Ubuntu server. For this purpose we should have created a VirtualBox Ubuntu 16.04 Server VM and installed Java on it.

# copy local file to remote:
sshpass -p '<password>' scp -r -v /home/<user>/development/projects/_java_misc/gs-accessing-data-rest/complete/build/libs/gs-accessing-data-rest-0.1.0.jar <user>@192.168.3.150:/home/<user>/apps/gs_rest_app_folder

# log in to remote:
ssh '<user>@192.168.3.150'

# on remote, check if new file is there:
cd apps/gs_rest_app_folder
ls -alh

# on remote, run the jar:
java -jar gs-accessing-data-rest-0.1.0.jar

# on the local, check that server is serving the application:
curl http://192.168.3.150:8080


After this we want our application to be easily started as Unix/Linux services.

Systemd is the successor of the System V init system, and is now being used by many modern Linux distributions.

On the server, create the .service  file:
sudo vi /etc/systemd/system/gs_rest.service

And add the following:
[Unit]
Description=gs_rest
After=syslog.target

[Service]
User=<user_name>
WorkingDirectory=/home/vb_dhr/apps/gs_rest_app_folder
ExecStart=/usr/bin/java -Xmx256m -jar /home/<user_name>/apps/gs_rest_app_folder/gs-accessing-data-rest-0.1.0.jar
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target


Start/stop/reload the service using the following commands:

# flag the application to start automatically on system boot :
systemctl enable gs_rest.service

# start it now:
systemctl start gs_rest.service

systemctl restart gs_rest.service

sudo systemctl status gs_rest.service

To check if it's working do a system reboot and go to http://vm_ip_address:8080/ to see the result.

We have now a fully working Spring application that will start automatically on server reboot.

3. Spring application behind nginx

sudo apt-get install nginx

cd /etc/nginx/sites-available

cp default default_backup

vi default

Edit /etc/nginx/sites-available/default:

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;

        # root /var/www/html;
        root /home/vb_dhr/apps/gs_rest_app_folder;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                # try_files $uri $uri/ =404;
                proxy_pass  http://localhost:8080;
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #       include snippets/fastcgi-php.conf;
        #
        #       # With php7.0-cgi alone:
        #       fastcgi_pass 127.0.0.1:9000;
        #       # With php7.0-fpm:
        #       fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
}


sudo systemctl restart nginx

You can see now that the application is being served on port 80:



No comments:

Post a Comment