7 Steps to run a Spring Boot website in Amazon Lightsail

7 Steps to run a Spring Boot website in Amazon Lightsail

I posted why Amazon Lightsail is popular in one of my earlier posts. You may read this post, why we use Lightsail to run a Spring Boot application.

Spring Boot is a popular framework for building Java applications. It makes it easy to create stand-alone, production-grade Spring applications that you can “just run”.

There are several reasons why people are interested in running a Spring Boot application in Amazon Lightsail.

  • Simplicity: Amazon Lightsail is a very simple service to use. It’s easy to get started, and you don’t need to be a cloud expert to use it.
  • Cost-effectiveness: Amazon Lightsail is a very cost-effective way to host applications in the AWS cloud. The prices are very competitive, and you can easily scale your resources up or down as needed.
  • Performance: Amazon Lightsail provides a reliable and performant environment for hosting applications. The service is backed by Amazon’s global infrastructure, and you can be sure that your applications will be available when you need them.
  • Security: Amazon Lightsail provides a secure environment for hosting applications. The service includes a number of security features, such as firewall rules and access control lists, that you can use to protect your applications from unauthorized access.

Overall, Amazon Lightsail is a great option for hosting Spring Boot applications. It’s a simple, cost-effective, and performant way to get your applications up and running in the AWS cloud.

This article serves as a comprehensive guide for the deployment of a Spring Boot application. It encompasses the entirety of the process from initial setup to operational deployment. The guide is structured in a sequential manner, detailing each step to ensure a smooth deployment of your application with the following steps.

Step 1: Creating an account in Amazon AWS
Step 2: Create an Lightsail instance
Step 3: Connecting to the instance using SSH Client
Step 4: Initial server configuration
Step 5: MariaDB installation
Step 6: Spring Boot Configuration
Step 7: Apache reverse proxy configuration

Alright, let’s get things rolling!

Step 1: Creating an account in Amazon AWS

Goto https://aws.amazon.com/ and sign up as a user. You may need a credit card to complete this. This account is necessary to proceed with this tutorial.

Step 2: Create an Lightsail instance

Login to your AWS account. Select Root user while signing in.

AWS Login screen

You will land in the AWS console. Use the search functionality to search for Lightsail. You will see the Lightsail listed under the services section of the search result. Click it.

Search for Lightsail

You will see this Amazon Lightsail screen.

AWS Instances

Click on Create instance to create a new instance. A new instance may cost you as per your consumption.

Instance details

You need to provide the details related to the new instance. 

Firstly it is related to the platform. I select as Linux/Unix

Pick Lightsil instance image

The interface prompts one to select a geographical area for service setup. I opt for the ap-southeast-1 designation. This identifier corresponds to the location in South East Asia where Amazon Web Services establishes its data center operations. For the configuration of my computing instance, the South East Asia region has been selected.

Seelct a region

Inside an AWS region, you’ll find Availability Zones (AZs), which are isolated data centers within that region. Think of a region as a large state and AZs as individual cities within that state. Each AZ has its own independent power, cooling, and networking infrastructure, making them highly fault-tolerant. Ap-southeast-1 has 3 zones. I chose Zone C for my instance.

Choosing the availability zone

Next, choose a blueprint. Lightsail comes with prebuilt instances with packages like WordPress, databases etc. For this tutorial, I chose a vanilla Ubuntu instance. So I clicked ‘OS only’ button. I chose Ubuntu.

Instance blueprint – OS Only

There are optional features

  1. Launch script: You may execute a customized command after the launch of the instance. (Assume you need to install a backup client software, you may provide the command to install the same here). For our tutorial, it is not needed.
  2. Change SSH Key Pair: You need SSH keys to login to Linux instances in Lightsail. You may use default SSH key-pair. Or you may create a new one. We choose to go ahead with new key-pair, which is explained in the following section.
  3. Snapshots: If you want Lightsail to take frequent snapshots of your image automatically, you may check the ‘Enable Automatic Snapshots’ button. It is not needed for our tutorial.

Creating SSH Keys

Click on ‘Change SSH key pair’ to create a new key.

Click ‘Create New

Select the region from which you will be using this key to connect to your Linux server.

Provide a name for your SSH key

Download the private key. You need to note that you can download this only once. So keep it safe. 

Save the private key to your local HDD safely and securely.

Instance plan

Now is the time to choose your instance plan. As per your budget and technical specs, you may choose a plan. It comes with some free options also. Your credit card will be charged at the month end.

Specify the name of the instance and the quantity of the instance you want. For this tutorial, 1 instance is sufficient.

You may enter the tag for the ease of configuration/reporting. But it is purely optional.

Press the Create Instance button to create the instance. Your billing cycle will start now!

You will see the instance is in ‘Pending’ status first. You will see a public IP is allotted to it. As long the server is alive, it will use this public IP. But if the server restarts, there is no guarantee that you will get the same static IP.

After sometime, you will see the instance status is changed from ‘Pending’ to ‘Running’. So you are ready to use your instance now.

You may click on the console icon to get the web shell.

How to get a permanent IP to your Lightsail VM?

As I mentioned earlier, the permanent IP of your Lightsail instance may change after rebooting. This tutorial is about creating a public website. So we need a static IP which is persistent, i.e., the IP should not change even if you restart your instance. How to do it? Let’s see.

Look at the left side menu. Click Networking.

You will find an option to create static IP, CDN and Load Balancer. Click on the Static IP.

Choose the IP location. By default it chooses the southeast-1 region.

You need to assign this IP to your instance to access it from the outside world.

Choose your instance to bind this IP.

Finally click the Create button to create the Static IP.

As you see in the screenshot, static IPs are free in Lightsail, when this post was written. But they should be assigned to an instance to meet this criteria.

Static IP is created and assigned to our instance.

DNS zone

The scope of this article is to run a website. Hence I need a domain. I may register a domain with Amazon Route 53. But I have an economic domain registrar. So I registered my domain over there. To link my domain with Amazon Lightsail, I should create a DNS zone in Lightsail and change the name server in my domain register.

To create a DNS zone, Click the ‘Domains & DNS’ menu item in the left side menu.

Click the ‘Create DNS zone’ button to proceed.

Select the ‘Use a domain from another registrar’.

Enter the name of the domain.

Press the ‘Create DNS zone’ button

DNS zone is created.

Click on the domain and go to the Assignments tab.

To add the DNS zone with our instance, click on ‘+ Add assignment’ button.

Select your domain and resource for the assignment to get completed. We have two resources now. 

  1. The light sail instance
  2. The static IP

I selected the static IP so that the domain will be pointing at the same.

DNS Zone Assignment is completed for our website.

Click on the DNS records. 

You will see the domain name will be pointing at the static IP.

Name servers

When you click on the domain, you will see the name servers of Amazon Lightsail.

I go to my domain registrar website. I click on the name server button on their site to modify the same.

Enter the Amazon Lightsail name servers and press ‘Update Name Servers’. The screen may vary from one registrar to another registrar. You may need to check the documentation or support of your registrar for the right details.

Please note that this change will take up to 1 day to reflect across the globe.

Step 3: Connecting to the instance using SSH Client

Next part of this tutorial is on how to connect to our Lightsail instance using Putty client. We need to import the private key to our Putty client first. For that, open PUTTYgen first in your laptop.

Press Load button in PuTTY Key Generator.

Load our private key, which was downloaded initially from Lightsail.

If you save the private key using Save private key button, Putty will be able to connect to our instance without any password prompt. If you prefer that way, click on the Save private key button. You will see a warning about saving the key without a password. You may press Yes and continue. 

But I want to store it with a passphrase. I enter the Key passphrase and Confirm passphrase and press the Save private key button.

Choose a directory to save the key. Remember this location.

Open PuTTY client now. 

Enter your domain name as Host name and save it.

Click on Connection>SSH>Auth in the left menu.

Look for ‘Private key for authentication’ on the right side and press Browse and select the file we generated from PuTTYgen just now.

Go to Session and select your domain and press Open button.

Press Accept for the Security Alert.

Enter the username as ubuntu.

Enter the passphrase (given in PuTTYgen)

You will be connected to the server.

Step 4: Initial server configuration

We will be setting up a database server, application server and a web server. Before that we should set the timezone.

Setting server timezone

First step is to set the time zone of your server. Because all your applications and databases will use this time. A reboot is needed after changing the timezone.

sudo timedatectl set-timezone Asia/Singapore
sudo reboot

Step 5: MariaDB installation

We will install, configure the MariaDB server and import our database dump in this step.

Install MariaDB first.sudo apt update
sudo apt install mariadb-server

You should protect the database as the default installation is open for root users without a password. This is a crucial step. Any incorrect value may be irreversible for a normal user, even with reinstallation of the database server.

sudo mysql_secure_installation
    Enter current password for root (enter for none): <enter>
    Switch to unix_socket authentication [Y/n] n
    Change the root password? [Y/n] n
    Remove anonymous users? [Y/n] y
    Disallow root login remotely? [Y/n] y
    Remove the test database and access to it? [Y/n] y
    Reload privilege tables now? [Y/n] y

Now you will not be able to connect to MariaDB as a root user as a normal unix user. You need a sudo.

sudo mysql -uroot -p

Create an admin user for day today operations. So I create a user admin@localhost.

GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY '******' WITH GRANT OPTION;
FLUSH PRIVILEGES;

Login as the admin user now.

mysql -u admin -p******

We shall create the database for our application now.

CREATE DATABASE alligator;
SHOW DATABASES;

We shall create a database user that will be the owner of our application database.

CREATE USER 'alligator'@localhost IDENTIFIED BY '******';
SELECT User FROM mysql.user;
GRANT ALL PRIVILEGES ON alligator.* TO 'alligator'@localhost;
FLUSH PRIVILEGES;
SHOW GRANTS FOR 'alligator'@localhost;

Try logging into MariaDB using our database user.

mysql -ualligator -p******

It worked right. Let’s proceed to importing our database dump.

Importing database dump

Dump is copied from the development environment as tar.gz file using WinSCP application. This tutorial does not cover configuring WinSCP with SSH Keys. You may try Googling! Upload the dump to /tmp directory.

Unzip the dumpg

unzip alligator.tar.gz

Extract the tar archive

tar -xvf alligator.tar

Import it to our database, created by us just now.

mysql -ualligator -p****** alligator < alligator.sql

Hurray! We do not see any errors. The database is imported properly.

Step 6: Spring Boot Configuration

As database setup is completed, let’s set up the application now. We will be using a SpringBoot application. Hence the first step is to download the JDK.

JDK Installation

We use the openjdk 21 in this tutorial. To do /tmp directory and download the jdk.

cd /tmp
wget https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_linux-x64_bin.tar.gz

Unzip the JDK file

gunzip openjdk-21.0.2_linux-x64_bin.tar.gz

I want to extract java to /opt directory. Hence use sudo and extract the tar file accordingly.

sudo tar -xvf openjdk-21.0.2_linux-x64_bin.tar -C /opt

We see if the JDK directory is created. Yes. 

ls /opt/ -alt
total 12
drwxr-xr-x  8 root root 4096 Jan 17 03:25 jdk-21.0.2
drwxr-xr-x  3 root root 4096 Jan 17 03:25 .
drwxr-xr-x 19 root root 4096 Jan 17 01:40 ..

Let’s see if we can execute java. Yes we can. Good.

/opt/jdk-21.0.2/bin/java -version
openjdk version "21.0.2" 2024-01-16
OpenJDK Runtime Environment (build 21.0.2+13-58)
OpenJDK 64-Bit Server VM (build 21.0.2+13-58, mixed mode, sharing)

We may keep on updating JDK as and when new releases appear. So the name of the directory may keep on changing. If the name of the java folder changes, we may need to change in so many other places like scripts, services etc. hence it is always a good habit to create a soft link. I create a softlink /opt/jdk which points at our JDK directory.

sudo ln -s /opt/jdk-21.0.2/ /opt/jdk

Let’s see if our java executes fine with our softlink.

/opt/jdk/bin/java -version
openjdk version "21.0.2" 2024-01-16
OpenJDK Runtime Environment (build 21.0.2+13-58)
OpenJDK 64-Bit Server VM (build 21.0.2+13-58, mixed mode, sharing)

Excellent! We shall move to our application configuration now. 

Unix user creation

Our application will be running from the /opt/alligator directory. We shall create the directory first.

sudo mkdir /opt/alligator/

This is the time to create a unix user for the application with /opt/alligator as the home directory.

useradd -m -d /opt/alligator alligator

Set the password for the application user

passwd alligator
******
sudo chown alligator:alligator /opt/alligator/

Let’s see if the user is created with the user group as expected. Yes.

sudo id alligator
uid=1001(alligator) gid=1001(alligator) groups=1001(alligator)

Let’s verify if we are able to login as the application user.

sudo su alligator

Copying Spring Boot application

Following will be the directories in the home directory /opt/alligator

  1. logs – this will contain all log files.
  2. config – this will contain the application.properties
  3. lib – this will contain the spring boot jar file.

Let’s create the directory structure.

sudo su - alligator
mkdir /opt/alligator/lib/
mkdir /opt/alligator/config/
mkdir /opt/alligator/logs/

Upload the spring jar to the /tmp directory using WinSCP. 

Copy the jar file to the lib directory

sudo su - alligator
cp /tmp/alligator-2.jar /opt/alligator/lib/

Spring Configuration application.properties

We shall create application.properties in the config directory and enter the production specific properties over there. All the other missed out properties will use the default values bundled with the application.

vi config/application.properties

I used the following properties for my applicationspring.

datasource.password=*****
logging.file.name=/opt/alligator/logs/alligator.log
logging.level.root=WARN

Application startup script

We need a shell script to start this application, right? Let’s create now.vi cat start-alligator

#i!bash
export JAVA_HOME=/opt/jdk
export PATH=$JAVA_HOME/bin:$PATH
java -jar /opt/alligator/lib/alligator-2.jar

We shall assign right permission to this sensitive file.

chmod 774 /opt/alligator/start-alligator

Let’s see if we are able to run this application as app user.

./start-alligator

Yes it is running fine. Application port is open 8080. You can not verify it on the browser outside as this port is blocked by Lightsail firewall. So issue a telnet to check the port availability.

telnet localhost 8080

If it opens, the application will be running.

Creating a Linux Service in Ubuntu

Next step is to create a Linux service for our operation so that it will be running 24×7

Execute the following command as ubuntu

usersudo vi /etc/systemd/system/alligator.service

Following is the content of this service file.

[Unit]
Description=Alligator
After=syslog.target
[Service]
User=alligator
Restart=always
RestartSec=30s
ExecStart=/bin/bash -c '/opt/alligator/start-alligator'
WorkingDirectory=/opt/alligator
[Install]
WantedBy=multi-user.target

After saving the file, enable the service.

sudo systemctl enable alligator.service

Check if the service is responsive to systemctl command.

sudo systemctl start alligator.service
sudo systemctl status alligator.service
sudo systemctl stop alligator.service
sudo systemctl restart alligator.service

Yes. The application is running.

Step 7: Apache reverse proxy configuration

We can not expose our application directly to the outside world. We need to secure it with a reverse proxy in the front end. We will use Apache server for that.

Let’s install Apache Web Server as ubuntu user.

sudo apt update
sudo apt install apache2

Let’s verify if Apache is installed properly by executing the following commands.

sudo systemctl status apache2
apache2 -version

Reverse proxy configuration

To run the reverse proxy, we need to enable a few modules in Apache. Let’s do it.

sudo a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests

To activate the settings, a restart of the Apache server is necessary.

sudo systemctl restart apache2

We shall create a virtual host for our Spring boot application. Let’s create an Apache configuration file. Apache has a conf file 000-default.conf. We shall use it as a template to create our configuration.

cd /etc/apache2/sites-available/
sudo cp 000-default.conf alligator.conf

Now edit the configuration file

sudo vi alligator.conf

Have a setting like this. This will redirect any requests that reach our static IP to the Spring boot application.

<VirtualHost *:80>
ServerAdmin alligator@xyz.com
ServerName alligator.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Activate the new configuration.

sudo a2ensite alligator.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo systemctl restart apache2

That’s all. This will listen to port 80, which is already open in the Lightsail firewall. Your site will be reachable in the browser now.

This post is written as part of #WriteAPageADay campaign of BlogChatter