My Docker Stack

A lot of folks ask how to get started on a Docker stack and what to use to manage it all, so I figured I could share my docker-compose file for everyone to dig through and modify to your liking.

There are plenty of writeups on how to get Docker running on your platform, but I recommend using the official documentation from the Docker website. I assume most of you might use Ubuntu, so here are the instructions for Ubuntu

A few notes about it:

  1. On my docker host (Intel NUC, 8GB RAM, 256GB Samsung Evo m.2, running Alpine Linux), I have a directory /srv/docker where I store all persistent data for all my containers.
  2. I use Portainer for a ‘GUI’ for my Docker stack
  3. If you don’t have any Ubiquiti gear, obviously the UNIFI container is worthless to you. :wink:
  4. My Home Assistant is storing data in PostgreSQL, and I have a flow in my Node Red that also copies some events to the Mongo database (for me to play with later on another project)
  5. I am using InfluxDB so I can feed Grafana (Chronograf is really just there for me to play with)

My workflow consists of:

  • syncthing running in a container, pointing to my hass-config directory, where all my home assistant configuration files are, and I have syncthing running on my desktop, laptop, and NAS so I can keep versions, as well as being able to edit files locally on my computer, or while I am away on my laptop.
  • config changes are synced across almost instantly, and whenever I am done, I just restart my container using either Portainer or HA-Dockermon script in HASS

Once you have a docker compose file created, you can just type docker-compose up -d to start it all up.

I hope this helps some of you get started and takes some of the mystery out of a Home Assistant Docker stack. While this is not a comprehensive tutorial, or considered the ‘correct way’ to do anything, this has been working well for me for coming up on 8 months (many months of just running a couple of containers to figure out what I wanted the end product to look like)

In case you are wondering about the load on my NUC:

My Docker-Compose.yaml:

version: '3'
services:
  portainer:
    container_name: portainer
    image: portainer/portainer
    volumes:
      - /srv/docker/portainer:/data
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - "9000:9000"
  unifi:
    container_name: unifi
    restart: unless-stopped
    image: linuxserver/unifi
    volumes:
      - /srv/docker/unifi:/config
    environment:
      - PGID=0
      - PUID=0
      - ES_JAVA_OPTS='-Xms2g -Xmx2g'
    ports:
      - "8080:8080"
      - "8081:8081"
      - "8443:8443"
      - "8843:8843"
      - "8880:8880"
      - "3478:3478"
  syncthing:
    container_name: hass-sync
    restart: unless-stopped
    image: linuxserver/syncthing
    volumes:
      - /srv/docker/syncthing:/config
      - /srv/docker/hass-config:/sync
      - /etc/localtime:/etc/localtime:ro
    network_mode: host
    environment:
      - PGID=0
      - PUID=0
  mqtt:
    container_name: MQTT
    restart: unless-stopped
    image: eclipse-mosquitto
    volumes:
      - /srv/docker/mosquitto/config/mosquitto.conf:/mosquitto/config/mosquitto.conf
      - /srv/docker/mosquitto/log:/mosquitto/log
      - /srv/docker/mosquitto/data:/mosquitto/data
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "1883:1883"
      - "9001:9001"
  mongo:
    container_name: mongo
    restart: unless-stopped
    image: mongo
    volumes:
      - /srv/docker/mongo:/data/db
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "27017:27017"
  hadockermon:
    container_name: ha-dockermon
    restart: unless-stopped
    image: philhawthorne/ha-dockermon
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /srv/docker/ha-dockermon:/config
    ports:
      - "8126:8126"
  postdb1:
    container_name: postdb1
    restart: unless-stopped
    image: postgres:9.6
    volumes:
      - /srv/docker/postgresql:/var/lib/postgresql/data
      - /etc/localtime:/etc/localtime:ro
    environment:
      - POSTGRES_USER='myusername'
      - POSTGRES_PASSWORD='mypassword'
    ports:
      - "5432:5432"
  influxdb:
    container_name: influxdb
    restart: unless-stopped
    image: influxdb
    volumes:
      - /srv/docker/influxdb/influxdb.conf:/etc/influxdb/influxdb.conf:ro
      - /srv/docker/influxdb/db:/var/lib/influxdb
    environment:
      - INFLUX_GRAPHITE_ENABLED='true'
    ports:
      - "8086:8086"
  grafana:
    container_name: grafana
    restart: unless-stopped
    image: grafana/grafana
    depends_on:
      - "influxdb"
    volumes:
      - /srv/docker/grafana:/var/lib/grafana
    ports:
      - "3000:3000"
  chronograf:
    container_name: chronograf
    restart: unless-stopped
    image: chronograf
    depends_on:
      - "influxdb"
    volumes:
      - /srv/docker/chronograf:/var/lib/chronograf
    ports:
      - "8888:8888"
  speedtest:
    container_name: speedtest
    restart: unless-stopped
    image: atribe/speedtest-for-influxdb-and-grafana
    depends_on:
      - "influxdb"
    volumes:
      - /srv/docker/speedtest/config.ini:/src/config.ini
  homeassistant:
    container_name: home-assistant
    restart: unless-stopped
    image: homeassistant/home-assistant
    depends_on:
      - "influxdb"
      - "postdb1"
    devices:
      - /dev/ttyACM0:/dev/ttyACM0
    volumes:
      - /srv/docker/hass-config:/config
      - /etc/localtime:/etc/localtime:ro
      - /srv/docker/hass_media:/media
    network_mode: host
    privileged: true
  nodered1:
    container_name: node-red-1
    restart: unless-stopped
    image: nodered/node-red-docker
    depends_on:
      - "homeassistant"
    user: root
    volumes:
      - /srv/docker/node-red-1/user:/data
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "1880:1880"
50 Likes

Hi,

I am runing more containers on my NAS.
(including bookstack, concrete5, find, firefly, gogs, kanboard, organizr, phpmyadmin), but not running some that you have of course :slight_smile:

Thanks for enlightening me with ha-dockermon. Never heard of it till now, and I might try it out.

Why are you using speedtest in docker instead of just using homeassistant component? Because it gets broken sometimes or any other reasons?

Nice! What’s the tool you’re using to produce the output in the second screenshot (the one below htop) ?

One more question:

What does this do in docker-compose?
user: root

I see you have it in node-red config.

I have an extra PC lying around and it seems that my rPi3 is struggling to keep up. I may switch to this and consolidate my Unify controller & Hass so a single machine.

I was considering moving Unify to my FreeNAS and even contemplated moving HASS into a Jail as well (if that is even possible).

It’s a tool called glances. https://nicolargo.github.io/glances/

1 Like

Ha. Yeah, pretty much.

as @Mohitsharma44 pointed out, Glances

It runs the processes inside that container as that user. I run my stack as root (I know, naughty naughty…lol), and I don’t like dealing with the permissions issues.

if you need to connect to any hardware, this won’t work on FreeNAS

3 Likes

Does portainer have support for docker-compose yet (ie can you do the equivalents of down and up -d from the GUI)? I tried it a while ago and when I realized it didn’t have compose support I just went back to command line admin (which with docker-compose is pretty minimal anyway). But I know there have been requests for compose support on GitHub.

I have not seen support for that added yet. Mainly I use Portainer to quickly tear down or restart containers, without dealing with the command line for it. Sometimes it is nice to be able to console into a container from the gui, rather than the command line. It’s just handy for little one-offs and basic management, I feel.

I was searching for a way how to run it aas different user. I saw some containers exposed PUID and PGUID so I used those. Do you know if user also has to be exposed (command used while building docker image)?

When I run from the command line, I use -e PGID=0 -e PUID=0. I don’t remember why I used user: root in my compose as opposed to -e PGID=0 -e PUID=0. Maybe I was just testing it out to see if it worked. LOL. I will experiment and see.

That I am not sure about.

Thank you for sharing! Getting a NUC and using Docker is the next step in my smart home Home Assistant evolution. This is a nice overview of how it’s setup.

I have been experimenting with Docker inside of an Ubuntu VirtualBox container on my Windows machine and Node Red just wouldn’t work unless I used the --user root command. For whatever reason, it just couldn’t get access to shares like every other container. This is referenced in the Node Red docker page so I’m guessing its something others have issues with.

Hoping that when I get a real machine to run this stuff on I won’t have to do that, but we will see.

1 Like

Running as root isn’t exactly as bad as it has been made out to be. lol.

I may set this up over the weekend. Is this meant to be installed on a server install (unbuntu)? I noticed you said you were using Alpine Linux.

Which would be best? Straight up Debian?

I prefer a the GUI interface sometimes.

Docker doesn’t care if it is a ‘server’ install or ‘desktop’. Any OS can be a server.

Whatever you are comfortable with.

I would probably go with a version of Ubuntu. For most of my linux VMs that I want a GUI on, I use Xubuntu

That’s really cool. I’m curious; why did you pick Portainer vs. Rancher?

Do you use rancher?

I have a prod and dev environment rancher at work that I maintain. Rancher is way more complicated than is necessary for this setup. Portainer doesn’t require a DB. :wink:

1 Like

I misunderstood, I didn’t realize it was a web page control. I installed Ubuntu desktop 16.04, Docker CE, and now Portainer.

I’ll probably test/play getting a working HA then reinstall Ubuntu Server… or maybe not.

No idea what I’m doing at this point anyway lol.

1 Like

Desktop/Server it doesn’t matter. Think if it like this: they both run the same OS. One just has an interface on it that you can use keyboard, monitor, and mouse. The other is command line and usually only accessed over the network via SSH. Once you have your server working, there is no need for the keyboard, monitor, or mouse. Stuff it in a corner with power and network and you’re done. At that point the desktop interface is a waste of resources.