How to Deploy Home Assistant on a VPS
Updated Aug 2026
Self-host Home Assistant on your own VPS — the open-source hub for home automation, with local control of thousands of smart devices and automations that run entirely on your own hardware.
- A VPS with 2+ GB RAM
- A domain or subdomain for HTTPS access
- A fresh Ubuntu 24.04 or 26.04 server with root/sudo SSH access
What Home Assistant is
Home Assistant is the open-source hub for home automation — a single control plane for thousands of smart devices across Wi-Fi, Zigbee, Z-Wave, and every major cloud platform, with automations that run entirely on your own hardware. Everything stays on your server: device data, automation logic, and history never leave your box.
Hosting it on a VPS is the standard move for people who want maximum uptime and minimal fuss. A cloud box stays up when your home internet or power drops, is easy to back up, and you can reach it from anywhere. The trade-off is that devices that must live on your LAN need a bridge — but for cloud-connected devices and most automations, a VPS runs the same Home Assistant you'd run on a Raspberry Pi, with better specs. It's a Python stack rated 3 / 5 to deploy, and it hums along happily on 2 GB of RAM.
Server sizing — steady, with spikes
Home Assistant is a steady, light workload: it sits at a fraction of your VM's capacity most of the time, then spikes when automations fire or the dashboard refreshes.
- 2 GB RAM — the comfortable floor for Home Assistant, the recorder, and a handful of integrations
- 4 GB RAM — if you run media add-ons, Frigate for cameras, or many simultaneous integrations
The recorder database (history) grows over time, so plan for disk — 20–40 GB is plenty for years of history. A Hetzner CX22 (2 vCPU / 4 GB) at $4.59/mo runs Home Assistant plus its add-ons with headroom to spare.
Prepare the server
Start from a fresh Ubuntu 24.04 or 26.04 server. Update and create a non-root user:
apt update && apt upgrade -y
adduser deploy
usermod -aG sudo deploy
Lock down the firewall:
ufw allow OpenSSH
ufw allow 80
ufw allow 443
ufw allow 8123/tcp
ufw enable
Port 8123 is Home Assistant's web UI. Keeping it open is optional — if you put Home Assistant behind a reverse proxy for everything, you can drop this line and rely on Caddy alone.
Install Docker:
curl -fsSL https://get.docker.com | sh
usermod -aG docker deploy
Log out and back in as deploy so the docker group takes effect.
Install Home Assistant
Home Assistant publishes an official container. Create a working directory:
mkdir ~/homeassistant && cd ~/homeassistant
Create a compose file. Home Assistant uses host networking for device discovery, which is a key difference from most other containers:
services:
homeassistant:
image: ghcr.io/home-assistant/home-assistant:stable
restart: unless-stopped
network_mode: host
volumes:
- ./config:/config
Host networking lets Home Assistant see your network's multicast traffic, which is what makes auto-discovery of devices (and, later, a Zigbee/Z-Wave USB stick passthrough) work. The trade-off is that Home Assistant binds directly to host ports — the web UI comes up on port 8123 with no port mapping needed.
Start it:
docker compose up -d
Give it a minute to initialize, then load http://SERVER_IP:8123.
First-run setup
On the first load you'll set up:
- An admin account — your name, username, and a strong password. This is your only super-user; make it a good one.
- A location and time zone — Home Assistant uses this for sunrise/sunset automations and history.
- Device discovery — it scans your network automatically. Cloud-connected devices (Hue, Tuya, and so on) appear once you sign in to each integration.
The first-run experience is a guided flow, not a config file. Complete it before you enable remote access, and set up at least one device or integration so you have something to automate.
Connect your devices
The integrations you'll actually use depend on your hardware:
- Cloud devices (Hue, Tuya, Tasmota, SmartThings) — add each integration from Settings → Devices & services → Add integration and sign in. These work identically on a VPS because the cloud talks to Home Assistant, not to your LAN.
- Local Wi-Fi (Tasmota, Shelly, ESPHome) — add them by IP address. They must be reachable from the VPS, which usually means a VPN (see below) or a remote-access tool between your home network and the server.
- Zigbee / Z-Wave — needs the USB stick physically attached to the machine running Home Assistant, so it pairs naturally with a local install. On a VPS you'd need to host the coordinator on a device at home and connect remotely.
For a VPS setup, cloud-connected devices are the seamless path; local-only devices are best reached through a secure tunnel.
Remote access to LAN devices
This is the one genuine difference from running Home Assistant on a Pi at home: to control local-only devices from a cloud box, you need a secure path back into your home network. The standard solution is a VPN — Tailscale or Headscale on the VPS and your home network, with a device at home advertising the local subnet. See Deploy Headscale on a VPS for the full setup. Once the tunnel is up, integrations reach local devices through it exactly as if Home Assistant were on your LAN.
HTTPS + domain
Home Assistant needs HTTPS, especially once you expose it beyond localhost. Point a reverse proxy at port 8123 and terminate TLS on 443.
The simplest path is Automatic HTTPS with Caddy.
Point an A record for your hostname (say ha.example.com) at the server's
public IP, then have Caddy reverse-proxy that hostname to 127.0.0.1:8123.
Alternatively, Home Assistant ships its own remote-access add-on that handles certificates for you — but a Caddy front door keeps everything else on the box behind the same TLS setup.
Backups
Home Assistant's entire configuration lives in the config directory — backing
it up is the whole disaster-recovery story:
docker run --rm -v $(pwd)/config:/config -v $(pwd):/backup alpine \
tar czf /backup/homeassistant-$(date +%F).tar.gz -C /config .
If you're on a provider with daily snapshots (a Hetzner CX22
includes them), you get this for free at the box level. Keep the recorder
database and all your secrets.yaml in the same backup, and you can restore
the entire installation — devices, integrations, automations, and history.
Upgrades
Pull the newer image and recreate:
docker compose pull
docker compose up -d
Home Assistant runs database migrations automatically on startup. Upgrading the minor release line is low-risk; major releases occasionally change integration configs, so read the release notes first. Take a backup before every upgrade — it's one command and it makes a botched migration a non-event.
Troubleshooting
Setup screen doesn't load. Home Assistant takes a minute to initialize on
first boot. Check docker compose logs homeassistant | tail -20 for errors, and
confirm port 8123 is open in both the OS firewall and your provider's network
firewall.
No devices discovered. Home Assistant can't see your LAN through host networking if the traffic can't reach it. Cloud integrations work anywhere; local discovery needs the VPN path described above.
Automations don't fire. Check the recorder and integration states in Settings → Logs, and confirm the automation's conditions evaluate — sunrise times, for example, depend on the location you set at setup.
Slow dashboard. Usually the recorder database growing. Prune history via Settings → System → Storage, or size up the disk if you want years of retention.
Verification + next steps
You're done when you can: load the dashboard over HTTPS, sign in as your admin, add an integration that shows live device state, and create an automation that runs end to end.
From here, add media add-ons (Audiobookshelf, Jellyfin) or Frigate for cameras if you sized up to 4 GB, wire your LAN devices through a VPN, and set up the mobile apps so your automations travel with you. For the right box and the reliability argument, see Best VPS for Home Assistant for the ranked picks.