Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Keep the Java application on port 8080 and put Nginx on port 80 as the public entry point. Nginx can send one hostname or URL path to the Java process and another to your blog, while Spring Boot is configured to understand the original host, protocol, and client address.

What the finished setup looks like

Only the reverse proxy should normally be exposed to the internet. The request flow is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Browser
   |
   | HTTP :80
   v
Nginx (reverse proxy)
   |-- app.example.com  -> 127.0.0.1:8080 (Java/Spring Boot)
   |-- blog.example.com -> blog service or static files

The Java process does not need to listen on port 80. It listens on 8080, where it avoids the normal Linux restriction on ports below 1024. Nginx, which is designed to accept public connections and route them, owns port 80.

The blog can share that same port because Nginx chooses a destination from the request hostname (server_name) or, if you deliberately design it that way, from the URL path.

Decide how requests will be split

Routing method Example request When it fits Main caveat
Separate hostnames app.example.com for Java and blog.example.com for the blog Best isolation and the least application-specific configuration Each hostname needs DNS pointing to the server
One hostname, different paths example.com/app/ for Java and example.com/blog/ for the blog Useful when you have one public domain The Java and blog applications must tolerate a URL prefix; redirects and asset URLs often need adjustment
One hostname, one site at the root example.com serves the blog and a path such as /api/ reaches Java Good when the blog is the primary website and Java is an API or secondary service Path ordering and trailing-slash behavior matter in Nginx

Use separate hostnames unless you have a specific reason to place both applications under one path. The examples below use app.example.com and blog.example.com; replace them with names in your own DNS zone.

Prepare the server and check for conflicts

Confirm that port 80 is free

Before starting Nginx, check whether another web server or service already owns the port:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo ss -tlnp | grep :80

If the command returns a listener, stop or reconfigure that service before asking Nginx to bind to port 80. A bind error is not caused by Spring Boot; it means two processes are competing for the same address.

Keep 8080 private

On a single Linux host, bind the Java service to loopback when that is compatible with your deployment. Loopback means the process accepts connections from the local machine, including Nginx, but not direct connections from the public network. If the application runs in a container or on a separate host, use the appropriate internal interface instead; blindly choosing 127.0.0.1 inside a container can make the service unreachable from the proxy.

Allow inbound port 80 (and 443 if you later add TLS) in the host firewall. Do not open 8080 publicly unless a separate, deliberate use case requires it.

Configure the Java application for port 8080

Spring Boot properties file

Spring Boot’s standalone embedded server defaults to port 8080. You can make that choice explicit in src/main/resources/application.properties:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
server.port=8080
server.address=127.0.0.1
server.forward-headers-strategy=NATIVE

server.address is optional and is appropriate for a Java process installed directly on the same machine as Nginx. Omit it, or choose the container’s reachable interface, when your topology requires external or inter-container access.

YAML equivalent

server:
  port: 8080
  address: 127.0.0.1
  forward-headers-strategy: NATIVE

Override the port without rebuilding

Spring Boot’s relaxed binding accepts the environment variable SERVER_PORT:

SERVER_PORT=8080 java -jar app.jar

You can also pass a command-line property at launch:

java -jar app.jar --server.port=8080

Command-line and environment values are useful for deployments that use the same artifact in several environments. Check the effective configuration in your service manager so a later environment setting does not silently replace 8080.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make forwarded headers work correctly

After Nginx proxies a request, the Java process sees the proxy’s connection unless it is told to process forwarded headers. Without that handling, generated redirects may use the wrong scheme, secure-cookie decisions can be wrong, and logs may show the proxy address instead of the original client.

Value Behavior Typical use
NATIVE Uses the servlet container’s own forwarded-header support Simple servlet deployments where the container support is sufficient
FRAMEWORK Uses Spring’s ForwardedHeaderFilter for servlet applications or ForwardedHeaderTransformer for reactive applications When you want Spring Framework to apply the forwarded-header handling
NONE Ignores X-Forwarded-* headers Only when no trusted proxy is in front of the application

Spring Boot uses NATIVE by default on a supported cloud platform and NONE elsewhere. A self-managed Nginx server therefore should set NATIVE or FRAMEWORK explicitly. Choose one strategy, not both, and verify the behavior with a request that passes through Nginx.

Forwarded headers are security-sensitive. A client can send an X-Forwarded-For or X-Forwarded-Proto header directly unless the edge proxy overwrites or removes it. Treat the Nginx configuration as the trust boundary.

Configure Nginx for the Java hostname

Install and validate Nginx

Install the Nginx package using your operating system’s package manager, then validate the configuration before every reload:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo nginx -t
sudo systemctl reload nginx

The exact package command differs by distribution, so use the repository supported by your operating system rather than copying an old distribution-specific command.

Proxy the Java app

Create a server block that listens on port 80 and forwards requests for the Java hostname to loopback port 8080:

upstream java_app {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    listen [::]:80;
    server_name app.example.com;

    location / {
        proxy_pass http://java_app;
        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_read_timeout 60s;
    }
}

The explicit X-Forwarded-For $remote_addr line prevents an outside client from supplying an arbitrary chain of addresses. If your server is behind another trusted proxy or load balancer, build a documented trust chain instead of blindly using an incoming header.

Host preserves the requested hostname, and X-Forwarded-Proto tells Spring whether the client used HTTP or HTTPS at the edge. Keep the timeout appropriate for your endpoints; a long-running export may need a separate location with a larger value.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Put the blog on the same public port

Blog served as static files

If the blog is a directory of generated HTML, give it its own hostname and document root:

server {
    listen 80;
    listen [::]:80;
    server_name blog.example.com;

    root /srv/blog/public;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Ensure the Nginx worker can read the files and that the directory contains the generated index.html. This server block and the Java block can both listen on port 80 because their server_name values differ.

Blog running as its own application

If the blog has an HTTP server of its own, proxy it to its private listening port. The port below is an example; use the port configured by your blog software:

upstream blog_app {
    server 127.0.0.1:3000;
}

server {
    listen 80;
    listen [::]:80;
    server_name blog.example.com;

    location / {
        proxy_pass http://blog_app;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Do not expose the blog’s private port in DNS or the firewall merely because Nginx proxies to it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Path-based alternative

A single hostname can route a path to Java and another path to the blog:

server {
    listen 80;
    server_name example.com;

    location /app/ {
        proxy_pass http://127.0.0.1:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /blog/ {
        proxy_pass http://127.0.0.1:3000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

The trailing slash in each proxy_pass changes how Nginx replaces the matched prefix. Test both /app/ and links generated by the Java application. Many frameworks need an explicit base-path setting to generate assets and redirects correctly. Hostname routing avoids that extra application work.

Run the Java process as a service

For a host installation, use a service manager instead of an interactive shell. A minimal systemd unit is:

[Unit]
Description=Java application
After=network.target

[Service]
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/java -jar /opt/myapp/app.jar --server.port=8080
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

After saving the unit, reload systemd, enable the service, and inspect its logs:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
sudo systemctl status myapp
sudo journalctl -u myapp -e

Use a non-root service account and grant it read access only to the application files and directories it needs. Nginx still requires the ability to bind port 80, while the JVM remains on 8080.

Test each layer in order

  1. Confirm listeners: sudo ss -tlnp | grep -E ':(80|8080)b'. You should see Nginx on 80 and the Java process on 8080.
  2. Test Java without Nginx: curl -i http://127.0.0.1:8080/. A response proves the application is running and reachable locally.
  3. Validate Nginx syntax: sudo nginx -t, then reload it.
  4. Test hostname routing locally: curl -i -H 'Host: app.example.com' http://127.0.0.1/. This checks the selected server block without depending on public DNS.
  5. Test the blog hostname or path with the same technique and confirm that static assets, redirects, and cookies use the intended URL.
  6. From an external network, request both public names and verify that port 8080 is not reachable from the internet.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common failures

Nginx returns 502 Bad Gateway

The proxy cannot connect to its upstream. Check that Java is running, that it is listening on the address and port in proxy_pass, and that a local firewall or SELinux policy is not blocking the connection. Read the Nginx error log and the Java service journal together; a failed application startup often appears only in the latter.

The wrong site appears

Verify the browser’s hostname, DNS record, and exact server_name. A request made by IP address may select Nginx’s default server rather than either named block.

Redirects point to HTTP or the wrong host

Check proxy_set_header Host, X-Forwarded-Proto, and Spring’s server.forward-headers-strategy. If TLS terminates at another proxy before Nginx, ensure that proxy passes a trusted scheme and that Nginx does not accept arbitrary client-supplied forwarded values.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Client IPs are all the same

The application may be logging Nginx’s address because forwarded-header handling is disabled, or Nginx may be passing an unsanitized header chain. Set the Spring strategy explicitly and overwrite the headers at the trusted edge.

The Java app works on 8080 but not through a path

Path-based proxying can alter the URI prefix. Inspect the exact proxy_pass trailing slash, then configure the framework’s context path or public base URL if required. Move the app to its own hostname when it assumes it is mounted at /.

Nginx versus other proxy choices

Proxy location Advantages Trade-offs
Nginx on the server Direct control of host and path routing, headers, logs, and local upstreams You maintain upgrades, firewall rules, certificates, and configuration
Apache HTTP Server Equivalent reverse-proxy architecture with modules and familiar configuration for Apache users Module and directive choices differ; do not mix configuration syntax
Managed load balancer or ingress Can terminate TLS and route traffic without exposing the host directly Header trust, health checks, and private-network connectivity must be configured in that service

Whichever proxy you choose, the invariants are the same: Java listens on 8080, the edge owns port 80, routing is deterministic, and forwarded headers come only from a trusted proxy.

Adding HTTPS later

Port 80 is commonly retained for an HTTP-to-HTTPS redirect after you obtain a certificate. TLS can terminate at Nginx or at an upstream load balancer. If Nginx terminates TLS, keep forwarding X-Forwarded-Proto https to Spring so secure redirects and cookies remain correct. Do not change the Java listener merely because the public site moves to 443; the private upstream can remain 8080.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Operational checklist

  • Spring Boot has server.port=8080 (or an equivalent environment or command-line setting).
  • Nginx is the only public listener on port 80.
  • The Java upstream points to the correct address and port.
  • The blog uses a separate hostname or a deliberately tested path.
  • server.forward-headers-strategy is NATIVE or FRAMEWORK when Nginx is trusted.
  • Nginx overwrites forwarded headers rather than trusting arbitrary client values.
  • Port 8080 is restricted to the proxy or internal network.
  • Nginx configuration passes nginx -t before reloads.
  • Service logs, proxy logs, and direct upstream tests are available for diagnosis.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.