Using Azure to deploy your Java projects is expensive and time consuming. Let’s learn how to deploy a Java Spring Boot web server to Amazon EC2.
This will cost you just $3 / month. With Azure, you don’t even know how much it is going to cost you.
In this tutorial, we are focusing on deploying our Java Spring Boot server to Amazon EC2 - so we are not going to learn how to build a Spring Boot web service from scratch.
If you don’t have an existing project, you can clone our example repository from GitHub.
First, go to AWS Console for EC2 and select Amazon Linux 2023 AMI and 64-bit (Arm) Architecture.
In the instance type you can select whatever you want. Here I am going with the cheapest instance, which is t4g.nano which will give us 2vCPU and 512 MiB of RAM.
This t4g.nano instance will cost you just $3/month in us-east-1 . Breakdown of On-Demand Linux base pricing:
= $0.0042 / hour = $0.0042 * 24 / day = $0.0042 * 24 * 30 / month = $3.024 / month
In Key pair select or create a new SSH key pair for your instance. We will need this to login.
In the Network section allow HTTP and HTTPS traffic, you can also select existing security group as well.
Now Launch instance with the default storage config by clicking on Launch instance on the bottom right.
Our EC2 instance was created with this success message: Successfully initiated launch of instance (i-xxxx)
Go to your instance, find and copy the public IP by selecting the instance:
We will be using rsync , so it’s best to connect using the terminal.
Alternatively, you can use the connect button to directly get the command or connect to EC2 from the browser itself.
The default username for Amazon Linux EC2 instance is ec2-user .
ssh -i your-key.pem ec2-user@your-ip-address
Type yes and save the fingerprint:
On successful login you’ll see the Amazon Linux logo:
, #_ ~\_ ####_ Amazon Linux 2023 ~~ \_#####\ ~~ \###| ~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023 ~~ V~' '-> ~~~ / ~~._. _/ _/ _/ _/m/' Last login: Mon Jun 3 13:15:51 2024 from 46.36.xxx.53 [ec2-user@ip-172-31-xx-82 ~]$
All you need to do is use yum to install the headless java-17 :
sudo yum install java-17-amazon-corretto-headless
Type y and hit enter to install Java on your EC2 instance:
[ec2-user@ip-172-31-19-82 ~]$ sudo yum install java-17-amazon-corretto-headless Last metadata expiration check: 1 day, 17:42:09 ago on Tue Jun 18 04:50:04 2024. Dependencies resolved. ============================================================================================================================================================================== Package Architecture Version Repository Size ============================================================================================================================================================================== Installing: java-17-amazon-corretto-headless aarch64 1:17.0.11+9-1.amzn2023.1 amazonlinux 91 M Installing dependencies: alsa-lib aarch64 1.2.7.2-1.amzn2023.0.2 amazonlinux 492 k cairo aarch64 1.17.6-2.amzn2023.0.1 amazonlinux 669 k dejavu-sans-fonts noarch 2.37-16.amzn2023.0.2 amazonlinux 1.3 M dejavu-sans-mono-fonts noarch 2.37-16.amzn2023.0.2 amazonlinux 467 k dejavu-serif-fonts noarch 2.37-16.amzn2023.0.2 amazonlinux 1.0 M fontconfig aarch64 2.13.94-2.amzn2023.0.2 amazonlinux 278 k fonts-filesystem noarch 1:2.0.5-12.amzn2023.0.2 amazonlinux 9.5 k freetype aarch64 2.13.0-2.amzn2023.0.1 amazonlinux 412 k google-noto-fonts-common noarch 20201206-2.amzn2023.0.2 amazonlinux 15 k google-noto-sans-vf-fonts noarch 20201206-2.amzn2023.0.2 amazonlinux 492 k graphite2 aarch64 1.3.14-7.amzn2023.0.2 amazonlinux 93 k harfbuzz aarch64 7.0.0-2.amzn2023.0.1 amazonlinux 843 k javapackages-filesystem noarch 6.0.0-7.amzn2023.0.6 amazonlinux 12 k langpacks-core-font-en noarch 3.0-21.amzn2023.0.4 amazonlinux 10 k libX11 aarch64 1.7.2-3.amzn2023.0.4 amazonlinux 648 k libX11-common noarch 1.7.2-3.amzn2023.0.4 amazonlinux 152 k libXau aarch64 1.0.9-6.amzn2023.0.2 amazonlinux 32 k libXext aarch64 1.3.4-6.amzn2023.0.2 amazonlinux 40 k libXrender aarch64 0.9.10-14.amzn2023.0.2 amazonlinux 27 k libjpeg-turbo aarch64 2.1.4-2.amzn2023.0.5 amazonlinux 191 k libpng aarch64 2:1.6.37-10.amzn2023.0.6 amazonlinux 121 k libxcb aarch64 1.13.1-7.amzn2023.0.2 amazonlinux 231 k pixman aarch64 0.40.0-3.amzn2023.0.3 amazonlinux 194 k xml-common noarch 0.6.3-56.amzn2023.0.2 amazonlinux 32 k Transaction Summary ============================================================================================================================================================================== Install 25 Packages Total download size: 98 M Installed size: 271 M Is this ok [y/N]:
Run java --version to find if you have installed Java and JDK correctly.
You should see something like this:
[ec2-user@ip-172-31-19-82 ~]$ java --version openjdk 17.0.11 2024-04-16 LTS OpenJDK Runtime Environment Corretto-17.0.11.9.1 (build 17.0.11+9-LTS) OpenJDK 64-Bit Server VM Corretto-17.0.11.9.1 (build 17.0.11+9-LTS, mixed mode, sharing)
Just run mvn package to create the .jar file of your Java application. You’ll see two .jar files inside target directory:
├── hello-0.0.1-SNAPSHOT.jar ├── hello-0.0.1-SNAPSHOT.jar.original
Copy the file ending with SNAPSHOT.jar to your remote maching:
rsync target/hello-0.0.1-SNAPSHOT.jar ec2-user@your-ec2-ip-addr:~/
You can confirm on the EC2 machine if the jar file got transferred or not using ls :
[ec2-user@ip-172-31-xx-82 ~]$ ls hello-0.0.1-SNAPSHOT.jar
We installed Java earlier so that we can use it’s CLI to run the jar file using -jar and passing the path for the .jar file:
java -jar hello-0.0.1-SNAPSHOT.jar
[ec2-user@ip-172-31-19-82 ~]$ java -jar hello-0.0.1-SNAPSHOT.jar . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.3.0) 2024-06-19T22:43:29.909Z INFO 684333 --- [hello] [ main] com.learnaws.hello.HelloApplication : Starting HelloApplication v0.0.1-SNAPSHOT using Java 17.0.11 with PID 684333 (/home/ec2-user/hello-0.0.1-SNAPSHOT.jar started by ec2-user in /home/ec2-user) 2024-06-19T22:43:29.929Z INFO 684333 --- [hello] [ main] com.learnaws.hello.HelloApplication : No active profile set, falling back to 1 default profile: "default" 2024-06-19T22:43:32.204Z INFO 684333 --- [hello] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) 2024-06-19T22:43:32.223Z INFO 684333 --- [hello] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2024-06-19T22:43:32.224Z INFO 684333 --- [hello] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.24] 2024-06-19T22:43:32.287Z INFO 684333 --- [hello] [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2024-06-19T22:43:32.288Z INFO 684333 --- [hello] [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2209 ms 2024-06-19T22:43:33.135Z INFO 684333 --- [hello] [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 1 endpoint beneath base path '/actuator' 2024-06-19T22:43:33.259Z INFO 684333 --- [hello] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' 2024-06-19T22:43:33.303Z INFO 684333 --- [hello] [ main] com.learnaws.hello.HelloApplication : Started HelloApplication in 4.11 seconds (process running for 4.915)
Go to the security group attached to your EC2 instance and add port range of 8080:
Now we just visit the IP followed by the port ( 8080 )
❯ curl 3.xx.xxx.161:8080/hello\?name=LearnAWS.io Hello LearnAWS.io! It's 2024-06-19T22:51:56.371516135Z%
❯ curl 3.xx.xxx.161:8080/actuator/health "status":"UP">%
That’s it! You’re ready to go.
On system restart and application crash we want our application to start automatically, to achieve this we can use systemd.
Create a service file in /etc/systemd/system/java-server.service using vim :
sudo vim /etc/systemd/system/java-server.service
Press i and paste the content and save it with Esc followed by :wq .
[Unit] Description=Spring Boot Server [Service] ExecStart=java -jar /home/ec2-user/hello-0.0.1-SNAPSHOT.jar Restart=on-failure RestartSec=1s [Install] WantedBy=multi-user.target
Now you’ll need to reload systemd and enable the java server:
sudo systemctl daemon-reload sudo systemctl enable java-server
sudo systemctl start java-server
sudo systemctl status java-server
You’ll see something like this:
● java-server.service - Spring Boot Server Loaded: loaded (/etc/systemd/system/java-server.service; enabled; preset: disabled) Active: active (running) since Thu 2024-06-20 15:58:30 UTC; 53s ago Main PID: 712513 (java) Tasks: 30 (limit: 406) Memory: 140.0M CPU: 8.844s CGroup: /system.slice/java-server.service └─712513 java -jar /home/ec2-user/hello-0.0.1-SNAPSHOT.jar
Now this ensures your Java web server will keep running even when you restart your system or logout from the SSH session.