This guide will walk you through setting up an MQTT broker with PostgreSQL for managing users. By using Docker, you'll create a modular and scalable environment that integrates well with other systems.
Prerequisites
Installing Docker and Docker-Compose on Ubuntu
To install Docker and Docker-Compose from their official Git repositories on Ubuntu, follow these steps:
- Update the System Packages
sudo apt update sudo apt upgrade -y
- Install Required Dependencies
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
- Add Docker's Official GPG Key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
- Add Docker's Stable Repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- Install Docker Engine
sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io
- Verify Docker Installation
docker --version
- Install Docker-Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
- Verify Docker-Compose Installation
docker-compose --version
You are now ready to proceed with the setup.
Before starting, ensure you have the following installed:
- Docker
- docker-compose
If you're new to Docker, consider reading Docker's official documentation to familiarize yourself with its basics.
Step-by-Step Guide
1. Create a docker-compose.yml
File
Begin by creating a docker-compose.yml
file in a new project directory. This file will define the services for the MQTT broker, PostgreSQL, and a FastAPI application to manage users.
Here’s the content of the docker-compose.yml
file:
version: '3.8' networks: mqtt-net: driver: bridge ipam: driver: default config: - subnet: 172.100.10.0/24 services: mqtt-broker: image: eclipse-mosquitto:latest user: mosquitto volumes: - type: bind source: ./config/ target: /mosquitto/config/ read_only: false - type: bind source: ./log/ target: /mosquitto/log/ read_only: false - type: volume source: data target: /mosquitto/data/ ports: - target: 1883 published: 1883 protocol: tcp mode: host - target: 9001 published: 9001 protocol: tcp mode: host networks: mqtt-net: ipv4_address: 172.100.10.10 environment: - MOSQUITTO_AUTH_PLUGIN=auth_plugin_pgsql.so - PGSQL_HOST=pgsql - PGSQL_USER=mqtt_user - PGSQL_PASSWORD=mqtt_password - PGSQL_DATABASE=mqtt_users pgsql: image: postgres:latest container_name: postgres-container environment: POSTGRES_USER: mqtt_user POSTGRES_PASSWORD: mqtt_password POSTGRES_DB: mqtt_users volumes: - pg_data:/var/lib/postgresql/data networks: mqtt-net: ipv4_address: 172.100.10.20 fastapi-service: build: context: ./fastapi container_name: fastapi-container ports: - "8000:8000" networks: mqtt-net: ipv4_address: 172.100.10.30 environment: - DATABASE_URL=postgresql+psycopg2://mqtt_user:mqtt_password@pgsql:5432/mqtt_users volumes: data: name: "mqtt-broker-data" pg_data: name: "pg-data"
2. Create a FastAPI Service
a. Create a Directory for FastAPI
In your project directory, create a folder named fastapi
. Inside this folder, you'll define the FastAPI application and its Docker configuration.
b. Create a Dockerfile for FastAPI
In the fastapi
directory, create a Dockerfile
with the following content:
FROM python:3.10-slim # Set the working directory WORKDIR /app # Copy FastAPI app files COPY . /app # Install dependencies RUN pip install --no-cache-dir fastapi uvicorn sqlalchemy psycopg2-binary pydantic # Expose FastAPI default port EXPOSE 8000 # Command to run FastAPI CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
3. Write the FastAPI Application
Create a file named main.py
in the fastapi
directory. This file will define the FastAPI application. Here’s an example:
from fastapi import FastAPI, HTTPException from pydantic import BaseModel from sqlalchemy import create_engine, Column, String, Table, MetaData from sqlalchemy.orm import sessionmaker app = FastAPI() # Database configuration DATABASE_URL = "postgresql+psycopg2://mqtt_user:mqtt_password@pgsql:5432/mqtt_users" engine = create_engine(DATABASE_URL) metadata = MetaData() mqtt_users = Table( 'mqtt_users', metadata, Column('username', String, primary_key=True), Column('password', String, nullable=False) ) metadata.create_all(engine) Session = sessionmaker(bind=engine) # Pydantic model for user input class User(BaseModel): username: str password: str @app.get("/users") def list_users(): with Session() as session: result = session.query(mqtt_users).all() users = [{"username": row.username} for row in result] return {"users": users} @app.post("/users") def add_user(user: User): with Session() as session: existing_user = session.query(mqtt_users).filter_by(username=user.username).first() if existing_user: raise HTTPException(status_code=400, detail="User already exists") session.execute(mqtt_users.insert().values(username=user.username, password=user.password)) session.commit() return {"message": "User added successfully"} @app.delete("/users/{username}") def remove_user(username: str): with Session() as session: result = session.query(mqtt_users).filter_by(username=username).delete() session.commit() if not result: raise HTTPException(status_code=404, detail="User not found") return {"message": "User removed successfully"} @app.put("/users/{username}/reset-password") def reset_password(username: str, new_password: str): with Session() as session: result = session.query(mqtt_users).filter_by(username=username).update({"password": new_password}) session.commit() if not result: raise HTTPException(status_code=404, detail="User not found") return {"message": "Password reset successfully"}
4. Start the Services
Run the following command in your project directory to build and start the containers:
docker-compose up --build
5. Test the FastAPI Service
Open your browser or a tool like Postman and navigate to http://localhost:8000
. Use the provided endpoints to manage users:
- GET /users: List all users.
- POST /users: Add a new user.
- DELETE /users/{username}: Remove a user.
- PUT /users/{username}/reset-password: Reset a user’s password.
Top comments (0)