Configure Nginx as a reverse proxy for Home Assistant OS on KVM by forwarding port 8123 traffic to the guest's internal IP. This setup allows secure external access while keeping the virtual machine isolated. The configuration requires specific Nginx directives to handle WebSocket connections and proper SSL termination, ensuring seamless integration with your home server infrastructure without exposing the underlying hypervisor directly to the internet.
Network Configuration and Prerequisites
Before configuring the web server, ensure that the Home Assistant OS instance is running correctly within your KVM environment. The guest operating system must have a static internal IP address assigned via DHCP reservation or manual configuration in the VM settings. This stability is crucial because any change in the internal IP will break the reverse proxy routing immediately. Verify connectivity by pinging the guest from the host machine using the command
ping [guest-ip]. If the ping fails, check the network bridge configuration on the KVM host. You may need to adjust firewall rules to allow traffic between the host and the guest. For detailed troubleshooting on network isolation issues, refer to our guide on
How to Fix UFW Blocking KVM Guest from Getting IP Address and Accessing Network. Ensure that port 8123 is open on the guest's firewall if applicable, although typically the guest handles its own local services.
Nginx Installation and Initial Setup
Install the latest version of Nginx on your host machine if it is not already present. On Debian-based systems, use
apt install nginx. Once installed, verify the service status with
systemctl status nginx. It is recommended to create a dedicated configuration file for Home Assistant rather than modifying the default site configuration. Create a new file at
/etc/nginx/sites-available/home-assistant. This separation makes future updates and debugging significantly easier. Disable the default site to avoid conflicts by running
ln -sf /dev/null /etc/nginx/sites-enabled/default. Then, enable your new configuration with
ln -s /etc/nginx/sites-available/home-assistant /etc/nginx/sites-enabled/home-assistant. Always test the syntax before restarting the service to prevent downtime. Use
nginx -t to validate your configuration files. If the test passes, restart Nginx with
systemctl restart nginx.
Core Reverse Proxy Configuration
The core of the solution lies in the Nginx server block. You must define the server name, which should be your desired domain or subdomain for accessing Home Assistant. Configure the listen directive to accept traffic on port 443 for HTTPS. Inside the server block, add a location block for the root path. Use the
proxy_pass directive to forward requests to the Home Assistant instance on port 8123. Crucially, you must include headers to pass the correct client information. Add
proxy_set_header Host $host;,
proxy_set_header X-Real-IP $remote_addr;, and
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;. These headers ensure that Home Assistant knows the original requester's details, which is vital for authentication and logging. Without these, you might encounter issues where the application thinks all requests are coming from localhost.
WebSocket Support and SSL Termination
Home Assistant relies heavily on WebSockets for real-time updates, such as state changes and automation triggers. Standard HTTP proxies often drop these connections unless explicitly configured. To fix this, add specific upgrade headers within your location block. Include
proxy_http_version 1.1; and
proxy_set_header Upgrade $http_upgrade;. Also, set
proxy_set_header Connection "upgrade";. These lines tell Nginx to maintain the persistent connection required for WebSocket communication. If you plan to terminate SSL at the Nginx level, you must point to valid certificate files. Use
ssl_certificate and
ssl_certificate_key directives pointing to your Let's Encrypt or self-signed certificates. Self-signed certificates will trigger browser warnings, so obtaining a trusted certificate is highly recommended for a smooth user experience. For more insights on managing certificates in reverse proxy scenarios, see
Configuring SSL Passthrough with Certificates on Nginx Reverse Proxy for Paperless-ngx.
Troubleshooting Common Issues
After applying the configuration, you may encounter connection errors. A common issue is the 502 Bad Gateway error, which usually indicates that Nginx cannot reach the backend service. Check if the Home Assistant container or VM is running and listening on the expected port. Another frequent problem involves redirect loops caused by incorrect internal URL configurations in Home Assistant. Ensure that the
base_url in your Home Assistant configuration matches the public domain you are accessing. If you experience intermittent disconnections, review your WebSocket headers again. Sometimes, firewall rules on the host machine can interfere with established connections. If you suspect broader networking problems, such as the server becoming unreachable entirely, consult
Troubleshooting Home Server: Suddenly Unreachable Over Internet. Regularly check Nginx logs located at
/var/log/nginx/error.log for detailed error messages that can guide your fixes.
Frequently Asked Questions
Why do I get a 502 Bad Gateway error?
This error typically means Nginx cannot connect to the upstream Home Assistant service. Verify that the guest VM is running and that the internal IP address matches the one in your Nginx configuration. Check if port 8123 is accessible from the host machine using
curl http://[guest-ip]:8123.
Do I need to expose port 8123 to the internet?
No, you should never expose port 8123 directly to the internet. By using Nginx as a reverse proxy, you keep the internal port hidden behind your domain name. This adds a layer of security and allows you to manage SSL certificates centrally through Nginx rather than on the guest.
How do I handle multiple Home Assistant instances?
You can run multiple instances by creating separate server blocks in Nginx, each with a different server name or subdomain. Each block will point to a different internal IP address or port for the respective Home Assistant instance. Ensure that each instance has a unique
base_url configured internally.
Can I use HTTP instead of HTTPS?
While technically possible, using HTTP is strongly discouraged due to security risks. Home Assistant sends sensitive data including credentials and device states. Without encryption, this data can be intercepted by anyone on the network path. Always configure SSL/TLS for production or remote access setups.
What if my WebSocket connections drop frequently?
Frequent drops often indicate missing or incorrect WebSocket upgrade headers in the Nginx configuration. Double-check that
proxy_set_header Upgrade $http_upgrade and
Connection "upgrade" are present. Also, ensure that no intermediate firewalls are terminating idle connections too quickly.