Home Assistant Installation on Linux Server

Home Assistant is an open-source home automation platform that integrates thousands of smart home devices and services into a unified dashboard with powerful automation rules. This guide covers deploying Home Assistant on a Linux server using Docker, configuring integrations, building automation rules, setting up MQTT, and enabling secure remote access.

Prerequisites

  • Ubuntu 20.04/22.04 or CentOS 8/Rocky Linux 8+
  • Docker and Docker Compose installed
  • At least 2 GB RAM (4 GB recommended)
  • A domain name and SSL certificate (for secure remote access)
  • Smart home devices on the same network

Install with Docker

Docker is the recommended installation method for Home Assistant on a generic Linux server:

# Create directory structure
mkdir -p /opt/homeassistant/config

# Create docker-compose.yml
cat > /opt/homeassistant/docker-compose.yml << 'EOF'
version: '3.7'
services:
  homeassistant:
    container_name: homeassistant
    image: ghcr.io/home-assistant/home-assistant:stable
    volumes:
      - /opt/homeassistant/config:/config
      - /etc/localtime:/etc/localtime:ro
    restart: unless-stopped
    privileged: true
    network_mode: host   # Required for device discovery on LAN
    environment:
      - TZ=America/New_York  # Set your timezone
EOF

cd /opt/homeassistant
docker-compose up -d

# Follow logs during startup (first start takes 2-5 minutes)
docker-compose logs -f homeassistant

Access Home Assistant at http://your-server:8123.

Alternative: Home Assistant Container (without Supervisor):

docker run -d \
  --name homeassistant \
  --restart unless-stopped \
  --privileged \
  --network host \
  -v /opt/homeassistant/config:/config \
  -v /etc/localtime:/etc/localtime:ro \
  -e TZ=America/New_York \
  ghcr.io/home-assistant/home-assistant:stable

Initial Setup and Configuration

After startup, complete the onboarding wizard:

  1. Navigate to http://your-server:8123
  2. Create an admin account
  3. Set your location (for sun-based automations)
  4. Home Assistant will auto-discover devices on your network

Edit the main configuration file:

nano /opt/homeassistant/config/configuration.yaml
# /opt/homeassistant/config/configuration.yaml

# Home Assistant core config
homeassistant:
  name: "My Home"
  latitude: 40.7128
  longitude: -74.0060
  elevation: 10
  unit_system: metric
  currency: USD
  time_zone: America/New_York

# Enable the frontend
frontend:
  themes: !include_dir_merge_named themes/

# Enable HTTP (for reverse proxy setup)
http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 127.0.0.1
    - ::1

# Recorder - how long to keep history
recorder:
  purge_keep_days: 30
  db_url: sqlite:////config/home-assistant_v2.db

# Logger
logger:
  default: warning
  logs:
    homeassistant.components.mqtt: info

# Enable notifications
notify:
  - name: admin_email
    platform: smtp
    server: smtp.gmail.com
    port: 587
    starttls: true
    username: [email protected]
    password: your-app-password
    recipient: [email protected]

Restart after config changes:

docker restart homeassistant
# Or from the UI: Developer Tools > Check Config > Restart

Integration Setup

Home Assistant integrations connect to external services and devices:

# Most integrations are configured via the UI:
# Settings > Devices & Services > Add Integration

# Common integrations:
# - Philips Hue (auto-discovered on LAN)
# - Google Assistant / Amazon Alexa
# - Sonos / Chromecast
# - MQTT (for DIY devices)
# - Zigbee (via ZHA or Zigbee2MQTT)
# - Z-Wave (via Z-Wave JS)
# - Weather (OpenWeatherMap, Met.no)

Configure via YAML for programmatic integrations:

# /opt/homeassistant/config/configuration.yaml

# REST sensor (poll an API endpoint)
sensor:
  - platform: rest
    name: "Server CPU Temperature"
    resource: http://192.168.1.100:8080/api/temperature
    value_template: "{{ value_json.cpu_temp }}"
    unit_of_measurement: "°C"
    scan_interval: 30

  - platform: template
    sensors:
      feels_like:
        friendly_name: "Feels Like"
        value_template: "{{ states('sensor.outdoor_temperature') | float - 2 }}"
        unit_of_measurement: "°C"

# Binary sensor from REST
binary_sensor:
  - platform: rest
    name: "Server Online"
    resource: http://192.168.1.100/health
    value_template: "{{ value_json.status == 'ok' }}"

Automation Rules

Automations in Home Assistant use triggers, conditions, and actions:

# /opt/homeassistant/config/automations.yaml

# Turn on lights at sunset
- id: 'sunset_lights'
  alias: "Turn on living room lights at sunset"
  trigger:
    - platform: sun
      event: sunset
      offset: "-00:30:00"   # 30 minutes before sunset
  action:
    - service: light.turn_on
      target:
        entity_id: light.living_room
      data:
        brightness: 200
        color_temp: 4000

# Alert on high CPU temperature
- id: 'high_cpu_alert'
  alias: "Alert on high server CPU temperature"
  trigger:
    - platform: numeric_state
      entity_id: sensor.server_cpu_temperature
      above: 75
      for:
        minutes: 5
  condition:
    - condition: time
      after: "08:00:00"
      before: "22:00:00"
  action:
    - service: notify.admin_email
      data:
        message: "Server CPU temperature is {{ states('sensor.server_cpu_temperature') }}°C"
        title: "High Temperature Alert"

# Lock front door if left unlocked
- id: 'auto_lock_door'
  alias: "Auto-lock door after 10 minutes"
  trigger:
    - platform: state
      entity_id: lock.front_door
      to: "unlocked"
      for:
        minutes: 10
  action:
    - service: lock.lock
      target:
        entity_id: lock.front_door
    - service: notify.admin_email
      data:
        message: "Front door was automatically locked"

Dashboard Customization

Configure Lovelace dashboards:

# /opt/homeassistant/config/ui-lovelace.yaml
# (Or configure via UI: Settings > Dashboards)

title: My Home Dashboard
views:
  - title: Overview
    path: overview
    cards:
      - type: glance
        title: Climate
        entities:
          - entity: sensor.living_room_temperature
          - entity: sensor.living_room_humidity
          - entity: climate.thermostat

      - type: entities
        title: Lights
        entities:
          - entity: light.living_room
          - entity: light.bedroom
          - entity: light.kitchen
        show_header_toggle: true

      - type: history-graph
        title: Temperature History
        entities:
          - entity: sensor.living_room_temperature
        hours_to_show: 24

      - type: alarm-panel
        entity: alarm_control_panel.home_alarm

  - title: Server Monitoring
    path: servers
    cards:
      - type: gauge
        entity: sensor.server_cpu_temperature
        name: CPU Temp
        min: 0
        max: 100
        severity:
          green: 0
          yellow: 60
          red: 80

MQTT Configuration

MQTT connects Home Assistant to DIY sensors and IoT devices:

# /opt/homeassistant/config/configuration.yaml
mqtt:
  broker: localhost        # Or external MQTT broker IP
  port: 1883
  username: homeassistant
  password: mqttpassword
  discovery: true          # Auto-discover MQTT devices
  discovery_prefix: homeassistant

# MQTT sensor (ESP8266 temperature sensor example)
sensor:
  - platform: mqtt
    name: "Garage Temperature"
    state_topic: "home/garage/temperature"
    unit_of_measurement: "°C"
    device_class: temperature
    value_template: "{{ value_json.temperature }}"

binary_sensor:
  - platform: mqtt
    name: "Garage Door"
    state_topic: "home/garage/door"
    payload_on: "OPEN"
    payload_off: "CLOSED"
    device_class: garage_door

Run Mosquitto MQTT broker alongside Home Assistant:

# Add Mosquitto to docker-compose.yml
cat >> /opt/homeassistant/docker-compose.yml << 'EOF'

  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    ports:
      - "1883:1883"
      - "9001:9001"
    volumes:
      - /opt/homeassistant/mosquitto/config:/mosquitto/config
      - /opt/homeassistant/mosquitto/data:/mosquitto/data
      - /opt/homeassistant/mosquitto/log:/mosquitto/log
    restart: unless-stopped
EOF

mkdir -p /opt/homeassistant/mosquitto/config
cat > /opt/homeassistant/mosquitto/config/mosquitto.conf << 'EOF'
listener 1883
allow_anonymous false
password_file /mosquitto/config/passwd
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
EOF

# Create MQTT user
docker run --rm -it eclipse-mosquitto \
  mosquitto_passwd -c /tmp/passwd homeassistant
# Copy the generated password file
sudo cp /tmp/passwd /opt/homeassistant/mosquitto/config/passwd

docker-compose up -d mosquitto

Remote Access Setup

# Install Nginx reverse proxy with SSL
sudo apt install -y nginx certbot python3-certbot-nginx

# Obtain SSL certificate
sudo certbot certonly --standalone -d home.example.com

# Configure Nginx
cat > /etc/nginx/sites-available/homeassistant << 'EOF'
server {
    listen 443 ssl http2;
    server_name home.example.com;

    ssl_certificate /etc/letsencrypt/live/home.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/home.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:8123;
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }
}

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

sudo ln -s /etc/nginx/sites-available/homeassistant /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Troubleshooting

Home Assistant fails to start:

docker-compose logs homeassistant --tail 50

# Common issues:
# - configuration.yaml syntax errors
# - Missing integration dependencies

# Validate config from CLI
docker exec homeassistant python -c "import homeassistant; print('OK')"

# Check config via UI: Developer Tools > Check Configuration

Devices not discovered:

# Home Assistant needs host network mode for mDNS/SSDP discovery
docker inspect homeassistant | grep NetworkMode
# Should be: "NetworkMode": "host"

# Restart with host networking
docker-compose down && docker-compose up -d

Automation not triggering:

# Check automation trace: Settings > Automations > <Your Automation> > Traces
# Review trigger conditions and state values

# Test from Developer Tools > Template:
{{ states('sensor.living_room_temperature') }}

# Check if entity exists
docker exec homeassistant hass --script check_config

Database growing too large:

# Reduce history retention in configuration.yaml
recorder:
  purge_keep_days: 7   # Reduce from 30 to 7 days
  exclude:
    domains:
      - media_player   # Exclude noisy entities
    entities:
      - sensor.some_noisy_sensor

# Manually purge old data from UI:
# Developer Tools > Services > recorder.purge

Conclusion

Home Assistant on a Linux server delivers a fully self-hosted smart home platform with thousands of integrations and no cloud dependency. Docker deployment simplifies installation and updates, MQTT enables custom sensor integration, and the Nginx reverse proxy with SSL provides secure remote access. Start with a few automations and expand gradually — Home Assistant's visual automation editor and extensive documentation make it accessible even for complex multi-device setups.