How to Configure Apache to Use a Different Port

How to configure Apache to use a different port

Apache listens on port 80 and 443 by default, but I’ve had plenty of good reasons to run it somewhere else: multiple sites on distinct ports on the same box, avoiding a conflict with another service, exposing a staging environment on a non-standard port, or sitting Apache behind a reverse proxy that owns the standard ports itself.

Here’s how I change Apache’s listening port, plus the firewall and SELinux steps that are easy to forget.

Why I Change Apache’s Port

  • Running multiple independent Apache instances or virtual hosts distinguished by port rather than domain.
  • Avoiding conflicts when another service already occupies 80/443.
  • Restricting public exposure — Apache on a non-standard, internal-only port, with a separate reverse proxy handling the public-facing standard ports.
  • Development and staging environments where I’ve got multiple projects running at once on one machine.

Prerequisites

  • Apache installed and running
  • Root or sudo access
  • Awareness of firewall rules and SELinux status (RHEL-based systems), both of which affect this change

Step 1: Update the Listen Directive

The Listen directive tells Apache which port(s) to bind to, independent of any specific virtual host.

Debian/Ubuntu: I edit /etc/apache2/ports.conf

RHEL/CentOS: I edit /etc/httpd/conf/httpd.conf

Listen 8080

To keep 80 and add 8080 simultaneously:

Listen 80
Listen 8080

To bind a port to a specific IP only:

Listen 192.168.1.10:8080

Step 2: Update the Virtual Host to Match

Every <VirtualHost> block has to specify the exact IP:port combination it should respond to, matching a Listen directive:

<VirtualHost *:8080>
    ServerName example.com
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

If there’s a Listen directive but no matching <VirtualHost *:port> block, Apache accepts connections on that port but serves the wrong site — or the default one.

Step 3: Test and Restart

sudo apachectl configtest
sudo systemctl restart apache2

A restart, not just a reload, is required for Listen changes to actually take effect, since it involves binding to a new socket.

Step 4: Open the New Port in the Firewall

I’ve got a full post on this; the short version:

# firewalld
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

# ufw
sudo ufw allow 8080/tcp

Step 5: SELinux Considerations (RHEL/CentOS/Fedora)

With SELinux enforcing, Apache can only bind to a predefined set of ports by default (80, 443, 8080, 8443, a few others). Binding to something outside that list fails even with correct firewall rules — I’ve been caught by this more than once.

I check currently permitted ports:

sudo semanage port -l | grep http_port_t

If my chosen port isn’t listed, I add it:

sudo semanage port -a -t http_port_t -p tcp 9090

If the port was already assigned to a different SELinux type, I use -m (modify) instead of -a (add).

Step 6: Verify

sudo ss -tulnp | grep apache2
curl -I http://localhost:8080/

From another machine, once firewall rules are confirmed:

curl -I http://your-server-ip:8080/

Running Apache on Ports Below 1024 as a Non-Root User

Ports under 1024 are “privileged” on Linux and normally need root to bind. Apache’s master process typically starts as root specifically to bind 80/443, then drops privileges to a less-privileged worker user (www-data/apache) for handling requests — that’s already handled automatically by the standard startup scripts, so I don’t need to do anything special for standard ports.

If I’m deliberately running Apache entirely as a non-root user (like in a container) and need it to bind below 1024, I use setcap on the httpd binary, or more often, I just use a port above 1024 and put a reverse proxy in front that forwards from port 80.

Real-World Use Cases

  • Multiple projects on one dev server: Listen 8080 for Project A, Listen 8081 for Project B, each with its own <VirtualHost> block.
  • Apache behind Nginx or a load balancer: Apache listens on an internal-only port while Nginx handles 80/443 and proxies requests through.
  • Staging environments: exposing a staging instance on a distinct port to keep it separate from production without needing a whole separate server.
  • Container deployments: mapping a container’s internal Apache port to a different host port via Docker’s port mapping.

Mistakes I’ve Made

  • Changing Listen but forgetting to update the matching <VirtualHost> block’s port, so Apache accepts connections but serves the wrong content.
  • Forgetting to open the new port in the firewall, hitting “connection refused” from external clients even though curl localhost:PORT worked fine locally.
  • On RHEL-based systems, forgetting the SELinux port context, which stopped Apache from starting entirely with a permission-denied error buried in the journal.
  • Assuming systemctl reload was enough — a full restart is needed for Listen changes.
  • Port conflicts with another already-running service — I always check first: sudo ss -tulnp | grep 8080

Security Best Practices

  • I don’t rely on a non-standard port as a security measure — port scanners find open ports in seconds regardless of the number.
  • If I’m exposing Apache on a non-standard port for internal-only access, I still restrict it via firewall rules to trusted IP ranges rather than leaving it open to the whole internet.
  • When Apache sits behind a reverse proxy on an internal port, I double-check that internal port isn’t also accidentally exposed externally by a misconfigured firewall or cloud security group.
  • I keep TLS configuration consistent regardless of port — if a service is sensitive enough to need HTTPS on 443, I don’t downgrade to plain HTTP just because it’s on an alternate port.

Performance Considerations

  • Changing the port itself has no meaningful performance impact in my experience; performance comes down to MPM configuration and resource limits, not the port number.
  • If Apache’s behind a reverse proxy on a non-standard port, I make sure mod_remoteip is configured (see my log format post) so Apache logs and application logic see the real client IP rather than the proxy’s address.
  • For containerized deployments, I minimize the number of exposed/mapped ports to keep the attack surface and firewall management simpler.

Troubleshooting

Apache fails to start after changing Listen port I check the systemd journal for the specific error:

sudo journalctl -u apache2 -n 50

Common causes: the port’s already in use by another process, or (on RHEL-based systems) SELinux is blocking the bind.

curl works locally but not from another machine Almost always a firewall issue — I confirm the new port is explicitly allowed both on the host firewall and any cloud provider security group.

Wrong site/content served on the new port I confirm a <VirtualHost *:PORT> block exists matching the new port exactly; Apache falls back to the first matching virtual host if there’s no exact match.

FAQs

Can Apache listen on multiple ports at once? Yes — multiple Listen directives and a matching <VirtualHost> block for each port/IP combination I want to serve.

Does changing the port affect existing URLs or bookmarks? Yes — visitors need the new port explicit in the URL (like http://example.com:8080/) unless a reverse proxy or redirect maps the standard port to the new one transparently.

Is it safe to run a production site on a non-standard port permanently? Technically yes, but it adds friction for users who expect standard ports and complicates certificate/firewall management. I mostly use it internally, or behind a reverse proxy that presents the standard ports externally.

Summary and Key Takeaways

  • Changing Apache’s port means updating both the Listen directive and the matching <VirtualHost> block’s port.
  • A full restart, not a reload, is needed for Listen changes to take effect.
  • Firewall rules and, on RHEL-based systems, SELinux port contexts both need updating or clients won’t connect despite correct Apache config.
  • Non-standard ports are a convenience and architectural tool for me, not a security measure on their own.

References

  • Apache Listen Directive: https://httpd.apache.org/docs/current/mod/mpm_common.html#listen
  • Apache Virtual Host Documentation: https://httpd.apache.org/docs/current/vhosts/
  • Red Hat SELinux Ports Documentation: https://access.redhat.com/documentation/
Total
1
Shares

Leave a Reply

Previous Post
How to set up multiple websites on Apache

How to Set Up Multiple Websites on Apache

Next Post
How to configure Apache to use SSL (HTTPS)

How to Configure Apache to Use SSL (HTTPS)

Related Posts