Главная страницаHome AssistantHome Assistant в Docker ContainerDocker часть 5: MariaDB
Docker часть 5: MariaDB

Docker часть 5: MariaDB

В этой части мы переделаем базу данных SQLite на MariaDB. Так как стандартная база данных предназначена для большого количества данных. И может нестабильно работать при заполнении.

Контейнер с MariaDB

Продолжая ту же тенденцию, что и в предыдущих частях. Первым делом добавим новый контейнер, в котором будет храниться наша база данных.

version: '3.0'

services:
  portainer:         # часть 2
    [...]
  homeassistant:     # часть 3
    [...]
  hass-configurator: # часть 4
    [...]

  mariadb:
    container_name: mariadb
    image: mariadb:latest
    restart: unless-stopped
    environment:
      - TZ=Europe/Moscow
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_HA_DATABASE}
      - MYSQL_USER=${MYSQL_HA_USER}
      - MYSQL_PASSWORD=${MYSQL_HA_PASSWORD}
    ports:
      - "3306:3306"
    volumes:
      - ./mariadb:/var/lib/mysql

Так же создаем папку для mariadb

mkdir mariadb

Переменные окружения

Возможно вы заметили, что в docker-compose.yaml появились записи подобного типа ${MYSQL_ROOT_PASSWORD}. Они хранят конфиденциальные данные в отдельном файле. Это особенно полезно, когда мы хотим создать резервную копию и/или распространить нашу конфигурацию Docker в системе контроля версий (VCS), такой как GitHub/Gitlab.

Чтобы указать значение для этих переменных среды, создайте файл .env в том же каталоге, что и файл docker-compose.yaml.

sudo nano .env

# Так же настроим права на запись, чтобы не приходилось каждый раз писать sudo
sudo chown root:docker .env
sudo chmod g+w .env

.env файл будет выглядеть так, обязательно поменяйте пароли

MYSQL_ROOT_PASSWORD=mariadbrootpassword
MYSQL_HA_DATABASE=ha_db
MYSQL_HA_USER=homeassistant
MYSQL_HA_PASSWORD=mariadbhapassword

Зависимости контейнеров

Если перезагрузим нашу систему Docker, мы также хотим, чтобы контейнер Home Assistant перед запуском ждал, пока контейнер MariaDB запустится. Это необходимо, чтобы данные из HA не потерялись.

Поэтому добавьте следующее в запись конфигурации в контейнере homeassistant

[...]
  homeassistant:
    [...]
    depends_on:
      - mariadb

После всего перезапускам Docker

docker compose up -d

Конфигурация Home Assistant

Когда контейнеры запущены и они работают, то первая половина работы выполнена. Нам все еще нужно сообщить Home Assistant об этой новой базе данных. Для этого мы добавим конфигурацию в Home Assistant.

Секреты

Открываем файл secrets.yaml с помощью File Editor и добавляем новую переменную. Не забудьте поменять ip адрес, а также если вы меняли пароли, то замените их.

mariadb: "mysql://homeassistant:mariadbhapassword@<ip>:3306/ha_db?charset=utf8mb4"

Соединение с базой данных

Далее переходим к configuration.yaml. В него вставляем новую запись, в которой будет происходить соединение с базой данных.

recorder:
  db_url: !secret mariadb
  purge_keep_days: 30

Перезапуск

Последним этапом заходим в интерфейс Панель разработчика и проверяем все ли правильно мы заполнили. В случае успешной проверки нажимаем «Перезапуск». Теперь база данных будет MariaDB.

Управление базой из Home Assistant

Если вам необходим доступ напрямую в базу данных, то можно установить любой web клиент. Самым простым решением будет Adminer.

Для этого добавляем новый контейнер в docker-compose.yaml

adminer:
  container_name: adminer
  image: adminer
  restart: unless-stopped
  environment:
    - ADMINER_DEFAULT_SERVER=mariadb
    - ADMINER_PLUGINS=frames
  ports:
    - "8077:8080/tcp"
  depends_on:
    - mariadb

Ну и конечно вывести его в интерфейс Home Assistant, файл configuration.yaml

panel_iframe:
  [...]
  
  adminer:
    title: Adminer
    icon: mdi:database
    url: "http://<ip>:8077"
    require_admin: true

Итоговая структура проекта

home-assistant
├── .env
├── docker-compose.yaml
├── fileeditor
├── homeassistant
├── mariadb
│   └── ...
└── portainer

Список всех частей

Был ли полезен материал?

Мне очень важно получать обратную связь. Пожалуйста, оцените материал. Так я пойму в какую сторону его стоит изменить.

Комментарии
  • Александр
    Александр
    03.10.2023 00:05

    Можете помочь, не пойму какой ip вставлять? По каким адресам контейнеры между собой общаються?

    • Alexander Pushkarev
      Alexander Pushkarev
      03.10.2023 11:15

      Про какой шаг идет речь?

  • Алексей
    Алексей
    21.11.2023 00:50

    Приветствую.

    Все сделал по инструкции… все поднялось. администрирование работает,

    но в логах ловится такое (фрагмент):
    File «/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py», line 193, in __init__
    super().__init__(*args, **kwargs2)
    sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (2002, «Can’t connect to server on ‘192.168.1.59’ (115)»)
    (Background on this error at: https://sqlalche.me/e/20/e3q8)
    2023-11-18 19:12:49.117 ERROR (Recorder) [homeassistant.components.recorder.util] Error executing query: (MySQLdb.OperationalError) (2002, «Can’t connect to server on ‘192.168.1.59’ (115)»)
    (Background on this error at: https://sqlalche.me/e/20/e3q8)
    2023-11-18 19:12:49.220 ERROR (Recorder) [homeassistant.components.recorder.util] Error executing query: (MySQLdb.OperationalError) (2002, «Can’t connect to server on ‘192.168.1.59’ (115)»)
    (Background on this error at: https://sqlalche.me/e/20/e3q8)
    2023-11-18 19:12:49.322 ERROR (Recorder) [homeassistant.components.recorder.util] Error executing query: (MySQLdb.OperationalError) (2002, «Can’t connect to server on ‘192.168.1.59’ (115)»)
    (Background on this error at: https://sqlalche.me/e/20/e3q8)
    2023-11-18 19:12:49.323 ERROR (Recorder) [homeassistant.components.recorder.core] Unhandled database error while processing task EventTask(event=<Event state_changed[L]: entity_id=sensor.contact_battery, old_state=, new_state=>): (MySQLdb.OperationalError) (2002, «Can’t connect to server on ‘192.168.1.59’ (115)»)
    (Background on this error at: https://sqlalche.me/e/20/e3q8)
    Traceback (most recent call last):
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py», line 145, in __init__
    self._dbapi_connection = engine.raw_connection()
    ^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py», line 3288, in raw_connection
    return self.pool.connect()
    ^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 452, in connect
    return _ConnectionFairy._checkout(self)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 1267, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 721, in checkout
    with util.safe_reraise():
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/util/langhelpers.py», line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 719, in checkout
    dbapi_connection = rec.get_connection()
    ^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 839, in get_connection
    self.__connect()
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 902, in __connect
    with util.safe_reraise():
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/util/langhelpers.py», line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 898, in __connect
    self.dbapi_connection = connection = pool._invoke_creator(self)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/create.py», line 637, in connect
    return dialect.connect(*cargs, **cparams)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/default.py», line 615, in connect
    return self.loaded_dbapi.connect(*cargs, **cparams)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/MySQLdb/__init__.py», line 121, in Connect
    return Connection(*args, **kwargs)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py», line 193, in __init__
    super().__init__(*args, **kwargs2)
    MySQLdb.OperationalError: (2002, «Can’t connect to server on ‘192.168.1.59’ (115)»)
    The above exception was the direct cause of the following exception:
    Traceback (most recent call last):
    File «/usr/src/homeassistant/homeassistant/components/recorder/core.py», line 904, in _process_one_task_or_recover
    return task.run(self)
    ^^^^^^^^^^^^^^
    File «/usr/src/homeassistant/homeassistant/components/recorder/tasks.py», line 281, in run
    instance._process_one_event(self.event)
    File «/usr/src/homeassistant/homeassistant/components/recorder/core.py», line 1012, in _process_one_event
    self._process_state_changed_event_into_session(event)
    File «/usr/src/homeassistant/homeassistant/components/recorder/core.py», line 1097, in _process_state_changed_event_into_session
    elif metadata_id := states_meta_manager.get(entity_id, session, True):
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/src/homeassistant/homeassistant/components/recorder/table_managers/states_meta.py», line 58, in get
    return self.get_many((entity_id,), session, from_recorder)[entity_id]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/src/homeassistant/homeassistant/components/recorder/table_managers/states_meta.py», line 108, in get_many
    for metadata_id, entity_id in execute_stmt_lambda_element(
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/src/homeassistant/homeassistant/components/recorder/util.py», line 219, in execute_stmt_lambda_element
    executed = session.execute(stmt)
    ^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/session.py», line 2262, in execute
    return self._execute_internal(
    ^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/session.py», line 2134, in _execute_internal
    conn = self._connection_for_bind(bind)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/session.py», line 2001, in _connection_for_bind
    return trans._connection_for_bind(engine, execution_options)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «», line 2, in _connection_for_bind
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/state_changes.py», line 139, in _go
    ret_value = fn(self, *arg, **kw)
    ^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/session.py», line 1126, in _connection_for_bind
    conn = bind.connect()
    ^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py», line 3264, in connect
    return self._connection_cls(self)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py», line 147, in __init__
    Connection._handle_dbapi_exception_noconnection(
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py», line 2426, in _handle_dbapi_exception_noconnection
    raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py», line 145, in __init__
    self._dbapi_connection = engine.raw_connection()
    ^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py», line 3288, in raw_connection
    return self.pool.connect()
    ^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 452, in connect
    return _ConnectionFairy._checkout(self)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 1267, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 721, in checkout
    with util.safe_reraise():
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/util/langhelpers.py», line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 719, in checkout
    dbapi_connection = rec.get_connection()
    ^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 839, in get_connection
    self.__connect()
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 902, in __connect
    with util.safe_reraise():
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/util/langhelpers.py», line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/pool/base.py», line 898, in __connect
    self.dbapi_connection = connection = pool._invoke_creator(self)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/create.py», line 637, in connect
    return dialect.connect(*cargs, **cparams)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/default.py», line 615, in connect
    return self.loaded_dbapi.connect(*cargs, **cparams)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/MySQLdb/__init__.py», line 121, in Connect
    return Connection(*args, **kwargs)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File «/usr/local/lib/python3.11/site-packages/MySQLdb/connections.py», line 193, in __init__
    super().__init__(*args, **kwargs2)
    sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (2002, «Can’t connect to server on ‘192.168.1.59’ (115)»)
    (Background on this error at: https://sqlalche.me/e/20/e3q8)
    2023-11-18 19:12:49.361 ERROR (Recorder) [homeassistant.components.recorder.util] Error executing query: (MySQLdb.OperationalError) (2002, «Can’t connect to server on ‘192.168.1.59’ (115)»)
    (Background on this error at: https://sqlalche.me/e/20/e3q8)
    2023-11-18 19:12:49.464 ERROR (Recorder) [homeassistant.components.recorder.util] Error executing query: (MySQLdb.OperationalError) (2002, «Can’t connect to server on ‘192.168.1.59’ (115)»)
    (Background on this error at: https://sqlalche.me/e/20/e3q8)
    2023-11-18 19:12:49.566 ERROR (Recorder) [homeassistant.components.recorder.util] Error executing query: (MySQLdb.OperationalError) (2002, «Can’t connect to server on ‘192.168.1.59’ (115)»)

    На что это похоже? где проблемка?

    Спасибо заранее

  • Igor
    Igor
    03.12.2023 22:35

    После всех установок и перезапуска появляются ошибки. Несколько раз проверял конфигурацию. Все сделал как описано

    Home Assistant Core

    Setup failed for recorder: Integration failed to initialize.
    22:32:22 – (ОШИБКА) setup.py — первое сообщение получено 22:32:03 и повторялось 5 раз
    Unable to set up dependencies of history. Setup failed for dependencies: recorder
    22:32:22 – (ОШИБКА) setup.py — первое сообщение получено 22:32:12 и повторялось 4 раз
    Error during connection setup: (MySQLdb.OperationalError) (1045, «Access denied for user ‘homeassistant’@’172.18.0.1’ (using password: YES)») (Background on this error at: https://sqlalche.me/e/20/e3q8) (retrying in 3 seconds)
    22:32:00 – (ОШИБКА) recorder — первое сообщение получено 22:31:33 и повторялось 10 раз
    Setup of recorder is taking over 10 seconds.
    22:31:42 – (ПРЕДУПРЕЖДЕНИЕ) runner.py

  • Игорь
    Игорь
    05.12.2023 16:25

    переделывал. все равно выдает такие ошибки

    Home Assistant Core
    Setup failed for recorder: Integration failed to initialize.
    16:23:55 – (ОШИБКА) setup.py — первое сообщение получено 16:23:51 и повторялось 5 раз
    Unable to set up dependencies of logbook. Setup failed for dependencies: recorder
    16:23:55 – (ОШИБКА) setup.py — первое сообщение получено 16:23:53 и повторялось 4 раз
    Error during connection setup: (MySQLdb.OperationalError) (1045, «Access denied for user ‘homeassistant’@’172.18.0.1’ (using password: YES)») (Background on this error at: https://sqlalche.me/e/20/e3q8) (retrying in 3 seconds)
    16:23:48 – (ОШИБКА) Recorder — первое сообщение получено 16:23:21 и повторялось 10 раз
    Setup of recorder is taking over 10 seconds.
    16:23:30 – (ПРЕДУПРЕЖДЕНИЕ) runner.py

  • Алексей
    Алексей
    13.12.2023 21:51

    Спасибо за отменный материал.

    Хотелось бы уточнить один момент для будущих последователей.
    Настанет момент когда будете делать сенсор в HA который будет отображать объем места занимаемой системой MySql

    Запрос подают такой

    SELECT table_schema "database", Round(Sum(data_length + index_length) / 1048576, 2) "value"
    FROM information_schema.tables
    WHERE table_schema="homeassistant"
    GROUP BY table_schema;

    и вот тут у меня он возвращал пустоту — table_schema="homeassistant" — не было такой записи
    Стал писать вопрос сюда и обозревая текст запроса и структуру баз — догал, что table_schema — это имя БД homeassistant, которое вы указали в настройках docker-compose. Т.к. я не иду простыми путями и даю свои имена, вот и попался.

    Откорректируйте запрос под вашу БД

    WHERE table_schema="имя-вашей бд-homeassistant"
  • Валерий
    Валерий
    25.01.2024 23:17

    При установке марии на raspberry pi 3 по инструкции возникает ошибка no matching manifest for linux/arm/v7 in the manifest list entries
    В этом случае образ марии можно использовать yobasystems/alpine-mariadb
    (аналогичная проблема имеется с code-server, но ему решения я не искал)

    • Alexander Pushkarev
      Alexander Pushkarev
      05.02.2024 15:32

      Все так, официальный образ MariaDB не поставляется для arm/v7.

  • Sergey
    Sergey
    14.11.2024 15:00

    В новой версии Home Assistant вывод в интерфейс через panel_iframe считается устаревшим и не работает, нужно создавать dashboardы (https://my.home-assistant.io/redirect/lovelace_dashboards/).
    https://github.com/home-assistant/home-assistant.io/issues/32162

  • Максим
    Максим
    03.01.2025 20:53

    Пробую ставить всё по инструкции, до этого момента всё шло нормально, но тут споткнулся: контейнер с марией не запускался, разобрался, что порт 3306 чем-то занят (ручной запуск выдавал сообщение Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already in use), как оказалось — mysql, остановил сервис и у меня контейнер с марией заработал, но когда залез в Adminer, то обнаружил, что в базе ha_db вообще нет таблиц :(, короче совсем не как на скриншоте выше. По десять раз всё проверил: и пароли и записи во всех файлах и прочее рестарты докера, HomeAssistent — база пустая, причём сам HomeAssistent ничего не говорит, что у него где-то там проблемы. Куда можно посмотреть и что проверить? Ставлю на комп с Ubuntu 22.04.4 LTS x64.

Оставить комментарий