Last Updated on Dec 10, 2020

I use docker-compose to run the ESPHome container which I use to flash ESPHome onto my ESP32 devices. To see how I do that, check the configs in this post.

Note: This guide does not get into detail how to install docker-compose though, but I’m sure you’ll find information about that.

[zsiti@docker ~]$ cat /home/zsiti/docker/docker-compose.yml
---
version: '3.1'
services:
  # https://hub.docker.com/r/esphome/esphome/tags
  # command for flashing: docker exec -it <container name: esphome> <command to run within the container: esphome> <configfile to load: esphome433.yaml> <specify esphome task: run/build/...>
  # command for flashing: docker exec -it esphome esphome esphome-esp32-ble.yaml run
  esphome:
    container_name: esphome
    image: esphome/esphome:1.14.3 # I use version locking to prevent unsuspected issues. I update the version tag before I wish to use the container for flashing
    volumes:
      - /home/zsiti/docker/esphome/:/config:rw
    #devices: # most of the time we'll be flashing over OTA (that's why we have port 6052), so the devices setting is not needed, only if it's the first flash of a new device
    #  - /dev/ttyUSB0:/dev/ttyUSB0 # the ESP device has to be mapped to the docker host (in my case it's a VM in ESXi), if it's not mapped, the /dev/ttyUSB0 device will not exist and the container will fail. If the ESP32 is not connected at the time, we need to comment out the devices section.
    environment:
      - ESPHOME_DASHBOARD_USE_PING=true
    ports:
      - 6052:6052
    restart: unless-stopped

As you can see, the ESPHome configs are stored in a persistent volume /home/zsiti/docker/esphome/

[zsiti@docker ~]$ cat /home/zsiti/docker/esphome/esphome-esp32-ble.yaml 
# ESPHome config
esphome:
  name: esphome-esp32-ble
  platform: ESP32
  board: esp32doit-devkit-v1

wifi:
  domain: .yourdomain.eu
  fast_connect: false
  reboot_timeout: 5min
  networks:
  - password: thisisthewifipassword
    ssid: ZsitiWiFi
  use_address: esphome-esp32-ble.yourdomain.eu

# Enable logging
logger:

# Enable Home Assistant API
api:
  password: 'thisistheesphomepassword'

ota:
  password: 'thisistheesphomepassword'

# BLE devices setup
esp32_ble_tracker:
#  scan_interval: 300s

# BLE presence
binary_sensor:
  - platform: ble_presence
    mac_address: 88:0F:10:F3:5C:XX
    name: "BLE Presence MiBand1A"
    device_class: presence

  - platform: ble_presence
    mac_address: D9:FD:C2:66:43:XX
    name: "BLE Presence MiBand2"
    device_class: presence

  - platform: ble_presence
    mac_address: 70:58:96:06:FC:XX
    name: "BLE Presence Mijia Quartz"
    device_class: presence

  - platform: ble_presence
    mac_address: DA:BD:CA:1D:32:XX
    name: "BLE Presence MiBand4 Andris"
    device_class: presence

  - platform: ble_presence
    mac_address: F5:8B:41:B5:B3:XX
    name: "BLE Presence MiBand4 Csilla"
    device_class: presence

  - platform: ble_presence
    mac_address: C5:BA:7D:D4:6C:XX
    name: "BLE Presence Philips S7970"
    device_class: presence

sensor:
# Xiaomi HHCCJCY01 BLE Sensor a.k.a. MiFlora
  - platform: xiaomi_hhccjcy01
    mac_address: C4:7C:8D:61:57:XX
    temperature:
      name: "MiFlora 1 Temperature"
    moisture:
      name: "MiFlora 1 Moisture"
    illuminance:
      name: "MiFlora 1 Illuminance"
    conductivity:
      name: "MiFlora 1 Soil Conductivity"
    battery_level:
      name: "MiFlora 1 Battery Level"

  - platform: xiaomi_hhccjcy01
    mac_address: C4:7C:8D:62:41:XX
    temperature:
      name: "MiFlora 2 Temperature"
    moisture:
      name: "MiFlora 2 Moisture"
    illuminance:
      name: "MiFlora 2 Illuminance"
    conductivity:
      name: "MiFlora 2 Soil Conductivity"
    battery_level:
      name: "MiFlora 2 Battery Level"

  - platform: xiaomi_hhccjcy01
    mac_address: C4:7C:8D:6A:69:XX
    temperature:
      name: "MiFlora 3 Temperature"
    moisture:
      name: "MiFlora 3 Moisture"
    illuminance:
      name: "MiFlora 3 Illuminance"
    conductivity:
      name: "MiFlora 3 Soil Conductivity"
    battery_level:
      name: "MiFlora 3 Battery Level"

# Xiaomi LYWSDCGQ BLE Sensor a.k.a. MiTemp LCD
  - platform: xiaomi_lywsdcgq
    mac_address: 4C:65:A8:D4:A3:XX
    temperature:
      name: "MiJia 1 Temperature"
    humidity:
      name: "MiJia 1 Humidity"
    battery_level:
      name: "MiJia 1 Battery Level"

  - platform: xiaomi_lywsdcgq
    mac_address: 4C:65:A8:D4:F3:XX
    temperature:
      name: "MiJia 2 Temperature"
    humidity:
      name: "MiJia 2 Humidity"
    battery_level:
      name: "MiJia 2 Battery Level"

  - platform: xiaomi_lywsdcgq
    mac_address: 4C:65:A8:DF:F2:XX
    temperature:
      name: "MiJia 3 Temperature"
    humidity:
      name: "MiJia 3 Humidity"
    battery_level:
      name: "MiJia 3 Battery Level"

  - platform: xiaomi_lywsdcgq
    mac_address: 4C:65:A8:DF:F7:XX
    temperature:
      name: "MiJia 4 Temperature"
    humidity:
      name: "MiJia 4 Humidity"
    battery_level:
      name: "MiJia 4 Battery Level"

  - platform: xiaomi_lywsdcgq
    mac_address: 4C:65:A8:DF:75:XX
    temperature:
      name: "MiJia 5 Temperature"
    humidity:
      name: "MiJia 5 Humidity"
    battery_level:
      name: "MiJia 5 Battery Level"

  - platform: xiaomi_lywsdcgq
    mac_address: 4C:65:A8:DF:75:XX
    temperature:
      name: "MiJia 6 Temperature"
    humidity:
      name: "MiJia 6 Humidity"
    battery_level:
      name: "MiJia 6 Battery Level"

# Xiaomi CGG1 BLE Sensor a.k.a. ClearGrass eInk
  - platform: xiaomi_cgg1
    mac_address: 58:2D:34:10:53:XX
    temperature:
      name: "Xiaomi CGG1 Temperature"
    humidity:
      name: "Xiaomi CGG1 Humidity"
    battery_level:
      name: "Xiaomi CGG1 Battery Level"

# Xiaomi LYWSD02 BLE Sensor a.k.a. eInk Clock
  - platform: xiaomi_lywsd02
    mac_address: 3F:5B:7D:82:7C:XX
    temperature:
      name: "Xiaomi LYWSD02 Temperature"
    humidity:
      name: "Xiaomi LYWSD02 Humidity"

Running the command for flashing

docker exec -it esphome esphome esphome-esp32-ble.yaml run

Important note: The ESP32 devices I use have a “FLASH” or “BOOT” button close to the USB connector. You need to push that button for a few seconds just before the flashing process starts. If you don’t do that, the flashing will fail.