Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: December 20, 2024
Deploying React applications to a production-ready environment often requires efficiently and securely serving static files. Apache Tomcat, a widely used Java-based web server, is an excellent choice for hosting React applications due to its robust configuration options and high reliability.
In this tutorial, we’ll explore the detailed process of building and deploying a React application on a Tomcat server. This involves creating a React application, enhancing it with routing, and configuring the Tomcat server. At the end of this tutorial, we’ll have a React application running seamlessly on the Tomcat server.
We tested all the commands and code in this tutorial on Kali Linux. Unless otherwise specified, it should work in most Linux environments
To illustrate the deployment process, we create a sample React application and prepare it for deployment. Additionally, we also include routing functionality to simulate a real-world application scenario.
Firstly, we use the create-react-app CLI tool to scaffold a new React project:
$ npx create-react-app my-sample-app
The command creates a new directory named my-sample-app with all the necessary files and dependencies for a React application.
Next, let’s start with adding routing functionality to the application. We install the react-router-dom library which is essential for managing navigation in React applications:
$ cd my-sample-app
$ npm install react-router-dom
This library allows us to define and manage routes seamlessly.
Furthermore, we now update the src/App.js file to include routing logic. This file defines the main application component, which serves as the application entry point. Let’s replace the existing content of src/App.js with a new implementation:
cat > src/App.js << EOF
import React from "react";
import { BrowserRouter as Router, Route, Routes, Link } from "react-router-dom";
const Home = () => <h2>Welcome to My Sample React App!</h2>;
const About = () => <h2>About This App</h2>;
function App() {
return (
<Router>
<div>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
</nav>
<Routes>
<Route path="/about" element={<About />} />
<Route path="/" element={<Home />} />
</Routes>
</div>
</Router>
);
}
export default App;
EOF
This updated file introduces two pages which are Home and About. Additionally, it defines the navigation links for routing between them.
Further, let’s adjust the base URL (Homepage) in the package.json file on the React application:
$ nano package.json
...
},
"homepage": "http://localhost:8080/simpleapp"
}
Here, we added the “homepage”: “http://localhost:8080/simpleapp to the JSON file. It ensures the generated build file references the correct base path for assets.
Finally, let’s build the React application in the React project directory and generate the production build:
$ npm run build
The build artifacts are generated in the build directory. Additionally, this directory contains static files, such as index.html, JavaScript bundles, and CSS, ready to be served by a web server like Tomcat.
With the React application built and ready, let’s prepared to move on to setting up Apache Tomcat and deploying the application.
Apache Tomcat is available as a compressed archive that can be downloaded directly from its official website. As of the time of writing this article, the latest version of Apache Tomcat is version 11.0.1.
Firstly, let’s download the Tomcat archive using wget the command:
$ wget https://downloads.apache.org/tomcat/tomcat-11/v11.0.1/bin/apache-tomcat-11.0.1.tar.gz
...
apache-tomcat-11.0.1.tar.gz 100%[==============================================>] 13.01M 830KB/s in 14s
2024-12-06 08:55:35 (976 KB/s) - ‘apache-tomcat-11.0.1.tar.gz’ saved [13643429/13643429]
Once downloaded, we extract the content of the archive:
$ tar -xvzf apache-tomcat-11.0.1.tar.gz
Note that the extracted directory contains all the files necessary for running Tomcat.
For better security and management, let’s create a dedicated system user for running the Tomcat service:
$ sudo useradd -r -m -U -d /opt/tomcat -s /bin/false tomcat
Let’s explain what each of them does:
Additionally, this user will not have login privileges.
Next, let’s move the extracted Tomcat files to the appropriate directory under /opt:
$ sudo mv apache-tomcat-11.0.1 /opt/tomcat
For easier management, we create a symbolic link to the Tomcat directory:
$ sudo ln -s /opt/tomcat/apache-tomcat-11.0.1 /opt/tomcat/updated
In particular, this link ensures that future upgrades can be managed without modifying existing configurations.
Further, let’s change the ownership of the Tomcat files to the dedicated tomcat user:
$ sudo chown -R tomcat: /opt/tomcat/*
Additionally, we grant permissions for the Tomcat scripts located in the bin directory:
$ sudo sh -c 'chmod +x /opt/tomcat/updated/bin/*.sh'
This step ensures all startup and management scripts are executable.
Furthermore, let’s create a systemd service file for Tomcat:
$ sudo nano /etc/systemd/system/tomcat.service
Then, we add the following configuration inside the file:
[Unit]
Description=Apache Tomcat Web Application Container
After=network.target
[Service]
Type=forking
Environment="JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64"
Environment="CATALINA_PID=/opt/tomcat/updated/temp/tomcat.pid"
Environment="CATALINA_HOME=/opt/tomcat/updated/"
Environment="CATALINA_BASE=/opt/tomcat/updated/"
Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"
Environment="JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom"
ExecStart=/opt/tomcat/updated/bin/startup.sh
ExecStop=/opt/tomcat/updated/bin/shutdown.sh
User=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always
[Install]
WantedBy=multi-user.target
Next, we reload the systemd daemon to apply the changes:
$ sudo systemctl daemon-reload
Furthermore, we start the Tomcat service:
$ sudo systemctl start tomcat
To check if it’s successful, let’s verify the status of the Tomcat service:
$ sudo systemctl status tomcat
● tomcat.service - Apache Tomcat Web Application Container
Loaded: loaded (/etc/systemd/system/tomcat.service; disabled; preset: disabled)
Active: active (running) since Fri 2024-12-06 16:33:00 EST; 32s ago
Process: 103015 ExecStart=/opt/tomcat/updated/bin/startup.sh (code=exited, status=0/SUCCESS)
Main PID: 103022 (java)
Tasks: 31 (limit: 4615)
Memory: 167.9M
CPU: 4.695s
CGroup: /system.slice/tomcat.service
└─103022 /usr/lib/jvm/java-1.17.0-openjdk-amd64/bin/java -Djava.util.logging.config.file=/opt/tomcat/u>
Dec 06 16:33:00 kali systemd[1]: Starting Apache Tomcat Web Application Container...
Dec 06 16:33:00 kali startup.sh[103015]: Tomcat started.
Dec 06 16:33:00 kali systemd[1]: Started Apache Tomcat Web Application Container.
Finally, we enable the Tomcat service to start on boot:
$ sudo systemctl enable tomcat
Created symlink /etc/systemd/system/multi-user.target.wants/tomcat.service → /etc/systemd/system/tomcat.service.
We now have Apache Tomcat installed and running as a system service, ready for deploying the React applications.
Deploying the react application to the Tomcat server is seamless. Since we’ve built the react application in the earlier section, we copy the build folder to the Tomcat webapps directory:
$ sudo cp -r /home/kali/my-sample-app/build /opt/tomcat/updated/webapps/simpleapp
Here, the simpleapp directory name matches the basename used in the React application’s Router. Furthermore, once the React application’s build files are in place, Tomcat will automatically deploy the application.
Additionally, we can verify the deployment by navigating to the following URL:
http://ip-address:8080/simpleapp
We replace ip-address with our system IP address.
As can be seen, the deployment of the react application on the Apache Tomcat server has been successful.
In this article, we’ve demonstrated the process of deploying a React application on an Apache Tomcat server. We started with building a sample react application and incorporating routing functionalities to configure and secure the Tomcat environment.
Furthermore, this approach highlights the compatibility of modern web frameworks with traditional server technologies like Tomcat.
The code for the entire application alongside the server is available over on GitHub.