Guides 11792 Published by

This guide walks the reader through deploying a Java web application by running an official Tomcat image inside a Podman container on Windows, highlighting that Podman's daemon‑less architecture keeps things lightweight. It begins with installing Podman via the installer or Chocolatey, then pulls a specific Tomcat tag to avoid registry hiccups, and demonstrates how to expose port 8080 while mounting a local WAR directory so updates appear instantly. The tutorial also covers monitoring startup logs for class‑definition errors, stopping and removing containers cleanly, and troubleshooting common issues like port collisions, Java version mismatches, or SELinux permissions on WSL 2. Finally it offers a brief recipe for customizing JVM options with a wrapper script and building a small, tailored image, encouraging readers to experiment while keeping the host system free of root privileges.



How to Spin Up an Apache Tomcat Container with Podman on Windows

Running a Java web app is easier when you let a container do the heavy lifting.

With Podman you get a Docker‑compatible workflow, no daemon lurking in the background and, best of all, rootless mode that won’t scare your admin friend.

Steps to get Tomcat up and running
Install Podman
  • Windows: Grab the latest installer from the official site or use Chocolatey:

choco install podman.

The installer configures WSL‑2, which is where Podman lives on Windows.

  • Linux: sudo apt-get install podman (Debian/Ubuntu) or the equivalent for your distro.

Why this matters? Without a proper backend you’ll see “cannot connect to socket” errors before your container even starts.

Pull the official Tomcat image
podman pull tomcat:9-jdk11-openjdk-slim

I once pulled tomcat:latest and got a 404 because the registry moved it to tomcat:10. Explicit tags avoid that headache.

Map ports and volumes
podman run -d \
  --name tomcat-demo \
  -p 8080:8080 \
  -v C:\myapps\war:/usr/local/tomcat/webapps:Z \
  tomcat:9-jdk11-openjdk-slim
  • -p exposes the container’s 8080 to your host, so you can hit http://localhost:8080.
  • The volume mapping lets you drop WAR files into a local folder and have them auto‑deployed.

The :Z flag is WSL‑2’s way of setting SELinux context; without it the container will complain about “permission denied” when trying to read your WAR.

Check the logs
podman logs -f tomcat-demo

Watch for the “Server startup in X ms” line. If you see java.lang.NoClassDefFoundError, you’re probably missing a library or the image doesn’t include JDK 8, which some older WARs expect.

Shut down when done
podman stop tomcat-demo
podman rm tomcat-demo

You can keep the container alive as long as you need; Podman won’t eat up resources in the background like Docker’s daemon does.

Common pitfalls & how to fix them
  • Port collision

Scenario: “I get an error that port 8080 is already in use after a quick restart.”

Fix: Run netstat -ano | findstr :8080 on Windows or ss -ltnp | grep :8080 on Linux, kill the process, or choose another host port (e.g., -p 9090:8080).

  • Missing Java version

Scenario: “My WAR boots but throws a ‘java.lang.UnsupportedClassVersionError’.”

Fix: Pick an image that matches your app’s JDK target, like tomcat:9-jdk8-openjdk-slim.

  • SELinux/AppArmor hiccups on WSL‑2

Scenario: “Podman refuses to mount my volume and says ‘permission denied’.”

Fix: Add the :Z suffix or adjust your distro’s AppArmor profile. On Windows, also ensure the folder isn’t flagged as read‑only.

Tweaking Tomcat inside a container

If you need to bump memory limits or tweak JVM flags, create a tiny wrapper script:

# start-tomcat.sh
#!/bin/bash
export CATALINA_OPTS="-Xms512m -Xmx1024m"
exec "$@"

Then build your own image:

FROM tomcat:9-jdk11-openjdk-slim
COPY start-tomcat.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/start-tomcat.sh
ENTRYPOINT ["start-tomcat.sh", "catalina.sh"]

Build with podman build -t mytomcat . and run as usual. This keeps the container lean while giving you control over JVM tuning.

Final thoughts

Using Podman for Tomcat is a no‑frills way to spin up a Java web server on any machine that supports containers. It eliminates the daemon overhead, works great with WSL‑2 on Windows, and keeps your system clean from root privileges. Give it a try; if you hit a snag or have a neat trick to share, drop me a line.