Which Payara
Payara 7 implements Jakarta EE 11. Payara 6 implements Jakarta EE 10 and runs on Java 11 and 17 as well. If your application uses javax.* imports it needs Payara 5, which is end-of-life: migrate to jakarta.* instead. This guide uses Payara 7 on Java 21 and works the same for Payara 6.
1. Java, user and download
sudo apt update
sudo apt install -y openjdk-21-jdk-headless curl unzip
sudo useradd --system --home-dir /opt/payara --shell /usr/sbin/nologin payara
PAYARA_VERSION=7.XXXX.X # check Maven Central for the current number
cd /tmp
curl -fSLO https://repo1.maven.org/maven2/fish/payara/distributions/payara/${PAYARA_VERSION}/payara-${PAYARA_VERSION}.zip
curl -fsSL https://repo1.maven.org/maven2/fish/payara/distributions/payara/${PAYARA_VERSION}/payara-${PAYARA_VERSION}.zip.sha1; echo
sha1sum payara-${PAYARA_VERSION}.zip
The two checksums must match. To see the versions available, open https://repo1.maven.org/maven2/fish/payara/distributions/payara/maven-metadata.xml.
2. Unpack
sudo unzip -q payara-${PAYARA_VERSION}.zip -d /opt
sudo mv /opt/payara7 /opt/payara-${PAYARA_VERSION} # folder name is payara6 for Payara 6
sudo ln -sfn /opt/payara-${PAYARA_VERSION} /opt/payara
sudo chown -R payara:payara /opt/payara-${PAYARA_VERSION}
3. Set the heap and the listener address
Payara ships with fixed memory options in domain1/config/domain.xml. Look at what is there, then change the maximum heap with asadmin instead of editing XML by hand:
sudo -u payara /opt/payara/bin/asadmin start-domain domain1
sudo -u payara /opt/payara/bin/asadmin list-jvm-options | grep -i xm
sudo -u payara /opt/payara/bin/asadmin delete-jvm-options '-Xmx2048m'
sudo -u payara /opt/payara/bin/asadmin create-jvm-options '-Xmx2g'
sudo -u payara /opt/payara/bin/asadmin create-jvm-options '-XX\:+ExitOnOutOfMemoryError'
sudo -u payara /opt/payara/bin/asadmin stop-domain domain1
The default -Xmx value differs between releases, so use exactly what list-jvm-options printed in the delete command. Colons inside option names are escaped with a backslash.
Make the HTTP listener local only, so Nginx is the only way in:
sudo -u payara /opt/payara/bin/asadmin start-domain domain1
sudo -u payara /opt/payara/bin/asadmin set configs.config.server-config.network-config.network-listeners.network-listener.http-listener-1.address=127.0.0.1
sudo -u payara /opt/payara/bin/asadmin set configs.config.server-config.network-config.network-listeners.network-listener.admin-listener.address=127.0.0.1
sudo -u payara /opt/payara/bin/asadmin stop-domain domain1
4. systemd service
sudo tee /etc/systemd/system/payara.service >/dev/null <<'EOF'
[Unit]
Description=Payara Server
After=network.target
[Service]
User=payara
Group=payara
Environment=JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
ExecStart=/opt/payara/bin/asadmin start-domain --verbose domain1
ExecStop=/opt/payara/bin/asadmin stop-domain domain1
SuccessExitStatus=143
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now payara
sudo journalctl -u payara -n 30 --no-pager
The --verbose flag keeps the process in the foreground, which is what systemd expects.
5. Deploy the application
sudo -u payara /opt/payara/bin/asadmin deploy --force=true --contextroot / --name app /path/to/myapp.war
sudo -u payara /opt/payara/bin/asadmin list-applications
Use the same command for every new version. Then put Nginx in front, proxying to 127.0.0.1:8080, as in this guide.
Notes
- The admin console listens on port 4848. Keep it on localhost and reach it through an SSH tunnel. Set an admin password with
asadmin change-admin-password, and enable secure admin only if you must access it remotely. - Payara needs more memory than Tomcat. Do not run it on a 2 GB server for production.
Our Payara hosting plans include this installation. Start from €15.30 per month.
Last updated October 29, 2026.