Blog · WebJi® India

How to Deploy a WAR File in Tomcat

Quick answer: Copy the WAR into Tomcat's webapps directory. With autoDeploy on, Tomcat unpacks it and serves a context named after the file, so app.war answers at /app and ROOT.war answers at /. Confirm the startup line in logs/catalina.out, then open that context on port 8080.
✓ In business since 2005✓ INR + GST billing✓ 24/7 Email Support — avg reply < 60 min
Modern data center corridor in India with rows of server racks under cool blue-white lighting — how to deploy war file in tomcat

What a WAR File Is

A WAR file is a zip of one Java web application: classes, pages, and WEB-INF. Tomcat calls that application a context and serves it as soon as the archive is deployed.

The file name is the context path. app.war is served at /app. ROOT.war, spelled in capitals, is served at /. A hash in the name adds a path segment, so shop#v2.war is served at /shop/v2.

The archive has to match the server. Tomcat 9 loads javax.servlet, which is what Spring Boot 2.x and older servlet apps expect. Tomcat 10.1 and Tomcat 11 load jakarta.servlet. A javax WAR on Tomcat 10 fails before the first page renders.

  • One WAR is one web application.
  • The file name sets the URL path. A setting inside the zip does not.
  • ROOT.war is the only name that occupies the bare host.
  • javax WARs stay on Tomcat 9. jakarta WARs need Tomcat 10.1 or 11.

Which Tomcat method deploys the WAR

Three methods land on the same context URL. Pick by how the file reaches the server, not by a different Tomcat feature.

MethodUse it whenYou needIt worked when
Copy into webappsYou have a shell on the serverautoDeploy on, or a restartcatalina.out names the archive and the context URL loads
Manager HTMLSomeone uploads a build in a browserA user with manager-guiThe application list shows the path as running
Manager text APIA build server deploysA user with manager-scriptThe text call returns OK and the context URL loads

An IDE deploy talks to a Tomcat on your laptop. Use it to test. Use one of the three rows above when the WAR has to run on the VPS.

Option 1: Copy the WAR to webapps (Auto-Deploy)

Copy the WAR into the Host appBase. The default is $CATALINA_BASE/webapps: /opt/tomcat/webapps on a tarball install, and /var/lib/tomcat10/webapps on the Ubuntu tomcat10 package.

With autoDeploy left on, Tomcat publishes a new file without a reboot. If autoDeploy is off, restart the service. deployOnStartup, which defaults to on, then publishes whatever is sitting in webapps.

  1. Build the WAR on a JDK that matches the target Tomcat line, then copy it with scp as the tomcat user, not as root.
  2. Name it for the URL you want: app.war for /app, or ROOT.war for the host root. Remove a leftover exploded folder of the same name if one is still there.
  3. Watch logs/catalina.out for a line about that archive. With unpackWARs at its default, a directory appears beside the WAR.
  4. Open http://the-server:8080/app, or https://your-domain/app once a proxy is in front. A Tomcat 404 means the context never started. Your own app's error means it did.
  5. Replace the WAR to ship a new build. Tomcat picks up a newer archive. Delete the WAR and the exploded directory, or undeploy in Manager, when the context should go away.
Modern data center corridor in India with rows of server racks under cool blue-white lighting — how to deploy war file in tomcat

Do not drop the file in a PHP or static docroot. Tomcat only auto-deploys from appBase.

Option 2: Deploy via Tomcat Manager UI

Manager deploys a WAR while Tomcat is already running. Open http://the-server:8080/manager/html and sign in as a user whose role is manager-gui. Add that user in conf/tomcat-users.xml.

manager-script is a different role. It authenticates /manager/text, which scripts call. It does not sign you into the HTML page.

On the HTML page, choose the WAR from your computer and deploy it. The check is the new row: state running, path matching the file name. Undeploy on that row removes the context.

A correct password can still return 403. The stock Manager app allows only localhost until you edit its RemoteAddrValve. Add your address, or tunnel port 8080 over SSH. Do not open Manager to the whole internet.

  • manager-gui is the browser. manager-script is the text API.
  • 403 with a valid user is usually the address valve, not the password.
  • Undeploy from this list when a context must be removed cleanly.

Deploy a Spring Boot WAR on external Tomcat

A Spring Boot app can be a WAR on this same Tomcat. Three build settings matter. Set packaging to war. Mark spring-boot-starter-tomcat as provided, so the external server supplies those classes. Extend SpringBootServletInitializer from the application class so Tomcat can start the context.

The WAR is written to the build output, often target/. Deploy that file with the copy or with Manager. Do not also run java -jar for the same app on port 8080, or the port is already taken.

Spring Boot 2.x stays on Tomcat 9. Spring Boot 3.x needs Java 17 and a jakarta server, so use Tomcat 10.1 or 11. An executable jar brings its own server. That is not a WAR deploy.

Installing Tomcat on a Linux VPS First

The steps above assume Tomcat is already running. On Ubuntu this is the tarball path. The JDK itself is covered in how to install Java on Ubuntu. A Mac install uses the same webapps copy. Only the folder you extract into changes.

  1. Install a JDK that matches the Tomcat line. OpenJDK 17 runs Tomcat 10.1 and Tomcat 11. Tomcat 9 also runs on Java 8 or 11.
  2. Create a system user with adduser --system --group tomcat. Do not run the service as root.
  3. Download the core tarball from tomcat.apache.org, extract it to /opt/tomcat, and give that tree to the tomcat user.
  4. Add a systemd unit whose start command is /opt/tomcat/bin/catalina.sh run, with User=tomcat, then systemctl enable --now tomcat.
  5. Allow port 8080 from your own IP and open http://the-server:8080. The welcome page means the container is up. Your WAR is the next step.

An apt install of tomcat10 uses /var/lib/tomcat10/webapps instead of /opt/tomcat/webapps. The deploy steps do not change. A VPS is the machine this runs on. Shared hosting has no system JDK and no service you can restart.

If you would rather not write the unit file, Java and Tomcat hosting is this layout on a VPS with root SSH. Sizing is quoted by email before you pay. Moving an existing app is free only after terms and approval.

Changing Ports and Running Behind 80/443

Tomcat listens on 8080 because the HTTP Connector in conf/server.xml says so. The shutdown port in that file is 8005. The Connector's redirect port is 8443. Setting the Connector to 80 means the process must bind a privileged port, which pushes you to run as root. Do not do that.

Put Nginx or Apache on 443 and proxy to 127.0.0.1:8080. After the hostname answers, close 8080 on the public firewall. A timeout on the hostname, while :8080 still loads, is a closed 443 or a proxy pointed at the wrong port. It is not a bad WAR.

  • 8080 is the default HTTP port. 8005 is shutdown. 8443 is only the redirect port.
  • The public site should be 443 on the proxy. Tomcat stays on localhost.
  • Change server.xml only when 8080 is already taken, then point the proxy at the new port.

Memory Tuning for Java Apps

Set the heap in /opt/tomcat/bin/setenv.sh, which catalina.sh reads on start. On a 2 GB VPS, CATALINA_OPTS with -Xms1g -Xmx1g uses about half the RAM and leaves room for the OS and metaspace. Equal Xms and Xmx avoids a resize under traffic.

A systemd unit that sets its own environment never sees a flag you exported in .bashrc. If -Xmx is missing from the process, put the flags in the unit and restart. Check with ps. If the process dies just after deploy, the heap is larger than the VPS and the kernel is stopping it.

WAR Deploy Failed: Common Fixes

Read logs/catalina.out first. The line you want names your archive and says the context started. Anything else maps to one of these:

  • 404 at the right host: the path is the file name. app.war is /app, not /. ROOT.war is the bare host.
  • A javax.servlet error on Tomcat 10 or 11: the WAR is the wrong namespace. Move it to Tomcat 9, or rebuild it for jakarta.
  • Address already in use: another process holds 8080. Stop it, or change the Connector and the proxy together.
  • The WAR sits in webapps and nothing happens: autoDeploy is off, the tomcat user cannot read the file, or the copy is outside appBase.
  • Manager returns 403: the user lacks manager-gui, or the RemoteAddrValve still allows only 127.0.0.1.
  • The old app is still what you see: the exploded directory is newer than the WAR, or a second copy is deployed under another name.

Change one thing, wait for autoDeploy or restart, and read the log again. If the VPS is a WebJi® server and the unit will not stay up, email support@webji.services. That mailbox is staffed 24/7 in Hindi and English. The office phone is not a support line.

Frequently Asked Questions

How do I deploy a WAR file in Tomcat?

Copy the WAR into the webapps directory. With autoDeploy on, Tomcat serves app.war at /app and ROOT.war at /. Check logs/catalina.out for the deploy line, then open that path on port 8080.

Where do WAR files go in Tomcat?

They go in the Host appBase. That is $CATALINA_BASE/webapps, usually /opt/tomcat/webapps on a tarball install or /var/lib/tomcat10/webapps on the Ubuntu tomcat10 package.

How do I access Tomcat Manager?

Open http://the-server:8080/manager/html as a user with the manager-gui role in conf/tomcat-users.xml. A 403 usually means the Manager RemoteAddrValve still allows only localhost.

What port does Tomcat use by default?

The HTTP Connector in conf/server.xml uses port 8080. The shutdown port is 8005. Serve public traffic on 443 with a reverse proxy, and leave Tomcat on 8080.

How do I increase Tomcat memory on a VPS?

Put -Xms and -Xmx in CATALINA_OPTS inside bin/setenv.sh. On a 2 GB VPS, 1g for both is about half the RAM. Restart the service and confirm -Xmx on the java process line.

Why is my WAR not deploying?

Check catalina.out. Typical causes are a javax WAR on Tomcat 10, a file the tomcat user cannot read, autoDeploy turned off, or port 8080 already in use.

Need help with this?

WebJi® support does it for you — free. Talk to our Jaipur team →