Install and configure Jetty application server with SSL certificates and performance tuning

Intermediate 45 min Apr 03, 2026 33 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Deploy Eclipse Jetty application server with SSL/TLS encryption, systemd service management, and production-ready performance optimizations. Configure reverse proxy integration and security hardening for Java web applications.

Prerequisites

  • Root or sudo access
  • At least 2GB RAM
  • Java 17 or later
  • Basic understanding of Java web applications

What this solves

Eclipse Jetty is a lightweight, high-performance Java application server and servlet container ideal for deploying Java web applications, REST APIs, and microservices. This tutorial shows you how to install Jetty with SSL certificates, configure it as a systemd service with automatic startup, optimize JVM performance for production workloads, and set up a reverse proxy with Nginx for enhanced security and load distribution.

Step-by-step installation

Update system packages and install Java

Start by updating your system and installing OpenJDK 17, which provides the best performance and long-term support for Jetty.

sudo apt update && sudo apt upgrade -y
sudo apt install -y openjdk-17-jdk wget curl unzip
sudo dnf update -y
sudo dnf install -y java-17-openjdk java-17-openjdk-devel wget curl unzip

Create Jetty user and directories

Create a dedicated system user for Jetty to run securely without root privileges. This follows security best practices by isolating the application server.

sudo useradd --system --home /opt/jetty --shell /bin/false jetty
sudo mkdir -p /opt/jetty /var/log/jetty /etc/jetty
sudo chown jetty:jetty /opt/jetty /var/log/jetty

Download and install Jetty

Download the latest stable Jetty release and extract it to the installation directory. We'll use Jetty 12 which supports Jakarta EE and modern Java features.

cd /tmp
wget https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/12.0.5/jetty-home-12.0.5.tar.gz
tar -xzf jetty-home-12.0.5.tar.gz
sudo cp -r jetty-home-12.0.5/* /opt/jetty/
sudo chown -R jetty:jetty /opt/jetty

Create Jetty base directory

Set up a Jetty base directory where you'll store your configuration, webapps, and customizations. This separates your configuration from the Jetty installation.

sudo mkdir -p /var/lib/jetty
sudo chown jetty:jetty /var/lib/jetty
sudo -u jetty java -jar /opt/jetty/start.jar --create-startd --add-modules=http,https,deploy,ext,resources,server,webapp,jstl

Configure Jetty base settings

Create the basic configuration for HTTP and HTTPS connectors. This sets up Jetty to listen on standard ports with proper buffer sizes for production use.

# HTTP Connector Configuration
--module=http
jetty.http.port=8080
jetty.http.host=127.0.0.1
jetty.httpConfig.outputBufferSize=32768
jetty.httpConfig.requestHeaderSize=8192
jetty.httpConfig.responseHeaderSize=8192

Generate SSL keystore and configure HTTPS

Create a self-signed certificate for development or prepare the keystore for your production certificate. The keystore stores your SSL certificate and private key.

sudo mkdir -p /etc/jetty/ssl
sudo keytool -genkeypair -alias jetty -keyalg RSA -keysize 2048 -validity 365 \
  -dname "CN=example.com,OU=IT,O=Example Corp,L=City,S=State,C=US" \
  -keystore /etc/jetty/ssl/keystore.jks -storepass changeit -keypass changeit
sudo chown jetty:jetty /etc/jetty/ssl/keystore.jks
sudo chmod 600 /etc/jetty/ssl/keystore.jks

Configure HTTPS connector

Set up the HTTPS connector with modern security settings including TLS 1.2+ only and secure cipher suites.

# HTTPS Connector Configuration
--module=https
jetty.https.port=8443
jetty.https.host=127.0.0.1
jetty.sslContext.keyStorePath=/etc/jetty/ssl/keystore.jks
jetty.sslContext.keyStorePassword=changeit
jetty.sslContext.keyManagerPassword=changeit
jetty.sslContext.trustStorePath=/etc/jetty/ssl/keystore.jks
jetty.sslContext.trustStorePassword=changeit
jetty.sslContext.excludeProtocols=SSLv2Hello,SSLv3,TLSv1,TLSv1.1
jetty.sslContext.includeCipherSuites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

Configure JVM performance tuning

Create optimized JVM settings for production use including garbage collection tuning, memory allocation, and performance monitoring options.

# Jetty Environment Configuration
JETTY_HOME=/opt/jetty
JETTY_BASE=/var/lib/jetty
JETTY_USER=jetty
JETTY_PID=/var/run/jetty.pid
JETTY_ARGS=jetty.http.host=127.0.0.1 jetty.https.host=127.0.0.1

JVM Options for Production

JAVA_OPTIONS=" -server -Xms1g -Xmx2g -XX:NewRatio=2 -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+OptimizeStringConcat -XX:+UseCompressedOops -XX:MaxGCPauseMillis=200 -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/./urandom -Djetty.logs=/var/log/jetty "

Create systemd service file

Set up Jetty as a systemd service for automatic startup, proper logging, and service management. This ensures Jetty starts on boot and restarts if it crashes.

[Unit]
Description=Jetty Application Server
After=network.target
Wants=network.target

[Service]
Type=forking
User=jetty
Group=jetty
EnvironmentFile=/etc/jetty/jetty.conf
ExecStart=/opt/jetty/bin/jetty.sh start
ExecStop=/opt/jetty/bin/jetty.sh stop
ExecReload=/opt/jetty/bin/jetty.sh restart
PIDFile=/var/run/jetty.pid
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5

Security settings

NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes ReadWritePaths=/var/lib/jetty /var/log/jetty /var/run

Resource limits

LimitNOFILE=65536 LimitNPROC=4096 [Install] WantedBy=multi-user.target

Create Jetty startup script

Create a proper startup script that sources the configuration and starts Jetty with the correct user and environment.

#!/bin/bash

Jetty startup script

set -e

Source configuration

[ -f /etc/jetty/jetty.conf ] && . /etc/jetty/jetty.conf

Set defaults

JETTY_HOME=${JETTY_HOME:-/opt/jetty} JETTY_BASE=${JETTY_BASE:-/var/lib/jetty} JETTY_USER=${JETTY_USER:-jetty} JETTY_PID=${JETTY_PID:-/var/run/jetty.pid} case "$1" in start) echo "Starting Jetty..." cd "$JETTY_BASE" exec java $JAVA_OPTIONS -jar "$JETTY_HOME/start.jar" \ $JETTY_ARGS --daemon & echo $! > "$JETTY_PID" ;; stop) echo "Stopping Jetty..." if [ -f "$JETTY_PID" ]; then kill $(cat "$JETTY_PID") rm -f "$JETTY_PID" fi ;; restart) $0 stop sleep 2 $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac

Set proper permissions and enable service

Make the startup script executable and enable the systemd service for automatic startup on boot.

sudo chmod +x /opt/jetty/bin/jetty.sh
sudo chown -R jetty:jetty /var/lib/jetty
sudo systemctl daemon-reload
sudo systemctl enable jetty

Configure logging

Set up proper logging configuration for production monitoring and troubleshooting. This creates structured logs with rotation.

# Jetty Logging Configuration
org.eclipse.jetty.LEVEL=INFO
org.eclipse.jetty.server.LEVEL=INFO
org.eclipse.jetty.server.RequestLog.LEVEL=INFO

Console Handler

java.util.logging.ConsoleHandler.level=INFO java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

File Handler

java.util.logging.FileHandler.level=INFO java.util.logging.FileHandler.pattern=/var/log/jetty/jetty.%g.log java.util.logging.FileHandler.limit=10485760 java.util.logging.FileHandler.count=10 java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter

Start and test Jetty

Start the Jetty service and verify it's running correctly on both HTTP and HTTPS ports.

sudo systemctl start jetty
sudo systemctl status jetty

Configure reverse proxy with Nginx

Install and configure Nginx

Set up Nginx as a reverse proxy to handle SSL termination, static content serving, and load balancing. This improves security and performance.

sudo apt install -y nginx
sudo dnf install -y nginx

Configure Nginx reverse proxy

Create an Nginx virtual host that proxies requests to Jetty while handling SSL termination and adding security headers.

upstream jetty_backend {
    server 127.0.0.1:8080;
    keepalive 16;
}

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    # SSL Configuration
    ssl_certificate /etc/ssl/certs/jetty.crt;
    ssl_certificate_key /etc/ssl/private/jetty.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;

    # Security Headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Logging
    access_log /var/log/nginx/jetty-access.log;
    error_log /var/log/nginx/jetty-error.log;

    # Static content handling
    location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        try_files $uri @jetty;
    }

    # Proxy to Jetty
    location / {
        proxy_pass http://jetty_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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;
        proxy_cache_bypass $http_upgrade;
        proxy_connect_timeout 5s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        proxy_buffering on;
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
    }

    location @jetty {
        proxy_pass http://jetty_backend;
        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;
    }
}

Enable Nginx configuration and restart

Enable the Jetty site configuration and restart Nginx to apply the changes. For more advanced Nginx configuration, see our Nginx reverse proxy with SSL tutorial.

sudo ln -s /etc/nginx/sites-available/jetty /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl enable nginx

Security hardening and firewall configuration

Configure firewall rules

Set up firewall rules to allow only necessary traffic and block direct access to Jetty ports from external sources.

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Configure system resource limits

Set appropriate system resource limits for the Jetty process to prevent resource exhaustion attacks and ensure stable operation.

jetty soft nofile 65536
jetty hard nofile 65536
jetty soft nproc 4096
jetty hard nproc 4096
jetty soft memlock unlimited
jetty hard memlock unlimited

Performance tuning and optimization

Configure thread pool optimization

Optimize Jetty's thread pool settings for your expected load. This configuration handles concurrent requests efficiently without resource waste.

# Thread Pool Configuration
--module=threadpool
jetty.threadPool.minThreads=10
jetty.threadPool.maxThreads=200
jetty.threadPool.idleTimeout=60000
jetty.threadPool.reservedThreads=20

Configure JVM garbage collection monitoring

Add GC logging and monitoring options to track memory usage and optimize garbage collection performance.

# Add to existing JAVA_OPTIONS
JAVA_OPTIONS="$JAVA_OPTIONS
  -Xloggc:/var/log/jetty/gc.log
  -XX:+UseGCLogFileRotation
  -XX:NumberOfGCLogFiles=5
  -XX:GCLogFileSize=10M
  -XX:+PrintGC
  -XX:+PrintGCDetails
  -XX:+PrintGCTimeStamps
  -XX:+PrintGCApplicationStoppedTime
"

Configure system kernel optimization

Optimize kernel parameters for high-performance web serving with proper TCP settings and memory management. For more comprehensive system optimization, see our Linux system performance tuning guide.

# Network Performance Tuning
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_congestion_control = bbr

File and Process Limits

fs.file-max = 2097152 kernel.pid_max = 4194304

Memory Management

vm.swappiness = 1 vm.dirty_ratio = 15 vm.dirty_background_ratio = 5

Apply kernel optimizations and restart services

Apply the kernel parameter changes and restart Jetty with the optimized configuration.

sudo sysctl -p /etc/sysctl.d/99-jetty.conf
sudo systemctl restart jetty
sudo systemctl restart nginx

Verify your setup

Test your Jetty installation to ensure all components are working correctly with proper SSL configuration and performance settings.

# Check service status
sudo systemctl status jetty
sudo systemctl status nginx

Verify Jetty is listening on correct ports

sudo netstat -tlnp | grep java

Test HTTP to HTTPS redirect

curl -I http://example.com

Test HTTPS response

curl -k -I https://example.com

Check SSL certificate

openssl s_client -connect example.com:443 -servername example.com

Monitor JVM performance

jstat -gc $(pgrep -f jetty) 5s

Check log files

sudo tail -f /var/log/jetty/jetty.0.log sudo tail -f /var/log/nginx/jetty-access.log

Common issues

SymptomCauseFix
Jetty fails to startIncorrect Java version or missing dependenciesVerify Java 17+ with java --version, check logs in /var/log/jetty/
Port binding errorsPort already in use or permission issuesCheck with sudo netstat -tlnp | grep :8080, ensure Jetty runs as jetty user
SSL handshake failuresInvalid keystore or weak ciphersRegenerate keystore, verify cipher suites with openssl s_client
502 Bad Gateway from NginxJetty not responding or connection issuesCheck Jetty status, verify upstream configuration, check Nginx error logs
High memory usageIncorrect JVM heap settingsAdjust -Xmx value, monitor with jstat -gc, tune garbage collector
Slow response timesThread pool exhaustion or database connectionsIncrease thread pool size, optimize database queries, enable connection pooling

Next steps

Automated install script

Run this to automate the entire setup

#jetty #java #application-server #ssl #systemd #nginx #performance-tuning #reverse-proxy #security

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer