Tự triển khai Mosquitto MQTT trên Docker: Xây dựng trung tâm điều khiển IoT riêng biệt và ổn định

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

Sự bất tiện khi nhà thông minh phụ thuộc vào đám mây (Cloud)

Tôi vẫn nhớ như in cái đêm mất mạng khi đang cố hoàn thành nốt công việc. Tôi bước vào văn phòng, bật công tắc đèn và… chẳng có chuyện gì xảy ra cả. Đó là một hồi chuông cảnh tỉnh. Những chiếc đèn “thông minh” của tôi về cơ bản chỉ là những cục gạch, chỉ vì chúng không thể kết nối được với một máy chủ cách xa hàng nghìn cây số chỉ để kích hoạt một rơ-le nằm cách tay tôi chưa đầy một mét. Nếu bạn từng gặp phải tình trạng trễ 2 giây sau khi chạm vào điện thoại để bật đèn, bạn đã rơi vào cái bẫy độ trễ của đám mây.

Độ trễ đó tồn tại vì hầu hết các thiết bị tiêu dùng đều bị ràng buộc bởi các cloud broker độc quyền như Tuya hoặc Sonoff. Khi bạn thêm nhiều cảm biến hơn—có thể giờ bạn đã có 20 hoặc 30 thiết bị—mạng của bạn sẽ trở thành một mớ hỗn độn của các phụ thuộc bên ngoài. Cách khắc phục là gì?

Một local MQTT (Message Queuing Telemetry Transport) broker. Hãy coi MQTT như một dịch vụ bưu chính tốc độ cao cho ngôi nhà của bạn. Đây là một ngôn ngữ nhẹ nhàng cho phép các cảm biến, Home Assistant và Node-RED trao đổi dữ liệu tức thì mà không bao giờ cần rời khỏi mạng nội bộ của bạn.

Theo kinh nghiệm của tôi, việc chuyển sang sử dụng một thực thể Mosquitto riêng biệt trên Docker chính là thời điểm bạn ngừng làm một người sưu tầm thiết bị và bắt đầu trở thành một kỹ sư HomeLab. Nó cung cấp một xương sống dạng module, linh hoạt và vẫn hoạt động ngay cả khi nhà mạng (ISP) của bạn gặp sự cố.

Lựa chọn phương thức triển khai

Quyết định nơi đặt broker là một quyết định dài hạn. Tôi đã dành nhiều tuần để thử nghiệm các thiết lập khác nhau trước khi chọn Docker. Dưới đây là bảng so sánh các phương pháp phổ biến nhất trong thực tế:

Phương pháp Ưu điểm Nhược điểm
Home Assistant Add-on Thiết lập đơn giản với một cú nhấp chuột. Nếu Home Assistant khởi động lại để cập nhật, toàn bộ mạng IoT của bạn sẽ mất kết nối trong vài phút.
Bare Metal (Ubuntu) Ít tốn tài nguyên hệ thống. Các tệp cấu hình bị phân tán trong /etc/, khiến việc sao lưu và di chuyển trở nên khó khăn.
Standalone Docker Cách ly hoàn toàn và dễ dàng di chuyển. Yêu cầu kiến thức cơ bản về volumes và networking.

Tại sao Docker là lựa chọn tối ưu cho MQTT

  • Vòng đời độc lập: Bạn có thể khởi động lại bộ não tự động hóa (Home Assistant) mà không làm ngắt kết nối các thiết bị Zigbee2MQTT hoặc Tasmota khỏi broker.
  • Di chuyển dễ dàng: Nếu chiếc Raspberry Pi không còn đủ mạnh, việc di chuyển broker sang một chiếc mini PC N100 mạnh mẽ hơn chỉ mất chưa đầy 5 phút. Bạn chỉ cần sao chép thư mục và chạy container.
  • Khắc phục lỗi phân quyền: Mặc dù Docker đôi khi có thể gây rắc rối với quyền truy cập tệp, việc sử dụng một User ID (UID) cụ thể sẽ giải quyết vấn đề này vĩnh viễn.

Sơ đồ cho một thiết lập vững chắc

Để có một HomeLab đáng tin cậy, chúng ta sẽ sử dụng Eclipse Mosquitto thông qua Docker Compose. Chúng ta sẽ bật tính năng lưu trữ dữ liệu bền vững (persistence)—để trạng thái thiết bị như “Đèn: Bật” vẫn tồn tại sau khi mất điện—và xác thực bằng mật khẩu để giữ cho mạng của bạn luôn an toàn.

Triển khai từng bước

1. Xây dựng cấu trúc thư mục

Tôi đã rút ra bài học xương máu rằng các tệp cấu hình lộn xộn sẽ dẫn đến những cơn đau đầu về sau. Tôi lưu trữ mọi thứ trong thư mục trung tâm ~/docker để việc sao lưu trở nên cực kỳ dễ dàng. Chạy các lệnh sau để chuẩn bị môi trường:

mkdir -p ~/docker/mosquitto/config
mkdir -p ~/docker/mosquitto/data
mkdir -p ~/docker/mosquitto/log
touch ~/docker/mosquitto/config/mosquitto.conf
touch ~/docker/mosquitto/config/pwfile

2. Cấu hình Broker

Mở tệp mosquitto.conf bằng trình soạn thảo bạn thích. Chúng ta cần xác định nơi dữ liệu được lưu và cách bảo mật được xử lý. Kể từ phiên bản Mosquitto 2.0, bạn phải xác định rõ ràng một listener cho lưu lượng truy cập bên ngoài.

# ~/docker/mosquitto/config/mosquitto.conf

persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log

# Mở cổng MQTT tiêu chuẩn
listener 1883

# Bảo mật là yếu tố bắt buộc
allow_anonymous false
password_file /mosquitto/config/pwfile

Ngay cả trong một hệ thống thử nghiệm nội bộ, tôi cũng không bao giờ sử dụng allow_anonymous true. Chỉ cần một thiết bị ESP32 cấu hình sai là đủ để làm broker của bạn tràn ngập dữ liệu rác, khiến việc gỡ lỗi trở thành một cơn ác mộng.

3. Tạo tệp Docker Compose

Tiếp theo, chúng ta tạo tệp docker-compose.yml bên trong ~/docker/mosquitto. Đây là sơ đồ thiết kế cho container của bạn.

version: '3.8'
services:
  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    restart: unless-stopped
    ports:
      - "1883:1883"
      - "9001:9001"
    volumes:
      - ./config:/mosquitto/config
      - ./data:/mosquitto/data
      - ./log:/mosquitto/log
    user: "1883:1883" # Khớp với ID người dùng nội bộ của Mosquitto

Mẹo nhỏ: Đặt user thành 1883:1883 là bí quyết để tránh lỗi “Permission Denied”. Nó đảm bảo rằng container thực sự có quyền ghi các bản ghi nhật ký và cơ sở dữ liệu vào máy chủ của bạn.

4. Bảo mật bằng mật khẩu

Đừng chỉ sử dụng một mật khẩu yếu. Vì Mosquitto đang chạy trong Docker, chúng ta có thể sử dụng một container tạm thời để băm (hash) thông tin xác thực của mình một cách an toàn:

docker run --rm -it -v ~/docker/mosquitto/config:/mosquitto/config eclipse-mosquitto mosquitto_passwd -c /mosquitto/config/pwfile người_dùng_iot_của_tôi

Hãy chọn một mật khẩu mạnh. Thông tin xác thực này sẽ là chiếc chìa khóa vạn năng cho mọi thiết bị thông minh trong nhà bạn.

5. Khởi chạy dịch vụ

Khởi chạy hệ thống chỉ với một lệnh duy nhất:

cd ~/docker/mosquitto && docker-compose up -d

Kiểm tra trung tâm điều khiển mới

Trước khi bắt đầu thêm thiết bị, hãy kiểm tra kết nối. Tôi thực sự khuyên bạn nên dùng MQTT Explorer. Nó cung cấp một cây dữ liệu trực quan, điều này rất cần thiết khi bạn có hơn 50 cảm biến báo cáo cùng lúc.

  1. Kết nối tới địa chỉ IP máy chủ của bạn qua cổng 1883.
  2. Nhập thông tin xác thực bạn vừa tạo.
  3. Theo dõi các tin nhắn đổ về.

Nếu bạn là người thích sử dụng dòng lệnh, bạn có thể theo dõi lưu lượng dữ liệu trực tiếp từ container:

docker exec -it mosquitto mosquitto_sub -u "người_dùng_iot_của_tôi" -P "mật_khẩu_của_bạn" -t "#" -v

Tích hợp cuối cùng

Broker của bạn hiện đã trở thành trái tim của ngôi nhà. Việc kết nối các dịch vụ giờ đây rất đơn giản:

  • Home Assistant: Đi tới Settings > Devices > MQTT. Nhập địa chỉ IP và thông tin xác thực của bạn.
  • Node-RED: Sử dụng node “mqtt in”. Trỏ nó về máy chủ của bạn và bạn đã sẵn sàng để xây dựng các kịch bản tự động hóa phức tạp.

Bằng cách chuyển MQTT broker vào container Docker riêng biệt, bạn đã xây dựng được một kiến trúc cấp độ chuyên nghiệp. Các kịch bản tự động hóa của bạn giờ đây sẽ nhanh hơn, dữ liệu của bạn được giữ riêng tư và ngôi nhà thông minh của bạn cuối cùng cũng hoạt động ổn định ngay cả khi không có internet.

Share: