Remote access with Docker

Tags: #<Tag:0x00007fc4108d8c50> #<Tag:0x00007fc4108d8b38> #<Tag:0x00007fc4108d8a20>

Edit: Tim has pointed out that my ‘simple’ implementation has limitations.
Nginx Reverse Proxy Set Up Guide – Docker is a better implementation.

Getting remote access to Home Assistant without the add-ons seems to be a nightmare. But at last I have found real simple way to get everything done, including Letsencrypt, NGINX, certificate renewal, duckdns, security etc.

It is a docker package called SWAG (which used to be letsencrypt).

All you need to do is rename the sample home assistant configuration file!

I’ll keep things as simple as possible; giving you a working demo without trying to explain what I barely understand.

A basic understanding of Docker is presumed and Docker-Compose is installed on your machine.

I suggest you create a test directory (/home/user/test) and cut/paste the following configuration as explained below. The configuration is minimal so you can ​get the test working straight away. After that, it should be easy to modify your existing configuration.

1) Port Forwarding

You will need to forward ports 80 and 443 through your router to your server.
No need to forward port 8123

2) Set up a DuckDNS account

This is simple and fully explained on their web site.
Keep a record of “your-domain” and “your-access-token”

3) Create docker-compose.yml

In your test directory ( /home/user/test ) create the following docker-compose.yml file. Change your user and duckdns info.

version: "3"
services:
  swag:
    image: ghcr.io/linuxserver/swag:version-1.16.0
    container_name: swag-test
    environment:
      - URL=YOUR-DOMAIN.duckdns.org
      - SUBDOMAINS=wildcard
      - VALIDATION=duckdns
      - DUCKDNSTOKEN=YOUR-ACCESS-TOKEN
    volumes:
      - /home/user/test/volumes/swag:/config
    ports:
      - 443:443
      - 80:80
    restart: unless-stopped

  homeassistant:
    container_name: homeassistant-test
    image: homeassistant/home-assistant:2021.5.5
    volumes:
      - /home/user/test/volumes/hass:/config
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 8123:8123
    restart: unless-stopped

# docker internal network
networks:
  default:
      ipam:  
        config: 
         - subnet: 192.168.10.0/24

This is fairly standard docker config.
I specified the versions to be reasonsably future proof. It should be ok with latest versions.

NGINX will forward the external IP address through to homeassistant. Docker uses an internal network between its containers and it needs to be known so it can be trusted by home assistant.

I’ve named the containers xxx-test just to avoid name conflicts you might get with your production environment.

4) Set up SWAG

Set up the swag container.

docker-compose up swag

This will down load the swag image, create the swag volume, unpack and set up the default configuration.
It takes a some time to generate the certificates etc

If all goes well, it should end with

swag | [services.d] starting services
swag | [services.d] done.
swag | Server ready.

Use ctrl-c to stop docker gracefully.

5) Set up Homeassistant

Set up the homeassistant container

docker-compose up homeassistant

When it is done, use ctrl-c to stop docker gracefully.

6) Take ownership of volumes

Docker runs as root and you don’t get access to all the configuration data created in the volumes.

So, to take ownership of all volumes created by docker

sudo chown -R user:user /home/user/test/volumes

7) Activate for Homeassistant

The SWAG container contains a standard (NGINX) configuration for home assistant. All you have do is find it

cd /home/user/test/volumes/swag/nginx/proxy-confs

and rename it to remove the sample suffix…

mv homeassistant.subdomain.conf.sample homeassistant.subdomain.conf

No joking; that all !!

Note: The directory structure of SWAG may depend on the Linux system you have; I have Ubuntu 20.04.2 LTS

8) Enable IP banning

I tried to get fail2ban working, but eventually gave up. The standard home assistant ip banning is far simpler and seems to work well.

Also, we need to keep our ip address in duckdns uptodate.

Add the following to you home assistant config.yaml ( /home/user/test/volumes/hass/configuration.yaml).
Adjust for your local lan network and duckdns info

http:
  ip_ban_enabled: true
  login_attempts_threshold: 3
  use_x_forwarded_for: true
  trusted_proxies:
    - 192.168.X.0/24  # Local Lan
    - 192.168.10.0/24  # Docker network

duckdns: 
  domain: "YOUR-DOMAIN"
  access_token: "YOUR-TOKEN"

9) Finally-Test it is working

Launch homeassistant and swag

docker-compose up -d

Wait a little.

Then, use your browser to logon from your local network
192.168.X.XXX:8123
You should get your normal home assistant login.

Finally, use your browser to logon from outside your home
https://homeassistant.YOUR-SUB-DOMAIN.duckdns.org

Note: unless your router supports ’ loopback’ ( and mine didn’t) you might have to use telephone ( or tor browser) rather than local connection.

That’s it. You have remote access to home assistant; mission accomplished.


Notes:
If you misspell homeassistant or even leave it off, you’ll be taken through to a default web server page.
This default behqviour can be blocked ( see /home/user/test/volumes/swag/nginx/site-confs/default).
Also, you could change the home assistant server name in /home/user/test/volumes/swag/nginx/proxy-confs/homeassistant.subdomain.conf to make it more difficult to get to log in; eg https://h0m1$$t1nt.YOUR-SUB-DOMAIN.duckdns.org.
But I wanted to keep this as simple.
I didn’t get fail2ban to work for hass; their are by default, 4 other fail2ban jails implemented. These might be de-activated.

I’m sure you have your reasons for using docker. However I want to point out that using a virtual box (in my experience) has been such a fluid experience

Also I’m guessing that you can’t get supervisor addons in docker

If you can get supervisor addons in docker, use WireGuard, its amazing

If you have a windows server, you can use the link bellow, using the VirtualBox (.vdi) image choice

I fully agree. I would use the supervised system or a virtual machine if I could.
I tried installing hassio over Ubuntu, but ran into problems.
In a first draft, I started my write up with this observation, but removed it to keep things brief.

I use home assistant container and swag in docker too. I think the best benefit is I can run several other containers and programs, including a Shinobi NVR, on the same machine. That doesn’t seem possible with hass.io, and anyone trying to install any of the other supervised versions on linux always seems to have problems. It is more complex and you don’t get the add-ons, but there are a lot more options. You just have to run add-ons, like Node Red, in their own docker containers and manage them yourself.
Also, here is a good write up I used to set up the Swag/NGINX proxy, with similar steps you posted above Nginx Reverse Proxy Set Up Guide – Docker

Thanks, I don’t need another containers ( yet…), just a way to get remote access for my Smartthings. But yes it looks as if you can easily add in lots of stuff. I had previously followed an earlier (dehydrated) guide for remote access and it was complicated…
Reading through the good link you gave; there is no mention that swag is already configured and a simple file rename suffices.

Yes I definitely like the option to keep it simple, but I’ve found a lot with Home Assistant trying to take shortcuts generally has a downside that you only find out about later. The official home assistant install documentation advises home assistant container needs to be run with the --network=host option to be a supported install versus just mapping port 8123. Doing that then makes the container run with the network settings of the same machine it is hosted on. Without using the --network=host option auto discovery and bluetooth will not work in Home Assistant. The Smartthings integration doesn’t need autodiscovery so if that’s all you’re really using it for you’ll be fine, but definitely can run into issues trying to setup other integrations later that need either autodiscovery or upnp to work.

Once you do the --host option though, the Home Assistant container isn’t a part of the docker network anymore and it basically makes the default config in the swag container not work out of the box (unless they fixed it recently) and complicates the setup beyond the nice simple process you noted above. So then its pick your poison - not having autodiscovery working or not having your homeassistant container on the docker network. However if you update the config based on the post I linked above from @juan11perez to make everything work together you can have your cake and eat it too (use host network mode and get the swag/reverse proxy working), although it is a lot more complicated and more work. I also have fail2ban working using his setup/config so not sure why that didn’t work in your setup.

One other thing is that to overcome the root file permission issue and avoid needing to run a chown, you can set the PUID and PGID environment variables to the non-root user of the machine, which will be generally 1000. That way any files created by the swag container will have the same permissions as the non-root user. A lot of times when you don’t set these variables and you use chown, when you restart the container the files will just go back to belonging to root and you’ll have to chown them again to get access to them - Understanding PUID and PGID - LinuxServer.io