Apache Tomcat 11 on AWS User Guide
Overview
This image runs Apache Tomcat 11, the open source implementation of the Jakarta Servlet, Jakarta Pages, Jakarta Expression Language and Jakarta WebSocket specifications. Tomcat is installed under /opt/tomcat and run by a dedicated unprivileged tomcat system account under a systemd service that starts the container on boot and restarts it on failure. The container listens on port 8080.
The Tomcat Manager application administrator password is generated on the first boot of every deployed instance. Two instances launched from the same Amazon Machine Image never share a password. The password is written to /root/tomcat-credentials.txt with mode 0600 so that only the root user can read it.
The Manager application at /manager/html and the Host Manager application at /host-manager/html keep their Tomcat default access control: a valve restricts them to the loopback address, so they are reachable only from the instance itself. This is a deliberate security default and is left in place. You reach those applications from your workstation over an SSH tunnel, which arrives at the instance as a loopback connection. The public landing page on port 8080 needs no tunnel.
Tomcat reads no instance metadata. The container serves on whatever public DNS name or IP address visitors reach the instance on, so deployments behind an Application Load Balancer, in a private subnet, or on a custom domain all work without changes.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and inbound port 8080 from the networks your visitors will use
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Step 1: Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Apache Tomcat. Select the cloudimg listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network and inbound port 8080 from the networks your visitors use. Leave the root volume at the default size or larger.
Select Launch instance. First boot initialisation takes approximately one minute after the instance state becomes Running and the status checks pass.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg Apache Tomcat Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22 and 8080 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":30,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=apache-tomcat-01}]'
The command prints a JSON document on success. Note the instance ID, then retrieve its public address once it is running with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Step 3: Connect and Retrieve the Manager Password
Connect over SSH with the key pair you selected and the public IP address from step 2. The SSH login user depends on the operating system of the AMI variant you launched:
| AMI variant | SSH login user |
|---|---|
| Apache Tomcat 11 on Ubuntu 24.04 | ubuntu |
The first boot service runs before the SSH daemon becomes ready, so the credentials file is always in place when you log in for the first time.
ssh <login-user>@<public-ip>
sudo cat /root/tomcat-credentials.txt
You will see a plain text file containing the Tomcat URL, the Manager administrator username (tomcatadmin), and the administrator password. Copy these values somewhere secure (a password manager or encrypted vault). Do not commit them to source control.
From the same SSH session you can confirm the deployment is healthy:
curl -fsS -o /dev/null -w 'landing page HTTP %{http_code}\n' http://127.0.0.1:8080/
systemctl is-active tomcat.service
A landing page HTTP 200 response and active confirm the servlet container is serving requests.
Step 4: View the Tomcat Landing Page
Open a web browser and navigate to http://<public-ip>:8080/. Tomcat serves its landing page, which confirms the container is installed and running and links to the bundled documentation.

The landing page is the only Tomcat surface reachable directly over the public port. The Manager and Host Manager applications are restricted to the instance loopback address, so the next step opens an SSH tunnel to reach them.
Step 5: Reach the Manager Application over an SSH Tunnel
The Manager and Host Manager applications are restricted to the loopback address by a valve in each application's META-INF/context.xml. This is a deliberate security default: the management consoles are never exposed on the public port. To reach them, open an SSH tunnel from your workstation that forwards a local port to the instance's port 8080.
In a terminal on your workstation, run the following and leave it running:
ssh -L 8080:127.0.0.1:8080 <login-user>@<public-ip>
With the tunnel open, browse on your workstation to http://127.0.0.1:8080/manager/html. The connection reaches Tomcat as a loopback connection, so the valve permits it. Your browser prompts for HTTP Basic authentication: enter the username tomcatadmin and the password from /root/tomcat-credentials.txt.

The Manager application lists every web application deployed in the container with its context path, running state, and active session count. From here you can start, stop, reload, and undeploy applications, and deploy new ones. The bundled /docs and /examples applications are the Tomcat documentation and the servlet and JSP examples.
Step 6: Administer Virtual Hosts with the Host Manager
With the same SSH tunnel open, browse to http://127.0.0.1:8080/host-manager/html and authenticate as tomcatadmin with the same password. The Host Manager application administers Tomcat virtual hosts.

From the Host Manager you can add and remove virtual hosts and inspect the server information for the running container. Most single application deployments use the default localhost host and never need to change this; the Host Manager is there for multi tenant deployments that serve several hostnames from one container.
Step 7: Deploy a Java Web Application
There are two ways to deploy a WAR file to this image.
The first is through the Manager application. With the SSH tunnel from step 5 open, scroll to the Deploy section of http://127.0.0.1:8080/manager/html, choose your .war file under WAR file to deploy, and select Deploy. Tomcat unpacks the application and it appears in the applications list.
The second is by copying the WAR onto the server. Copy the file to the instance with scp, then move it into the Tomcat webapps directory, which the container scans automatically:
scp myapp.war <login-user>@<public-ip>:/tmp/myapp.war
ssh <login-user>@<public-ip> 'sudo install -o tomcat -g tomcat -m 0644 /tmp/myapp.war /opt/tomcat/webapps/myapp.war'
Tomcat deploys myapp.war as the /myapp context within a few seconds. Browse to http://<public-ip>:8080/myapp/ to reach it. To deploy an application at the root context, replace the bundled ROOT application in /opt/tomcat/webapps/.
Step 8: Manage the Tomcat Service
Tomcat runs as the systemd service tomcat.service under the unprivileged tomcat account. Manage it with the standard systemctl commands:
sudo systemctl status tomcat.service
sudo systemctl restart tomcat.service
sudo journalctl -u tomcat.service --since '10 minutes ago'
The container's own logs are written under /opt/tomcat/logs; catalina.out is the main log and the access log records every request.
Step 9: Tune the Java Virtual Machine
The image ships a conservative heap configuration in /opt/tomcat/bin/setenv.sh: an initial heap of 512 MB and a maximum of 1024 MB. For a larger instance type, raise the maximum heap so Tomcat can use the available memory. Edit the file as root:
sudo nano /opt/tomcat/bin/setenv.sh
Adjust the -Xms and -Xmx values in the CATALINA_OPTS line. A common guideline is to set the maximum heap to roughly half of the instance memory. Save the file and restart the service with sudo systemctl restart tomcat.service for the new settings to take effect. Confirm the running JVM picked them up under the Server Status page of the Manager application.
Step 10: Rotate the Manager Password
The Manager administrator password is generated on first boot. To set your own, edit the Tomcat users file as root:
sudo nano /opt/tomcat/conf/tomcat-users.xml
Change the password attribute on the <user username="tomcatadmin" ...> line, save the file, and restart Tomcat with sudo systemctl restart tomcat.service. To add further accounts, add more <user> elements; the available management roles are manager-gui for the Manager HTML interface, manager-script for the Manager text API, and admin-gui for the Host Manager interface.
Step 11: Enable HTTPS with a Reverse Proxy
For any production deployment serve the application over HTTPS so session cookies and authentication tokens cannot be intercepted. The recommended pattern on AWS is to terminate TLS in front of Tomcat rather than in the container itself.
For a single instance, install nginx as a reverse proxy and use certbot to obtain a certificate. The following assumes a DNS record points your fully qualified domain name at the instance's public IP address.
sudo apt-get update && sudo apt-get install -y nginx certbot python3-certbot-nginx
sudo tee /etc/nginx/sites-available/tomcat >/dev/null <<'CONF'
server {
listen 80;
server_name tomcat.your-domain.example;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
CONF
sudo ln -sf /etc/nginx/sites-available/tomcat /etc/nginx/sites-enabled/tomcat
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl restart nginx
sudo certbot --nginx -d tomcat.your-domain.example \
--non-interactive --agree-tos -m you@your-domain.example --redirect
For deployments behind an Application Load Balancer, terminate TLS on the load balancer with an AWS Certificate Manager certificate and forward plain HTTP to the instance on port 8080 instead.
Step 12: Backups and Maintenance
The deployment state to back up is the Tomcat tree under /opt/tomcat: the webapps directory with your deployed applications, and the conf directory with server.xml, tomcat-users.xml, and the per application context files.
sudo tar --acls --xattrs -czf /var/backups/tomcat-$(date +%F).tgz \
-C /opt tomcat/conf tomcat/webapps
Ship the archive to an Amazon S3 bucket or another object store.
For kernel and package updates, Ubuntu's unattended-upgrades is enabled by default, so security patches apply automatically. To move to a newer Apache Tomcat patch release, download the new Stable Core tarball from https://tomcat.apache.org/, stop the service, replace the contents of /opt/tomcat while preserving your conf and webapps directories, restore the tomcat ownership, and restart the service.
Step 13: Scaling Beyond a Single Instance
For larger deployments decouple Tomcat from the single instance pattern:
- Put the Tomcat tier behind an Application Load Balancer and scale horizontally with an Auto Scaling group, terminating TLS on the load balancer
- Enable sticky sessions on the load balancer, or configure Tomcat session replication, so a user's session survives across instances
- Externalise session state to Amazon ElastiCache for Redis so the web tier can be fully stateless
- Bake your application into a custom AMI from this image, or deploy it on boot with user data, so every scaled instance is identical
The official Tomcat documentation at https://tomcat.apache.org/tomcat-11.0-doc/ covers clustering, connector tuning, and security hardening in depth.
Support
cloudimg provides 24/7/365 expert technical support for this image. Guaranteed response within 24 hours, one hour average for critical issues. Contact support@cloudimg.co.uk.
For general Apache Tomcat administration questions consult the documentation at https://tomcat.apache.org/tomcat-11.0-doc/.