Ans: I have written a shell script to install Tomcat 9 on a Linux machine.
The setup is split into multiple files, with the main script named tomcat.sh, and additional files including tomcat.service, context.txt, and tomcat-users.txt.
All files are available in my GitHub repository: https://github.com/protalic-speaks/install-tomcat-9. You can clone the repository and run the tomcat.sh script to install everything. Just paste the following command into your terminal:
git clone https://github.com/protalic-speaks/install-tomcat-9.git
cd install-tomcat-9
bash tomcat.sh
Explanation of the above command:
- git clone https://github.com/protalic-speaks/install-tomcat-9.git — Clones the repository to your system.
- cd install-tomcat-9 — Navigates into the cloned directory.
- bash tomcat.sh — Executes the main installation script.
Note: If you're getting an error while executing the above commands, it could be due to Git not being installed on your server. Please install Git manually.
Below, I’ve also included the contents of each file:
- tomcat.sh
- tomcat.service
- tomcat-users.txt
- context.txt
Tomcat.sh:
#!/bin/bash
# Function to check if a service is running
check_service_status() {
systemctl is-active --quiet "$1"
}
# Function to get the current Tomcat port
get_tomcat_port() {
grep 'Connector port' /opt/tomcat/conf/server.xml | grep 'protocol="HTTP/1.1"' | grep -o 'port="[0-9]*"' | sed 's/port="\([0-9]*\)"/\1/'
}
# Function to get the public IP address
get_public_ip() {
curl -s http://checkip.amazonaws.com
}
# Detect Linux distribution and package manager
detect_os() {
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian|linuxmint|kali|pop|zorin|elementary)
echo "apt"
;;
rhel|centos|rocky|almalinux|fedora|amzn)
if command -v dnf >/dev/null 2>&1; then
echo "dnf"
elif command -v yum >/dev/null 2>&1; then
echo "yum"
elif command -v rpm >/dev/null 2>&1; then
echo "rpm"
else
echo "unsupported"
fi
;;
opensuse|sles)
echo "zypper"
;;
alpine)
echo "apk"
;;
*)
echo "unsupported"
;;
esac
else
echo "unsupported"
fi
}
os=$(detect_os)
if [ "$os" = "unsupported" ]; then
echo "Unsupported or unrecognized operating system. Exiting."
exit 1
fi
# Check and install Java 17 if not installed
if ! java -version 2>&1 | grep -q "17"; then
echo "Checking if Java OpenJDK 17 is installed. Please wait..."
case "$os" in
apt)
sudo apt update -y &> /dev/null
sudo apt install -y wget curl &> /dev/null
;;
dnf)
sudo dnf update -y &> /dev/null
sudo dnf install -y wget curl &> /dev/null
;;
yum)
sudo yum update -y &> /dev/null
sudo yum install -y wget curl &> /dev/null
;;
apk)
sudo apk update &> /dev/null
sudo apk add wget curl tar &> /dev/null
;;
zypper)
sudo zypper refresh &> /dev/null
sudo zypper install -y wget curl tar gzip &> /dev/null
;;
rpm)
echo "RPM-only system detected. Please manually ensure wget and curl are installed."
;;
*)
echo "Unsupported OS for package installation. Exiting."
exit 1
;;
esac
sudo mkdir -p /opt/java-17 &> /dev/null
wget https://download.java.net/java/GA/jdk17/0d483333a00540d886896bac774ff48b/35/GPL/openjdk-17_linux-x64_bin.tar.gz &> /dev/null
sudo tar xf openjdk-17_linux-x64_bin.tar.gz -C /opt/java-17 --strip-components=1 &> /dev/null
export JAVA_HOME=/opt/java-17
export PATH=$JAVA_HOME/bin:$PATH
echo "Java OpenJDK 17 is now installed. Initiating Tomcat installation. Please wait..."
else
echo "Java 17 is already installed." &> /dev/null
fi
# Check if Tomcat is installed
# Check if Tomcat directory exists (partial or full installation)
if [ -d "/opt/tomcat" ]; then
echo "An existing Tomcat installation was detected at /opt/tomcat."
echo "This could be a full or partial installation."
echo ""
echo "What would you like to do?"
echo "1) Remove Tomcat completely (no reinstallation)"
echo "2) Remove and install Tomcat freshly"
echo "3) Keep the existing installation (no changes)"
echo ""
echo "Note: This script won't fix broken or manually-installed Tomcat setups."
read -p "Enter your choice [1/2/3]: " choice
case "$choice" in
1)
echo "Removing existing Tomcat installation..."
sudo systemctl stop tomcat &> /dev/null
sudo systemctl disable tomcat &> /dev/null
sudo rm -rf /opt/tomcat
sudo rm -f /etc/systemd/system/tomcat.service
sudo systemctl daemon-reload
echo "Tomcat has been removed. Exiting script."
exit 0
;;
2)
backup_dir="/tmp/tomcat_backup_$(date +%Y%m%d_%H%M%S)"
echo "Backing up configuration files to $backup_dir"
mkdir -p "$backup_dir"
sudo cp -r /opt/tomcat/conf "$backup_dir/" 2>/dev/null
sudo systemctl stop tomcat &> /dev/null
sudo systemctl disable tomcat &> /dev/null
sudo rm -rf /opt/tomcat
sudo rm -f /etc/systemd/system/tomcat.service
sudo systemctl daemon-reload
echo "Existing Tomcat installation removed. Proceeding with fresh install..."
;;
3)
echo "Keeping the existing Tomcat installation. No changes made."
echo "Note: This script will not fix broken manual installations."
port=$(get_tomcat_port)
echo "Tomcat is already installed on port: $port"
while true; do
read -p "Do you want to change the port? (yes/no): " change_port
if [[ "$change_port" == "yes" ]]; then
while true; do
read -p "Enter new port for Tomcat (1024–65535): " new_port
if [[ "$new_port" =~ ^[0-9]+$ && "$new_port" -ge 1024 && "$new_port" -le 65535 ]]; then
if ! sudo lsof -iTCP:$new_port -sTCP:LISTEN >/dev/null; then
sudo sed -i "s/port=\"$port\"/port=\"$new_port\"/" /opt/tomcat/conf/server.xml
sudo systemctl restart tomcat
port=$new_port
echo "Port successfully changed to: $port and Tomcat restarted."
break 2
else
process_info=$(sudo lsof -iTCP:$new_port -sTCP:LISTEN | awk 'NR==2 {print $1, "with PID", $2}')
if echo "$process_info" | grep -qi 'tomcat'; then
echo "Port $new_port is already used by an existing Tomcat instance ($process_info)."
else
echo "Port $new_port is in use by another service ($process_info)."
fi
echo "Please enter a different port."
fi
else
echo "Invalid port. Please enter a number between 1024 and 65535."
fi
done
elif [[ "$change_port" == "no" ]]; then
break
else
echo "Invalid response! Please enter 'yes' or 'no'."
fi
done
exit 0
;;
esac
fi
if [ ! -d "/opt/tomcat" ]; then
echo "Installing Tomcat..."
sudo mkdir -p /opt/tomcat
# Check if the tomcat user exists
if id "tomcat" &>/dev/null; then
echo "" &> /dev/null
else
sudo useradd -m -U -d /opt/tomcat -s /bin/false tomcat &> /dev/null
fi
sudo yum install wget -y &> /dev/null
# Save the current directory
original_dir=$(pwd)
cd /tmp
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.105/bin/apache-tomcat-9.0.105.tar.gz &> /dev/null
sudo tar xf apache-tomcat-9.0.105.tar.gz -C /opt/tomcat --strip-components=1
sudo chown -R tomcat: /opt/tomcat
sudo chmod -R 755 /opt/tomcat
# Prompt for port selection
while true; do
read -p "Enter port for Tomcat: " port
if [[ "$port" =~ ^[0-9]+$ && "$port" -ge 1024 && "$port" -le 65535 ]]; then
if ! sudo lsof -iTCP:$port -sTCP:LISTEN >/dev/null; then
break # Port is available and valid, proceed silently
else
process_info=$(sudo lsof -iTCP:$port -sTCP:LISTEN | awk 'NR==2 {print $1, "with PID", $2}')
if echo "$process_info" | grep -qi 'tomcat'; then
echo "Port $port is already used by an existing Tomcat instance ($process_info)."
else
echo "Port $port is in use by another service ($process_info)."
fi
echo "Please choose a different port."
fi
else
echo "Invalid port. Please enter a number between 1024 and 65535."
fi
done
sudo sed -i "s/port=\"8080\"/port=\"$port\"/" /opt/tomcat/conf/server.xml
# Add service configuration
sudo cp "$original_dir/tomcat.service" /etc/systemd/system/tomcat.service
sudo cp "$original_dir/tomcat-users.txt" /opt/tomcat/conf/tomcat-users.xml
# Enable manager and host manager
sudo mkdir -p /opt/tomcat/webapps/manager/META-INF
sudo mkdir -p /opt/tomcat/webapps/host-manager/META-INF
sudo cp "$original_dir/context.txt" /opt/tomcat/webapps/manager/META-INF/context.xml
sudo cp "$original_dir/context.txt" /opt/tomcat/webapps/host-manager/META-INF/context.xml
sudo systemctl daemon-reload
sudo systemctl start tomcat
sudo systemctl enable tomcat &> /dev/null
echo ""
echo "Tomcat installed! Also manager and Host manager activated!"
# Save the current directory
original_dir=$(pwd)
# Add service configuration
sudo cp "$original_dir/tomcat.service" /etc/systemd/system/tomcat.service
sudo cp "$original_dir/tomcat-users.txt" /opt/tomcat/conf/tomcat-users.xml
# Enable manager and host manager if not enabled
sudo mkdir -p /opt/tomcat/webapps/manager/META-INF
sudo mkdir -p /opt/tomcat/webapps/host-manager/META-INF
sudo cp "$original_dir/context.txt" /opt/tomcat/webapps/manager/META-INF/context.xml
sudo cp "$original_dir/context.txt" /opt/tomcat/webapps/host-manager/META-INF/context.xml
sudo systemctl daemon-reload
# Check if Tomcat is running
if ! check_service_status tomcat; then
echo "Tomcat is not running. Attempting to restart..."
sudo systemctl restart tomcat
if ! check_service_status tomcat; then
echo "Failed to restart Tomcat. Please check the logs for more details."
sudo journalctl -u tomcat --since "5 minutes ago"
exit 1
fi
else
echo "Tomcat is running."
fi
fi
# Get the public IP address and display the URL to access Tomcat
public_ip=$(get_public_ip)
echo ""
echo ""
echo "##########################################################"
echo "# You can now access Tomcat at: http://$public_ip:$port #"
echo "##########################################################"
echo ""
echo ""
echo "Login details for manager and host-manager by default is:"
echo "Usename: admin"
echo "Password: admin"
echo ""
tomcat.service:
[Unit]Description=Apache Tomcat Web Application ContainerAfter=network.target
[Service]Type=forking
User=tomcatGroup=tomcat
Environment="JAVA_HOME=/opt/java-17"Environment="CATALINA_PID=/opt/tomcat/temp/tomcat.pid"Environment="CATALINA_HOME=/opt/tomcat"Environment="CATALINA_BASE=/opt/tomcat"Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"Environment="JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom"
ExecStart=/opt/tomcat/bin/startup.shExecStop=/opt/tomcat/bin/shutdown.sh
[Install]WantedBy=multi-user.target
tomcat-users.txt:
<?xml version="1.0" encoding="UTF-8"?><!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.--><tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" version="1.0"><!-- By default, no user is included in the "manager-gui" role required to operate the "/manager/html" web application. If you wish to use this app, you must define such a user - the username and password are arbitrary.
Built-in Tomcat manager roles: - manager-gui - allows access to the HTML GUI and the status pages - manager-script - allows access to the HTTP API and the status pages - manager-jmx - allows access to the JMX proxy and the status pages - manager-status - allows access to the status pages only
The users below are wrapped in a comment and are therefore ignored. If you wish to configure one or more of these users for use with the manager web application, do not forget to remove the <!.. ..> that surrounds them. You will also need to set the passwords to something appropriate.--><!-- <user username="admin" password="<must-be-changed>" roles="manager-gui"/> <user username="robot" password="<must-be-changed>" roles="manager-script"/>--><!-- The sample user and role entries below are intended for use with the examples web application. They are wrapped in a comment and thus are ignored when reading this file. If you wish to configure these users for use with the examples web application, do not forget to remove the <!.. ..> that surrounds them. You will also need to set the passwords to something appropriate.--><!-- <role rolename="tomcat"/> <role rolename="role1"/> <user username="tomcat" password="<must-be-changed>" roles="tomcat"/> <user username="both" password="<must-be-changed>" roles="tomcat,role1"/> <user username="role1" password="<must-be-changed>" roles="role1"/>--><role rolename="manager-gui"/><role rolename="manager-script"/><role rolename="manager-jmx"/><role rolename="manager-status"/><role rolename="admin-gui"/><role rolename="admin-script"/><user username="admin" password="admin" roles="manager-gui,admin-gui"/></tomcat-users>
context.txt:
<?xml version="1.0" encoding="UTF-8"?><!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.--><Context antiResourceLocking="false" privileged="true" > <CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor" sameSiteCookies="strict" /><!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />--> <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/></Context>
You'll also be able to access Manager and Host-manager with
- Username: admin
- Password: admin
No comments:
Post a Comment
If you have any doubt or question, you can post comment and I will check it.