Self-Hosted LoRaWAN with ChirpStack
ChirpStack is the open source LoRaWAN network server. It handles device authentication, packet deduplication from multiple gateways, adaptive data rate management, and delivery of sensor data to your application layer via MQTT. It is the software that sits at the centre of a private LoRaWAN deployment, doing the work that The Things Network or Helium would do in a public network arrangement, except entirely on your own infrastructure.
This guide walks through installing ChirpStack v4 on an Ubuntu server using the native apt packages. The target is the February homelab server once it is running, but the steps work on any Ubuntu 22.04 or 24.04 server.
Architecture overview
Before touching a command, it is worth being clear about what you are installing and why each component exists.
ChirpStack is the network server itself. It manages devices and applications, receives uplinks, sends downlinks, and exposes an API and web interface.
PostgreSQL is ChirpStack’s database. It stores device profiles, device sessions, application configuration, and gateway registrations.
Redis is ChirpStack’s in-memory store. It handles real-time packet processing, device session state, and caching.
Mosquitto is the MQTT broker. Gateways forward LoRa packets to Mosquitto. ChirpStack subscribes to Mosquitto to receive them. Your application subscribes to Mosquitto to receive processed device data.
ChirpStack Gateway Bridge runs on or close to the gateway. It translates the gateway’s packet format (Semtech UDP or Basics Station) into the MQTT messages ChirpStack expects.
The data flow is:
LoRa Device → Gateway → Gateway Bridge → Mosquitto → ChirpStack → Mosquitto → Your Application
Prerequisites
A running Ubuntu 22.04 or 24.04 server with:
- At least 1GB RAM (2GB recommended)
- At least 10GB available storage
- Network connectivity
- A non-root user with sudo access
The February homelab server comfortably exceeds these requirements.
Step 1: Install dependencies
Update the system and install required packages:
sudo apt update && sudo apt upgrade -y
sudo apt install -y \
postgresql \
redis-server \
mosquitto \
mosquitto-clients \
gpg \
curl
Step 2: Configure PostgreSQL
Start and enable PostgreSQL:
sudo systemctl enable --now postgresql
Create the ChirpStack database and user. Generate a strong password in KeePassXC first and store it there before running these commands:
sudo -u postgres psql << EOF
CREATE ROLE chirpstack WITH LOGIN PASSWORD 'your-strong-password-here';
CREATE DATABASE chirpstack WITH OWNER chirpstack;
\c chirpstack
CREATE EXTENSION pg_trgm;
\q
EOF
Verify the connection:
psql -h localhost -U chirpstack -d chirpstack -c "\l"
Enter the password when prompted. A successful connection confirms PostgreSQL is configured correctly.
Step 3: Configure Redis
Redis is used for session storage and caching. The default configuration is sufficient for a homelab deployment. Enable persistence so session data survives restarts:
sudo tee -a /etc/redis/redis.conf << 'EOF'
# ChirpStack persistence configuration
appendonly yes
appendfilename "appendonly.aof"
EOF
sudo systemctl enable --now redis-server
Verify Redis is responding:
redis-cli ping
Expected response: PONG
Step 4: Configure Mosquitto
ChirpStack v4 requires an MQTT broker. The default Mosquitto configuration allows unauthenticated connections on localhost, which is acceptable for a homelab behind a firewall. For a more hardened setup, configure username/password authentication.
Create the ChirpStack MQTT configuration:
sudo tee /etc/mosquitto/conf.d/chirpstack.conf << 'EOF'
# ChirpStack MQTT configuration
# Allow anonymous connections from localhost
# For production, use password authentication
listener 1883 127.0.0.1
# Allow connections from gateway bridge on the local network
listener 1883 0.0.0.0
allow_anonymous true
# Log to syslog
log_dest syslog
log_type all
EOF
For a more secure setup with authentication, generate a password file:
sudo mosquitto_passwd -c /etc/mosquitto/passwd chirpstack
sudo mosquitto_passwd /etc/mosquitto/passwd gateway
Then reference it in the configuration:
sudo tee /etc/mosquitto/conf.d/chirpstack.conf << 'EOF'
listener 1883
password_file /etc/mosquitto/passwd
allow_anonymous false
EOF
Enable and start Mosquitto:
sudo systemctl enable --now mosquitto
Step 5: Install ChirpStack
Add the ChirpStack apt repository:
sudo mkdir -p /etc/apt/keyrings/
sudo sh -c 'wget -q -O - https://artifacts.chirpstack.io/packages/chirpstack.key | \
gpg --dearmor > /etc/apt/keyrings/chirpstack.gpg'
echo "deb [signed-by=/etc/apt/keyrings/chirpstack.gpg] \
https://artifacts.chirpstack.io/packages/4.x/deb stable main" | \
sudo tee /etc/apt/sources.list.d/chirpstack.list
sudo apt update
sudo apt install -y chirpstack
Step 6: Configure ChirpStack
The main configuration file is at /etc/chirpstack/chirpstack.toml. Edit it:
sudo nano /etc/chirpstack/chirpstack.toml
Key sections to configure:
PostgreSQL connection
[postgresql]
dsn="postgres://chirpstack:your-strong-password-here@localhost/chirpstack?sslmode=disable"
Redis connection
[redis]
servers=["redis://127.0.0.1/"]
API secret key
Generate a unique secret key for securing API tokens:
openssl rand -base64 32
Copy the output and set it in the configuration:
[network]
net_id="000000"
enabled_regions=[
"eu868",
]
[api]
secret="your-generated-secret-here"
The net_id can remain 000000 for a private network. For a network that federates with other LoRaWAN networks, you would need a registered Net ID from the LoRa Alliance.
Region configuration
For the UK, the EU868 region is pre-configured. Verify it is in the enabled regions list. The region configuration file at /etc/chirpstack/region_eu868.toml contains channel configuration, data rates, and other region-specific settings.
The EU868 defaults are correct for the UK. No changes are needed here for a standard deployment.
MQTT integration
[integration]
enabled=["mqtt"]
[integration.mqtt]
server="tcp://localhost:1883"
# If using Mosquitto authentication:
# username="chirpstack"
# password="your-mosquitto-password"
Step 7: Start ChirpStack
Enable and start the service:
sudo systemctl enable --now chirpstack
Check the service status:
sudo systemctl status chirpstack
Follow the logs:
sudo journalctl -u chirpstack -f
The log output should show ChirpStack starting, connecting to PostgreSQL and Redis, and listening for connections. Any configuration errors appear here.
Step 8: Access the web interface
ChirpStack’s web interface runs on port 8080 by default. Access it from the desktop:
http://server.yourdomain.net:8080
Or from the server itself:
http://localhost:8080
The default credentials are:
- Username:
admin - Password:
admin
Change the admin password immediately after first login. Navigate to Users > admin > Change Password. Generate a strong password in KeePassXC.
Step 9: Install the ChirpStack Gateway Bridge
The Gateway Bridge runs close to the gateway: either on the gateway itself (if it runs Linux) or on a server on the same network. It translates the gateway’s packet format into the MQTT format ChirpStack expects.
Install it on the homelab server alongside ChirpStack:
sudo apt install -y chirpstack-gateway-bridge
Configure it at /etc/chirpstack-gateway-bridge/chirpstack-gateway-bridge.toml:
# UDP packet forwarder backend
[backend]
type="semtech_udp"
[backend.semtech_udp]
udp_bind="0.0.0.0:1700"
# MQTT integration
[integration.mqtt]
event_topic_template="eu868/gateway/{{ .GatewayID }}/event/{{ .EventType }}"
command_topic_template="eu868/gateway/{{ .GatewayID }}/command/#"
[integration.mqtt.auth]
type="generic"
[integration.mqtt.auth.generic]
server="tcp://localhost:1883"
Enable and start the Gateway Bridge:
sudo systemctl enable --now chirpstack-gateway-bridge
Step 10: Configure your gateway
The gateway must be configured to forward packets to the Gateway Bridge. The specific steps depend on the gateway hardware.
For most gateways running the Semtech UDP packet forwarder, configure the forwarder’s server_address to point at the homelab server:
{
"server_address": "server.yourdomain.net",
"serv_port_up": 1700,
"serv_port_down": 1700
}
For Basics Station protocol gateways, configure the Basics Station server URL:
wss://server.yourdomain.net:3001
Once the gateway is configured and connected, it should appear in the ChirpStack web interface under Gateways within a few minutes. The Last Seen timestamp will start updating as the gateway sends stats packets.
Step 11: Add a device profile and device
In the ChirpStack web interface:
- Navigate to Device Profiles > Add Device Profile
- Set the region to EU868
- Set the MAC version to LoRaWAN 1.0.4 (for most current devices) or 1.1.0 (for newer devices)
- Enable OTAA (Over-The-Air Activation) for devices that support it
Add an application:
- Navigate to Applications > Add Application
- Give it a descriptive name
Add a device to the application:
- Within the application, click Add Device
- Enter the Device EUI from the sensor’s documentation or label
- Enter the Application Key (for OTAA devices)
When the device transmits its first Join Request, ChirpStack handles the OTAA join procedure and the device begins appearing in the event log.
Receiving data via MQTT
Once a device is joined and transmitting, its data arrives on MQTT topics. Subscribe to see it:
mosquitto_sub -h localhost -t "application/#" -v
Uplink messages arrive on topics in the format:
application/{applicationId}/device/{devEui}/event/up
The payload is JSON containing the decoded frame data, signal strength, and metadata. This is the data that flows through to InfluxDB, Grafana, and Node-RED via the MQTT pipeline described in the MQTT series.
Firewall rules
Open the required ports on the homelab firewall:
# ChirpStack web interface
sudo ufw allow 8080/tcp
# Gateway Bridge UDP (Semtech UDP packet forwarder)
sudo ufw allow 1700/udp
# Gateway Bridge WebSocket (Basics Station)
sudo ufw allow 3001/tcp
# MQTT (restrict to internal network only)
sudo ufw allow from 10.0.0.0/8 to any port 1883 proto tcp
The MQTT port should not be exposed to the public internet. Restrict it to the internal network address space.
What comes next
A running ChirpStack instance is the foundation. The next steps are:
- Connecting the gateway hardware and verifying packet reception
- Importing device profiles from the
chirpstack-device-profilesrepository for common sensors - Configuring the MQTT integration to feed data into InfluxDB
- Setting up Grafana dashboards for sensor visualisation
- Configuring Node-RED for automation based on sensor readings