This guide provides a full Ansible playbook to deploy Apache Tomcat with a dedicated service user, runtime dependencies, extracted Tomcat files, and a managed systemd unit.
It covers Debian 10 to latest stable (Debian 12), Ubuntu LTS releases, and RHEL 9+ compatible systems.
- name: Install Apache Tomcat
hosts: apache-tomcat
become: true
vars:
tomcat_user: tomcat
tomcat_group: tomcat
tomcat_home: /opt/tomcat
tomcat_version: 11.0.18 # as of 2026-02-12; update before production rollout
tomcat_archive_url: "https://dlcdn.apache.org/tomcat/tomcat-11/v{{ tomcat_version }}/bin/apache-tomcat-{{ tomcat_version }}.tar.gz"
tomcat_archive_dest: "/tmp/apache-tomcat-{{ tomcat_version }}.tar.gz"
tomcat_install_dir: "{{ tomcat_home }}/apache-tomcat-{{ tomcat_version }}"
tomcat_service_name: tomcat
java_home_debian: /usr/lib/jvm/java-17-openjdk-amd64
java_home_redhat: /usr/lib/jvm/java-17-openjdk
tomcat_java_home: "{{ java_home_debian if ansible_os_family == 'Debian' else java_home_redhat }}"
tomcat_http_port: 8080
tasks:
- name: Install runtime dependencies on Debian/Ubuntu
apt:
name:
- openjdk-17-jdk
- curl
- tar
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Install runtime dependencies on RHEL family
dnf:
name:
- java-17-openjdk-devel
- curl
- tar
state: present
when: ansible_os_family == "RedHat"
- name: Create Tomcat group
group:
name: "{{ tomcat_group }}"
state: present
- name: Create Tomcat user
user:
name: "{{ tomcat_user }}"
group: "{{ tomcat_group }}"
home: "{{ tomcat_home }}"
shell: /usr/sbin/nologin
create_home: false
system: true
- name: Create Tomcat home directory
file:
path: "{{ tomcat_home }}"
state: directory
owner: "{{ tomcat_user }}"
group: "{{ tomcat_group }}"
mode: "0755"
- name: Download Tomcat archive
get_url:
url: "{{ tomcat_archive_url }}"
dest: "{{ tomcat_archive_dest }}"
mode: "0644"
- name: Extract Tomcat archive
unarchive:
src: "{{ tomcat_archive_dest }}"
dest: "{{ tomcat_home }}"
remote_src: true
creates: "{{ tomcat_install_dir }}/bin/catalina.sh"
- name: Symlink current Tomcat version
file:
src: "{{ tomcat_install_dir }}"
dest: "{{ tomcat_home }}/current"
state: link
- name: Fix Tomcat ownership
file:
path: "{{ tomcat_home }}"
state: directory
owner: "{{ tomcat_user }}"
group: "{{ tomcat_group }}"
recurse: true
- name: Configure server.xml HTTP connector port
replace:
path: "{{ tomcat_home }}/current/conf/server.xml"
regexp: 'port="8080"'
replace: 'port="{{ tomcat_http_port }}"'
- name: Create Tomcat systemd unit
copy:
dest: "/etc/systemd/system/{{ tomcat_service_name }}.service"
mode: "0644"
content: |
[Unit]
Description=Apache Tomcat
After=network.target
[Service]
Type=forking
User={{ tomcat_user }}
Group={{ tomcat_group }}
Environment=JAVA_HOME={{ tomcat_java_home }}
Environment=CATALINA_PID={{ tomcat_home }}/current/temp/tomcat.pid
Environment=CATALINA_HOME={{ tomcat_home }}/current
Environment=CATALINA_BASE={{ tomcat_home }}/current
ExecStart={{ tomcat_home }}/current/bin/startup.sh
ExecStop={{ tomcat_home }}/current/bin/shutdown.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target
- name: Reload systemd
systemd:
daemon_reload: true
- name: Enable and start application service
service:
name: "{{ tomcat_service_name }}"
state: started
enabled: true
tomcat_version to the latest stable release before applying in production.Any questions?
Feel free to contact us. Find all contact information on our contact page.