<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: John Cheng</title>
    <description>The latest articles on DEV Community by John Cheng (@z_zt).</description>
    <link>https://dev.to/z_zt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1213654%2F496325d6-b2af-4abb-b6df-bb5960871d41.jpg</url>
      <title>DEV Community: John Cheng</title>
      <link>https://dev.to/z_zt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/z_zt"/>
    <language>en</language>
    <item>
      <title>Introduction to a General IoT Platform Architecture</title>
      <dc:creator>John Cheng</dc:creator>
      <pubDate>Thu, 08 Oct 2026 04:04:42 +0000</pubDate>
      <link>https://dev.to/z_zt/introduction-to-a-general-iot-platform-architecture-18eo</link>
      <guid>https://dev.to/z_zt/introduction-to-a-general-iot-platform-architecture-18eo</guid>
      <description>&lt;h2&gt;
  
  
  1. Overview
&lt;/h2&gt;

&lt;p&gt;A typical Internet of Things (IoT) system consists of several major components, including &lt;strong&gt;end devices, IoT communication infrastructure, business services, data storage, and user-facing applications&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The primary goal of an IoT platform is to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Allow users to interact with and manage connected devices through applications such as mobile apps and web applications, while enabling devices to send data, status updates, and events to the cloud and receive commands from cloud services.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A commonly used high-level architecture looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│                     Application Layer                       │
│                                                             │
│             Mobile App / Web / Mini Program / API           │
└──────────────────────────┬──────────────────────────────────┘
                           │
                     HTTP / WebSocket
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│                      Business Services                      │
│                                                             │
│       API Service / Business Service / User Service         │
│                                                             │
│  User Mgmt │ Device Mgmt │ Authorization │ Command Mgmt      │
└───────────────┬──────────────────────┬──────────────────────┘
                │                      │
                ▼                      ▼
        ┌───────────────┐      ┌────────────────┐
        │ Cache / Redis │      │ Database       │
        │               │      │                │
        │ Real-time     │      │ Business data  │
        │ state / cache │      │ / history      │
        └───────────────┘      └────────────────┘
                                       ▲
                                       │
                              ┌────────┴────────┐
                              │                 │
                              │                 │
┌─────────────────────────────┴─────────────────┴─────────────┐
│                    IoT Communication Layer                  │
│                                                             │
│                       MQTT Broker                            │
│                                                             │
│   Message Routing │ Connection Mgmt │ Topic │ QoS │ Session │
└─────────────────────────────┬───────────────────────────────┘
                              │
                            MQTT
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                         Device Layer                        │
│                                                             │
│       MCU / Gateway / Sensor / Controller / IoT Device      │
│                                                             │
└─────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not the only possible architecture, but it represents a common and practical design pattern for IoT systems.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Major Components of an IoT System
&lt;/h1&gt;

&lt;p&gt;A typical IoT platform can be divided into several logical layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application Layer
        ↓
Business Service Layer
        ↓
IoT Communication Layer
        ↓
Device Layer

Supporting the entire system:

Data Storage
Caching
Message Queues
Logging &amp;amp; Monitoring
Security
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different products may implement these components differently, but the layered architecture provides a useful and reusable design model.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. Device Layer
&lt;/h1&gt;

&lt;p&gt;The Device Layer connects the digital system to the physical world.&lt;/p&gt;

&lt;p&gt;Devices may include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microcontroller-based devices&lt;/li&gt;
&lt;li&gt;Sensors&lt;/li&gt;
&lt;li&gt;Controllers&lt;/li&gt;
&lt;li&gt;Gateways&lt;/li&gt;
&lt;li&gt;Industrial equipment&lt;/li&gt;
&lt;li&gt;Smart home devices&lt;/li&gt;
&lt;li&gt;Vehicles&lt;/li&gt;
&lt;li&gt;Embedded systems&lt;/li&gt;
&lt;li&gt;Other connected devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Devices are typically responsible for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Collecting data&lt;/li&gt;
&lt;li&gt;Executing commands&lt;/li&gt;
&lt;li&gt;Storing essential local configuration&lt;/li&gt;
&lt;li&gt;Establishing communication with the cloud&lt;/li&gt;
&lt;li&gt;Reporting status and events&lt;/li&gt;
&lt;li&gt;Providing basic offline functionality when network connectivity is unavailable&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A device normally does not need to maintain a direct business connection with a mobile application. Instead, it communicates with the cloud through the IoT communication layer.&lt;/p&gt;

&lt;p&gt;A typical communication path is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device
   │
   │ MQTT
   ▼
MQTT Broker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MQTT is widely used in IoT because of its lightweight communication model, publish/subscribe mechanism, and suitability for devices operating over constrained or unreliable networks.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. IoT Communication Layer
&lt;/h1&gt;

&lt;p&gt;The IoT Communication Layer is responsible for:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Providing reliable and efficient message exchange between devices and cloud services.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An MQTT Broker is a common component of this layer.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device A ──┐
Device B ──┤
Device C ──┼──→ MQTT Broker
Device D ──┤
Device E ──┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A device can publish messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device
   │
   │ publish
   ▼
MQTT Broker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cloud services can also publish commands to devices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MQTT Broker
   │
   │ publish
   ▼
Device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MQTT Broker primarily handles &lt;strong&gt;message transport and routing&lt;/strong&gt; rather than complex business logic.&lt;/p&gt;

&lt;p&gt;Typical broker responsibilities include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MQTT Broker
    │
    ├── Message routing
    ├── Client connection management
    ├── Topic management
    ├── QoS handling
    └── Session management
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Business logic such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User authorization
Device management
Business rules
Data processing
Command management
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;should normally be handled by the Business Service Layer.&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Business Service Layer
&lt;/h1&gt;

&lt;p&gt;The Business Service Layer is the core of the IoT platform.&lt;/p&gt;

&lt;p&gt;It connects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Applications
        ↕
Business Services
        ↕
IoT Platform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typical responsibilities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User management&lt;/li&gt;
&lt;li&gt;Device management&lt;/li&gt;
&lt;li&gt;User-device relationships&lt;/li&gt;
&lt;li&gt;Authorization and access control&lt;/li&gt;
&lt;li&gt;Command management&lt;/li&gt;
&lt;li&gt;Business rules&lt;/li&gt;
&lt;li&gt;Device state management&lt;/li&gt;
&lt;li&gt;Data processing&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;WebSocket connections&lt;/li&gt;
&lt;li&gt;Message processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, when a user performs an operation in a mobile app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP
 │
 │ WebSocket / HTTP
 ▼
Service
 │
 │ MQTT
 ▼
MQTT Broker
 │
 ▼
Device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Service validates the user's identity, permissions, and applicable business rules before sending the corresponding command to the device.&lt;/p&gt;

&lt;p&gt;After the device executes the command, it can return the result through MQTT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device
   │
   │ MQTT
   ▼
MQTT Broker
   │
   ▼
Service
   │
   ├──→ Database
   │
   └──→ WebSocket
          │
          ▼
         APP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a complete end-to-end communication cycle.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Communication Between Applications and Services
&lt;/h1&gt;

&lt;p&gt;Mobile and web applications typically do not communicate directly with MQTT Brokers.&lt;/p&gt;

&lt;p&gt;A common architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP
 │
 ├── HTTP / HTTPS
 │
 └── WebSocket
       │
       ▼
    Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HTTP/HTTPS is commonly used for operations such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login&lt;/li&gt;
&lt;li&gt;Querying data&lt;/li&gt;
&lt;li&gt;Updating configuration&lt;/li&gt;
&lt;li&gt;Retrieving historical data&lt;/li&gt;
&lt;li&gt;Managing user information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WebSocket is particularly useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time status updates&lt;/li&gt;
&lt;li&gt;Real-time events&lt;/li&gt;
&lt;li&gt;Command execution results&lt;/li&gt;
&lt;li&gt;Server-initiated notifications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both mechanisms can coexist.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP
 ↓
Query device list
Query historical data
Update configuration

WebSocket
 ↓
Real-time device status
Real-time events
Command results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  7. Data Storage Layer
&lt;/h1&gt;

&lt;p&gt;IoT systems can generate large amounts of data. Therefore, different types of data should be handled according to their characteristics and purpose.&lt;/p&gt;

&lt;p&gt;Not every piece of data needs to be written directly to a database.&lt;/p&gt;

&lt;p&gt;A common approach is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Data
                     │
          ┌──────────┼──────────┐
          │          │          │
          ▼          ▼          ▼
        Cache     Database   Message Queue
          │          │          │
      Real-time   Persistent   Asynchronous
        state        data       processing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7.1 Cache
&lt;/h2&gt;

&lt;p&gt;A caching system such as Redis can be used for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device online status
Latest device state
Sessions
Temporary data
Frequently accessed data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key characteristic is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A cache is optimized for fast access and should generally not be the only source of persistent data.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7.2 Database
&lt;/h2&gt;

&lt;p&gt;A database is used for data that needs to be stored reliably over time, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
Devices
Device configuration
Permissions
Historical records
Operation records
Event records
Command records
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The primary role of the database is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Reliable persistence and queryable storage of business data.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7.3 Message Queue
&lt;/h2&gt;

&lt;p&gt;As the system grows, a message queue can be introduced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MQTT
  │
  ▼
Service
  │
  ▼
Message Queue
  │
  ├──→ Data Processing
  ├──→ Statistics
  ├──→ Notifications
  ├──→ Logging
  └──→ Other Services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents every MQTT message from having to be processed synchronously inside the message-receiving path.&lt;/p&gt;




&lt;h1&gt;
  
  
  8. Real-Time Communication vs. Persistent Storage
&lt;/h1&gt;

&lt;p&gt;This is an important principle in IoT architecture.&lt;/p&gt;

&lt;p&gt;Suppose a device reports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;temperature = 25.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system may need to handle this data in two different ways.&lt;/p&gt;

&lt;p&gt;For the current device state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Real-time state
      ↓
    Redis
      ↓
Current temperature = 25.3°C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For historical analysis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Historical data
      ↓
   Database
      ↓
Timestamp
Device
Temperature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Real-time communication and persistent data storage are separate concerns.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The database should not simply be used as a relay for every real-time message.&lt;/p&gt;

&lt;p&gt;A more appropriate design is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 ┌──→ Redis
                 │
MQTT → Service ──┼──→ Database
                 │
                 └──→ Message Queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different data paths can then be selected according to their purpose.&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Commands, Events, and State
&lt;/h1&gt;

&lt;p&gt;It is useful to distinguish three fundamental types of IoT data from the beginning of the system design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Command
&lt;/h2&gt;

&lt;p&gt;A Command represents:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An instruction requesting a device or service to perform an operation.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SetConfig
Reboot
Start
Stop
UpdateFirmware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typical direction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP
 ↓
Service
 ↓
MQTT
 ↓
Device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Event
&lt;/h2&gt;

&lt;p&gt;An Event represents:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Something that happened in the system or on a device.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DeviceStarted
SensorTriggered
ConfigurationChanged
ErrorOccurred
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typical direction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device
 ↓
MQTT
 ↓
Service
 ↓
APP / Database / Other Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  State
&lt;/h2&gt;

&lt;p&gt;State represents:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The current condition or status of a device or system component.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;online
offline
running
stopped
temperature
battery
firmware_version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Current state is often stored in a cache for fast access and may also be persisted in a database when required by the business.&lt;/p&gt;




&lt;h1&gt;
  
  
  10. Example of an End-to-End Data Flow
&lt;/h1&gt;

&lt;p&gt;Consider a user performing an operation on a device through a mobile application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: The user initiates an operation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP
 │
 │ WebSocket
 ▼
Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: The Service processes the request
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service
 │
 ├── Authenticate user
 ├── Check authorization
 ├── Check device state
 └── Create Command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: The command is sent to the device
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service
 │
 │ MQTT
 ▼
MQTT Broker
 │
 ▼
Device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: The device executes the command
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device
 │
 ├── Execute command
 └── Generate Event
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: The device reports the result
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device
 │
 │ MQTT
 ▼
MQTT Broker
 │
 ▼
Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: The Service processes the result
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service
 │
 ├──→ Database
 │
 ├──→ Redis
 │
 └──→ WebSocket
          │
          ▼
         APP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user can then see the operation result in the application.&lt;/p&gt;




&lt;h1&gt;
  
  
  11. Why Is This Architecture So Common?
&lt;/h1&gt;

&lt;p&gt;One of the major advantages of this architecture is &lt;strong&gt;decoupling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP
 ↓
Service
 ↓
MQTT
 ↓
Device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer has a clearly defined responsibility.&lt;/p&gt;

&lt;p&gt;The application does not need to understand the device's low-level communication details.&lt;/p&gt;

&lt;p&gt;The device does not need to understand the application's user interface or business logic.&lt;/p&gt;

&lt;p&gt;The MQTT Broker does not need to understand complex business rules.&lt;/p&gt;

&lt;p&gt;The Service Layer connects these components and implements the business logic between them.&lt;/p&gt;

&lt;p&gt;This makes it possible to evolve individual components independently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application can change
        ↓
Service remains largely unchanged

Device implementation can change
        ↓
Service remains largely unchanged

MQTT infrastructure can change
        ↓
Business logic remains largely unchanged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This loose coupling makes the system easier to maintain and extend.&lt;/p&gt;




&lt;h1&gt;
  
  
  12. Architecture as the System Scales
&lt;/h1&gt;

&lt;p&gt;As the number of devices and users increases, the Business Service Layer can be further divided into specialized services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         APP / Web
                             │
                       API Gateway
                             │
              ┌──────────────┼──────────────┐
              │              │              │
              ▼              ▼              ▼
         User Service   Device Service   Data Service
              │              │              │
              └──────────────┼──────────────┘
                             │
                       Message Queue
                             │
                             ▼
                       MQTT Service
                             │
                             ▼
                       MQTT Broker
                             │
                             ▼
                          Devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supporting infrastructure may include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 ┌── Redis
                 │
Services ────────┼── Database
                 │
                 └── Object Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows individual components to scale independently according to their workloads.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device Service
    × 3

MQTT Consumers
    × 10

Data Service
    × 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no need to scale the entire system as a single unit.&lt;/p&gt;




&lt;h1&gt;
  
  
  13. Security
&lt;/h1&gt;

&lt;p&gt;Security should be treated as a fundamental part of the IoT architecture.&lt;/p&gt;

&lt;p&gt;At a minimum, the system should consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
 │
 ├── Authentication
 ├── Authorization
 └── Session / Token

Devices
 │
 ├── Device ID
 ├── Device Credentials
 ├── TLS
 └── MQTT ACL

Communication
 │
 ├── HTTPS
 ├── WSS
 └── MQTT over TLS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other important security considerations include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Device identity and authentication&lt;/li&gt;
&lt;li&gt;User authentication&lt;/li&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;li&gt;Data encryption&lt;/li&gt;
&lt;li&gt;Firmware integrity&lt;/li&gt;
&lt;li&gt;Key management&lt;/li&gt;
&lt;li&gt;Audit logging&lt;/li&gt;
&lt;li&gt;Protection against device impersonation&lt;/li&gt;
&lt;li&gt;Protection against replay attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security should not be added only after the system is completed. It should be considered from the beginning of the architecture design.&lt;/p&gt;




&lt;h1&gt;
  
  
  14. Logging, Monitoring, and Operations
&lt;/h1&gt;

&lt;p&gt;Observability is another important part of an IoT platform.&lt;/p&gt;

&lt;p&gt;A production system should ideally provide:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Monitoring
                     │
       ┌─────────────┼─────────────┐
       │             │             │
     Metrics        Logs         Traces
       │             │             │
       ▼             ▼             ▼
   CPU / Memory    Service       Request
   MQTT sessions   Logs          Tracing
   Device count    Errors        Message flow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it possible to determine whether a problem is caused by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Device
   ↓
Network
   ↓
MQTT Broker
   ↓
Service
   ↓
Database
   ↓
Application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than simply observing that “the application is not responding.”&lt;/p&gt;




&lt;h1&gt;
  
  
  15. A More Complete General IoT Architecture
&lt;/h1&gt;

&lt;p&gt;Combining the concepts above, a general-purpose IoT platform can be represented as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────────┐
│                       Application Layer                      │
│                                                              │
│              Mobile App / Web / API / Other Clients         │
└─────────────────────────────┬────────────────────────────────┘
                              │
                       HTTPS / WebSocket
                              │
                              ▼
┌──────────────────────────────────────────────────────────────┐
│                        API Gateway                            │
└─────────────────────────────┬────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────┐
│                     Business Services                        │
│                                                              │
│  User │ Device │ Command │ Data │ Notification │ Other       │
└─────────────┬──────────────────────────────┬─────────────────┘
              │                              │
              ▼                              ▼
        ┌───────────┐                  ┌──────────────┐
        │   Redis   │                  │   Database   │
        │   Cache   │                  │              │
        └───────────┘                  └──────────────┘
              ▲                              ▲
              │                              │
              └──────────────┬───────────────┘
                             │
                       Message Queue
                             │
                             ▼
┌──────────────────────────────────────────────────────────────┐
│                     IoT Platform Layer                       │
│                                                              │
│                       MQTT Broker                            │
│                                                              │
│    Connection │ Routing │ QoS │ Session │ Authentication      │
└─────────────────────────────┬────────────────────────────────┘
                              │
                             MQTT
                              │
                              ▼
┌──────────────────────────────────────────────────────────────┐
│                        Device Layer                          │
│                                                              │
│   Sensor │ MCU │ Gateway │ Controller │ Embedded Device      │
└──────────────────────────────────────────────────────────────┘


              ┌───────────────────────────────┐
              │     Security &amp;amp; Observability │
              │                               │
              │ Logs │ Metrics │ Tracing      │
              │ IAM │ TLS │ Audit │ Key Mgmt  │
              └───────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  16. General Architecture Principles
&lt;/h1&gt;

&lt;p&gt;When planning an IoT platform, the following principles provide a useful starting point.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 1: Use Clear Layers
&lt;/h3&gt;

&lt;p&gt;Define clear responsibilities for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
Service
MQTT
Device
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer should focus on its own responsibilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 2: Keep Components Decoupled
&lt;/h3&gt;

&lt;p&gt;The application should not depend directly on device implementation details, and devices should not depend on application-specific business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 3: Separate Real-Time Communication from Persistence
&lt;/h3&gt;

&lt;p&gt;Do not treat the database as a general-purpose relay for all real-time messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 4: Distinguish Commands, Events, and State
&lt;/h3&gt;

&lt;p&gt;Clearly separating:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Command
Event
State
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;makes the system easier to understand and extend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 5: Prefer Stateless Services
&lt;/h3&gt;

&lt;p&gt;Whenever possible, avoid storing critical state inside an individual Service instance.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Service × N
    │
    ├── Redis
    ├── Database
    └── Message Queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes horizontal scaling much easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 6: Design for Intermittent Connectivity
&lt;/h3&gt;

&lt;p&gt;IoT devices cannot assume that network connectivity will always be available.&lt;/p&gt;

&lt;p&gt;Depending on the product requirements, devices should support appropriate mechanisms such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Local state
Local configuration
Offline operation
Automatic reconnection
Message retry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  17. Summary
&lt;/h1&gt;

&lt;p&gt;A general IoT platform can be understood as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Users
                  │
                  ▼
             APP / Web
                  │
                  ▼
               Service
                  │
        ┌─────────┴─────────┐
        │                   │
        ▼                   ▼
      Data                MQTT
        │                   │
        │                   ▼
        │                 Device
        │
        ▼
   Database / Cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the system grows, additional components can be introduced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API Gateway
Message Queue
Microservices
Object Storage
Monitoring
Logging
Tracing
Security
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The architecture does not need to be overly complicated at the beginning. A practical evolution path is often:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Phase 1
APP
 ↓
Service
 ↓
MQTT
 ↓
Device
 ↓
Database


Phase 2
Add Redis
Add WebSocket
Add Message Queue


Phase 3
Split Services
Scale MQTT Consumers
Optimize Database
Add Monitoring


Phase 4
Kubernetes
Microservices
Multi-Region Deployment
High Availability
Elastic Scaling
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fundamental goal is &lt;strong&gt;not to follow one rigid architecture&lt;/strong&gt;, but to establish clear boundaries between applications, business logic, communication infrastructure, devices, and data.&lt;/p&gt;

&lt;p&gt;A well-designed IoT platform should allow these components to evolve independently while remaining reliable, secure, observable, and scalable as the number of devices and the complexity of the business increase.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>cloud</category>
      <category>iot</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Fighting Wildfires with IoT and AI: A Father-Son Open Source Mission</title>
      <dc:creator>John Cheng</dc:creator>
      <pubDate>Sat, 05 Sep 2026 05:28:39 +0000</pubDate>
      <link>https://dev.to/z_zt/fighting-wildfires-with-iot-and-ai-a-father-son-open-source-mission-4ech</link>
      <guid>https://dev.to/z_zt/fighting-wildfires-with-iot-and-ai-a-father-son-open-source-mission-4ech</guid>
      <description>&lt;h2&gt;
  
  
  🌲 Falling in Love with Nature—and Facing Wildfires
&lt;/h2&gt;

&lt;p&gt;A while ago, my family and I moved to Canada. &lt;/p&gt;

&lt;p&gt;Coming from a bustling industrial background in China, the first thing that struck us was the raw, breathtaking nature. The air is crisp, the lakes and tap water are crystal clear, and humans live side-by-side with wildlife in total harmony. In fact, in our quiet neighborhood, black bears occasionally drop by! They wander through the yard looking for berries or fallen apples, and then quietly move on without ever disrupting our daily routine.&lt;/p&gt;

&lt;p&gt;It felt like paradise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Except for one devastating problem that returns every summer: wildfires.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Year after year, millions of hectares of majestic forests are consumed by roaring fires. Smoke blankets the skies for hundreds of miles, turning the sun into an eerie orange disc, shutting down schools, and forcing families to evacuate.&lt;/p&gt;

&lt;p&gt;Watching this repeat year after year broke our hearts. We asked ourselves: &lt;em&gt;Can we use technology to make a difference before fires rage out of control?&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🤝 The Father &amp;amp; Son Team: IoT Meets Computer Vision
&lt;/h2&gt;

&lt;p&gt;I have spent decades working in &lt;strong&gt;industrial IoT hardware and embedded systems&lt;/strong&gt; in China—designing rugged field sensors, remote telemetry units, and ultra-reliable communications. &lt;/p&gt;

&lt;p&gt;Meanwhile, my son is currently studying &lt;strong&gt;Computer Science with a focus on Artificial Intelligence and Computer Vision&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One evening, looking out at the haze during wildfire season, we had an idea: &lt;strong&gt;What if we combined our strengths?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Father (Edge Hardware &amp;amp; Firmware):&lt;/strong&gt; Build an ultra-reliable, off-grid, low-power IoT sensing node capable of surviving years in remote wilderness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Son (Cloud Backend &amp;amp; Multi-Modal AI):&lt;/strong&gt; Ingest real-time telemetry, filter sensor drift, and run lightweight AI vision models on remote camera snapshots to verify smoke columns and suppress false alarms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is how &lt;strong&gt;ForestFireGuard&lt;/strong&gt; was born.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎥 The Story in Video
&lt;/h2&gt;

&lt;p&gt;I recently recorded a short video sharing our journey, our motivation, and why we decided to make this project 100% open source:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/EVP5XfrIreA" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(If the embed doesn't load, you can watch it directly &lt;a href="https://youtu.be/EVP5XfrIreA" rel="noopener noreferrer"&gt;on YouTube&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ The Engineering Challenge: Why Wildfire IoT is Hard
&lt;/h2&gt;

&lt;p&gt;Building a wildfire detector for a warm living room is easy. Building one for an isolated boreal forest is an entirely different engineering beast:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Zero External Power:&lt;/strong&gt; The node must run off a single primary battery and small solar cells for years.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fragile Cellular Connectivity:&lt;/strong&gt; In deep forests, 4G signals fluctuate or drop for days. &lt;strong&gt;Zero data loss&lt;/strong&gt; is mandatory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Severe Hardware RAM Constraints:&lt;/strong&gt; Running on low-cost, low-power microcontrollers (STM32F030 with only 32KB SRAM) means you cannot allocate massive memory buffers for camera image payloads without risking stack overflows or fragmentation.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🏗️ How ForestFireGuard Works
&lt;/h2&gt;

&lt;p&gt;Here is a look at the system architecture we engineered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-----------------------------------------------------------------------------------+
|                            EDGE NODE SUBSYSTEM (mcu/)                             |
|                                                                                   |
|  +--------------------+         +---------------------+                           |
|  | ESP32 Camera Node  |--UART--&amp;gt;|  SPI RAM (64KB)     | (High-Speed Image Cache)  |
|  | (VGA 640x480 JPEG) |         +----------+----------+                           |
|  +--------------------+                    |                                      |
|                                            v                                      |
|  +--------------------+         +---------------------+         +--------------+  |
|  |  Primary Sensors   |--I2C/--&amp;gt;|  SPI Flash (1MB)    |&amp;lt;--FRAM--|  Mainboard   |  |
|  | (GPS, AQ, Temp/Humi|  ADC    | (Append-Only Queue) |  (8KB)  | (STM32F030)  |  |
|  +--------------------+         +----------+----------+         +-------+------+  |
|                                            |                            |         |
+--------------------------------------------|----------------------------|---------+
                                             v                            | TLV
                                  +---------------------+                 v
                                  |   Network Module    |&amp;lt;----------------+
                                  | (EC800CN 4G Cat.1)  |
                                  +----------+----------+
                                             |
                                    MQTT / TCP Cellular
                                             v
+-----------------------------------------------------------------------------------+
|                        SERVER &amp;amp; AI SUBSYSTEM (service/ &amp;amp; Cloud)                   |
|                                                                                   |
|  +-----------------------------------------------------------------------------+  |
|  |                       IoT Ingress Service (service/)                        |  |
|  |                     (Receives 4G Payload &amp;amp; Stores to DB)                    |  |
|  +--------------------------------------+--------------------------------------+  |
|                                         |                                         |
|  =======================================|=======================================  |
|                 DATABASE LAYER (Delivery &amp;amp; Separation Boundary)                   |
|  =======================================|=======================================  |
|                                         v                                         |
|  +-----------------------------------------------------------------------------+  |
|  |                   Cloud AI Engine (Son's Pipeline)                          |  |
|  |  * Fetches real-time sensor metrics &amp;amp; VGA photos from DB                   |  |
|  |  * Runs Lightweight CV models (Smoke &amp;amp; Flame detection)                    |  |
|  |  * Dispatches verified high-confidence alerts to emergency channels        |  |
|  +-----------------------------------------------------------------------------+  |
+-----------------------------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Technical Highlights:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;3-Tier Storage for Zero Data Loss:&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;64KB SPI RAM&lt;/strong&gt; caches incoming JPEG images from the ESP32 camera without touching the STM32's tiny 32KB internal SRAM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1MB SPI Flash&lt;/strong&gt; operates in append-only mode as an indestructible flight data recorder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8KB Ferroelectric RAM (FRAM)&lt;/strong&gt; records non-volatile read/write pointers with near-infinite endurance. If the battery dies or connection drops, transmission resumes seamlessly upon reboot.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time-Multiplexed Power Gating:&lt;/strong&gt; All power-hungry modules (4G modem, camera, gas sensors) sit behind independent MOSFET switches. The STM32 powers them on sequentially, preventing destructive peak current surges.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean Architecture Boundary:&lt;/strong&gt; The PostgreSQL/Timescale database serves as the strict contract boundary. I ensure rock-solid data ingestion from the field into the DB; my son pulls from the DB for AI training, validation, and real-time inference.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌍 Why We Are Making It 100% Open Source
&lt;/h2&gt;

&lt;p&gt;Wildfires don't respect borders or patents. Communities in Canada, the US, Southern Europe, Australia, and South America are all battling the same threat.&lt;/p&gt;

&lt;p&gt;We believe that by sharing our schematics, PCB gerbers, STM32 firmware, and cloud code with the global developer community, we can help local forestry teams, researchers, and volunteers deploy affordable, early-warning sensor meshes.&lt;/p&gt;

&lt;h3&gt;
  
  
  💻 Join Us on GitHub!
&lt;/h3&gt;

&lt;p&gt;The project source code is available now on GitHub:&lt;br&gt;
👉 &lt;strong&gt;&lt;a href="https://github.com/Snowy-Collie/ForestGuardCloud" rel="noopener noreferrer"&gt;Check out AI part on GitHub (Alex)&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
👉 &lt;strong&gt;&lt;a href="https://github.com/wezhike/ForestFireGuard" rel="noopener noreferrer"&gt;Check out Hardware on GitHub(John)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We would love to hear your feedback:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What sensors would you prioritize for forest deployment?&lt;/li&gt;
&lt;li&gt;Have you tackled similar memory and power constraints on Cortex-M0 devices?&lt;/li&gt;
&lt;li&gt;Want to help with PCB design, embedded C refactoring, or computer vision models?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a comment below or open an issue on GitHub. Let’s build technology that makes a real-world difference together! 🌲🔥🚒&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>iot</category>
      <category>ai</category>
      <category>hardware</category>
    </item>
    <item>
      <title>Building an Images Repository - Harbor</title>
      <dc:creator>John Cheng</dc:creator>
      <pubDate>Sun, 19 Nov 2023 13:53:59 +0000</pubDate>
      <link>https://dev.to/z_zt/building-a-harbor-repository-m16</link>
      <guid>https://dev.to/z_zt/building-a-harbor-repository-m16</guid>
      <description>&lt;p&gt;Harbor is designed for storing container images and is generally deployed in an intranet environment to provide image services for containers running within the intranet.&lt;/p&gt;

&lt;p&gt;Harbor is open source and can be found on GitHub at: &lt;a href="https://github.com/goharbor/harbor" rel="noopener noreferrer"&gt;https://github.com/goharbor/harbor&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Testing Environment
&lt;/h2&gt;

&lt;p&gt;For testing purposes, set up a new virtual machine with CentOS 7.9 and make some modifications to the test environment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Disable the firewall, install iptables, and temporarily disable it:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl stop firewalld
systemctl disable firewalld
yum &lt;span class="nb"&gt;install &lt;/span&gt;iptables-services &lt;span class="nt"&gt;-y&lt;/span&gt;
systemctl stop iptables
systemctl disable iptables
iptables &lt;span class="nt"&gt;-F&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Disable SELinux:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;setenforce 0
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/SELINUX=enforcing/SELINUX=disabled/g'&lt;/span&gt; /etc/selinux/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Synchronize system time:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ntpdata cn.pool.ntp.org
crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Insert the following entry to synchronize every hour:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;/1 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /usr/sbin/ntpdate cn.pool.ntp.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install common components:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; yum-utils device-mapper-persistent-data lvm2 wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip &lt;span class="nb"&gt;sudo &lt;/span&gt;ntp libaio-devel vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Set up the repository:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enable system forwarding:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"net.bridge.bridge-nf-call-ip6tables = 1"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/sysctl.conf
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"net.bridge.bridge-nf-call-iptables = 1"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/sysctl.conf
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"net.ipv4.ip_forward = 1"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/sysctl.conf
sysctl &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Install Docker and Download Docker Compose
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install the latest version of Docker:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; docker-ce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enable Docker:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;docker &lt;span class="nt"&gt;--now&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Download Docker Compose:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://github.com/docker/compose/releases/download/v2.23.1/docker-compose-linux-x86_64
&lt;span class="nb"&gt;mv &lt;/span&gt;docker-compose-linux-x86_64 /usr/bin/docker-compose
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/bin/docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Create Certificates
&lt;/h2&gt;

&lt;p&gt;During the certificate creation process, ensure consistency in country code and city code. The hostname must match the local machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; /data/ssl &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /data/ssl/
openssl genrsa &lt;span class="nt"&gt;-out&lt;/span&gt; ca.key 3072
openssl req &lt;span class="nt"&gt;-new&lt;/span&gt; &lt;span class="nt"&gt;-x509&lt;/span&gt; &lt;span class="nt"&gt;-days&lt;/span&gt; 3650 &lt;span class="nt"&gt;-key&lt;/span&gt; ca.key &lt;span class="nt"&gt;-out&lt;/span&gt; ca.pem
openssl genrsa &lt;span class="nt"&gt;-out&lt;/span&gt; harbor.key 3072
openssl req &lt;span class="nt"&gt;-new&lt;/span&gt; &lt;span class="nt"&gt;-key&lt;/span&gt; harbor.key &lt;span class="nt"&gt;-out&lt;/span&gt; harbor.csr
openssl x509 &lt;span class="nt"&gt;-req&lt;/span&gt; &lt;span class="nt"&gt;-in&lt;/span&gt; harbor.csr &lt;span class="nt"&gt;-CA&lt;/span&gt; ca.pem &lt;span class="nt"&gt;-CAkey&lt;/span&gt; ca.key &lt;span class="nt"&gt;-CAcreateserial&lt;/span&gt; &lt;span class="nt"&gt;-out&lt;/span&gt; harbor.pem &lt;span class="nt"&gt;-days&lt;/span&gt; 3650
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Download and Install Harbor
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a directory:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; /data/install
&lt;span class="nb"&gt;cd&lt;/span&gt; /data/install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Download and extract files:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://github.com/goharbor/harbor/releases/download/v2.3.0-rc3/harbor-offline-installer-v2.3.0-rc3.tgz
&lt;span class="nb"&gt;tar &lt;/span&gt;zxvf harbor-offline-installer-v2.3.0-rc3.tgz &lt;span class="nt"&gt;-C&lt;/span&gt; /data/install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Modify the configuration file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; /data/install/harbor/harbor.yml.tmpl /data/install/harbor/harbor.yml
vim /data/install/harbor/harbor.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the hostname, certificate, and private_key to actual values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt;: harbor &lt;span class="c"&gt;# Adjust as needed&lt;/span&gt;

certificate: /data/ssl/harbor.pem
private_key: /data/ssl/harbor.key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install Harbor:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/data/install/harbor/install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Web User Management on the Client
&lt;/h2&gt;

&lt;p&gt;Access the IP or domain of this host to open the login page. Initial admin account information: &lt;br&gt;
Username: admin&lt;br&gt;
Password: Harbor12345&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 6: Configure Docker on the Client
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Modify /etc/docker/daemon.json:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim /etc/docker/daemon.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Add the following field in the client machine's /etc/docker/daemon.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;insecure-registries&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;192.168.xxx.xxx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hostname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the Docker service:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl daemon-reload
systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7: Testing
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Upload Test: Tag the image on the local machine in the format: ip/project_name/image_name
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker tag tomcat:latest 192.168.xxx.xxx/test/tomcat:v1
docker push 192.168.xxx.xxx/test/tomcat:v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Download Test:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull 192.168.xxx.xxx/test/tomcat:v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>image</category>
      <category>docker</category>
      <category>k8s</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Building a Private Repository</title>
      <dc:creator>John Cheng</dc:creator>
      <pubDate>Sun, 19 Nov 2023 13:50:55 +0000</pubDate>
      <link>https://dev.to/z_zt/building-an-intranet-sync-source-3a3b</link>
      <guid>https://dev.to/z_zt/building-an-intranet-sync-source-3a3b</guid>
      <description>&lt;p&gt;In the architecture of cloud services, multiple network planes are generally deployed, and the management plane is usually in the intranet environment, accessible through a jump server or VPN technology. This brings significant inconvenience to the installation, upgrade, or system upgrade of applications for the infrastructure of the server. Today, I will introduce a simple method to build a self-built Linux private repository.&lt;/p&gt;

&lt;p&gt;Before we begin, you need to prepare a virtual host with dual network cards, or a physical host will work as well. The host should run the Linux operating system; here, we'll use CentOS 7.9 as an example. If you are using a Debian-based Linux system, just replace the commands with &lt;code&gt;apt&lt;/code&gt; commands; the principle is exactly the same.&lt;/p&gt;

&lt;p&gt;Once the system is installed, connect one network card to the external network and another to the intranet, complete the relevant configurations and tests. Now let's officially start building the private repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Install and Configure Nginx
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install Nginx
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a basic operation, and installing Nginx may require additional steps, such as installing the EPEL repository. If you encounter any issues installing Nginx, please search online for related tutorials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure Nginx
&lt;/h3&gt;

&lt;p&gt;Configuring Nginx is straightforward. Just add three lines under the &lt;code&gt;server&lt;/code&gt; section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim /etc/nginx/nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    server &lt;span class="o"&gt;{&lt;/span&gt;
        autoindex on&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c"&gt;# Add this line&lt;/span&gt;
        autoindex_exact_size on&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c"&gt;# Add this line&lt;/span&gt;
        autoindex_localtime on&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c"&gt;# Add this line&lt;/span&gt;
        listen       80&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c"&gt;# Listening port&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then restart Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create a Directory for Sync
&lt;/h2&gt;

&lt;p&gt;This directory is configured in the /etc/nginx/nginx.conf file from the previous step. Here, we create it in the default working directory of Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /usr/share/nginx/html/rsync/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Download Sources
&lt;/h2&gt;

&lt;p&gt;You can download applications individually or synchronize downloads in batches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Download a Single Application
&lt;/h3&gt;

&lt;p&gt;As an example, let's download haproxy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /usr/share/nginx/html/rsync/haproxy
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--downloadonly&lt;/span&gt; &lt;span class="nt"&gt;--downloaddir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/share/nginx/html/rsync/haproxy/ haproxy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: This method downloads only applications that have not been installed on the local machine before. If you try to download an application that has been previously installed, such as nginx, you will get nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Batch Download
&lt;/h3&gt;

&lt;p&gt;Here we use the EPEL repository as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p /usr/share/nginx/html/rsync/epel/7/x86_64/
rsync -vrt --bwlimit=3000 --exclude=debug/ rsync://rsync.mirrors.ustc.edu.cn/epel/7/x86_64/ /usr/share/nginx/html/rsync/epel/7/x86_64/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create an Index
&lt;/h3&gt;

&lt;p&gt;When creating the index for the first time, install &lt;code&gt;createrepo&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; createrepo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the index; you need to use this command every time you update the content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;createrepo /usr/share/nginx/html/rsync/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;After these steps, the sync source is successfully installed. On the intranet host, modify the repo file's &lt;code&gt;baseurl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;baseurl &lt;span class="o"&gt;=&lt;/span&gt; http://xxx.xxx.xxx.xxx/rsync
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, transfer it to the relevant host and install using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; http://xxx.xxx.xxx.xxx/rsync/haproxy/haproxy-1.5.18-9.el7_9.1.x86_64.rpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>repo</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
