Skip to main content

Configure ChirpStack

ChirpStack is an open-source, multi-tenant LoRaWAN Network Server (LNS) that provides a web interface and gRPC API for managing devices, routing messages, and interacting with major cloud providers.

Getting Started

Before beginning, make sure to have the following:

  • Helium Config Service CLI with delegate keypair
  • Helium Network Organizationally Unique Identifier (OUI)
  • Helium LoRaWAN devAddr slab
  • Data Credits (>3.5M DC)

Infrastructure Requirements

This guide describes running ChirpStack in a non-production setting. As such, the infrastructure requirements noted below are sufficient for getting a ChirpStack instance up and running for experimentation purposes, but are not suggested for use in a mission critical, production setting.

  • 4 vCPU
  • 8GB RAM
  • 100GB SSD hard drive
  • CPU with x86 architecture
  • Ubuntu 22.04

Server Configuration

While there are several methods for installing ChirpStack, this guide will demonstrate a configuration using Docker and the chirpstack-docker repository.

Accordingly, on the server intended to run the ChirpStack instance, install Docker using the apt repository on Ubuntu.

Install Docker using the apt repository
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

# Install the latest version:
sudo apt-get install docker-ce docker-ce-cli docker-buildx-plugin docker-compose-plugin

# Verify that the Docker Engine installation is successful by running the hello-world image:
sudo docker run hello-world

Next, clone the chirpstack-docker repository.

Clone the chirpstack-docker repository.
git clone

ChirpStack Port Accessibility

For the configuration described in this guide, the following ports need to be accessible on the server running the ChirpStack instance. In an AWS parlance, a Security Group needs to be attached to the underlying EC2 instance running ChirpStack with inbound rules for the noted ports.

  1. TCP 8080
  • The ChirpStack web UI and gRPC API are accessible over http://<public_ip_address>:8080
  1. UDP 1700
  • As described in further detail below, the chirpstack-gateway-bridge container for the EU868 region binds to UDP 1700. As such, for EU868-based sensor traffic to reach ChirpStack, UDP 1700 needs to be open.
  1. UDP 1701
  • Similarly, the chirpstack-gateway-bridge container for the US915 region binds to UDP 1701. As such, for US915-based sensor traffic to reach ChirpStack, UDP 1701 needs to be open.

Please note that if more chirpstack-gateway-bridge containers are added for additional LoRaWAN regions, the corresponding UDP ports will need to be added in a similar manner to UDP 1700 and 1701.

ChirpStack Configuration

The ChirpStack settings need to be configured so that ChirpStack can operate on the Helium Network. In particular, the chirpstack.toml and docker-compose.yml files, respectively located in the ./chirpstack-docker/configuration/chirpstack/ and ./chirpstack-docker/ directories, need to be updated. Prior to doing so, however, Helium-specific information for the OUI needs to be gathered to be applied in the ChirpStack configuration.

Gather Helium DevAddr Subnet Information for OUI

Use the Helium Config Service CLI to determine the subnet masks for the DevAddr associated with the LNS. In ChirpStack, the subnet masks will be referred to as dev_addr_prefixes.

To do so, first retrieve the DevAddr constraints for the OUI. The relevant values are each of the start_addr and end_addr groups provided in the devaddr_constraints array.

helium-config-service-cli org get --oui <OUI>
Example result from helium-config-service-cli org get --oui command
"org": {
"oui": <OUI>,
"owner": <Owner Public Key>,
"payer": <Payer Public Key>,
"delegate_keys": [
<Deletgate Public Key>
"locked": <Locked status>
"net_id": <Net ID>,
"devaddr_constraints": [
"start_addr": <Starting DevAddr>, // First DevAddr constraint
"end_addr": <Ending DevAddr> // Second DevAddr constraint

Next, using the the start_addr and end_addr values, identify the DevAddr subnet masks, (e.g., labeled as subnets in the returned JSON). If there are multiple, non-contiguous devaddr_constraints, this will need to be done for each set of constraints.

helium-config-service-cli subnet-mask <Starting DevAddr> <Ending DevAddr>
Example result from helium-config-service-cli subnet-mask command
"range": {
"start_addr": <Starting DevAddr>,
"end_addr": <Ending DevAddr>
"subnets": [
<Subnet Mask> // Desired value corresponding to the ChirpStack dev_addr_prefixes

Update chirpstack.toml

Access ./chirpstack-docker/configuration/chirpstack/chirpstack.toml.

Modify the following sections of chirpstack.toml. All other sections can be left as is.

  • Under [network]:
    • Set net_id to the Helium Net ID, 00003C, e.g., net_id="00003C".
    • Add dev_addr_prefixes with the value [<Subnet Mask>], e.g., dev_addr_prefixes=[<Subnet Mask>].
      • As an illustrative example, if the helium-config-service-cli subnet-mask command indicated a subnet mask of 00000000/29, then add dev_addr_prefixes=["00000000/29"].
      • If the OUI has multiple non-sequential DevAddr ranges, separate the corresponding subnet masks by comma. For instance, dev_addr_prefixes=["00000000/29", "00000010/29"].
    • Update the enabled_regions array to include the desired regions.
      • Multiple regions can be enabled simultaneously.
      • Each added region must match the id parameter of the [[regions]] configuration in the corresponding ./chirpstack-docker/configuration/chirpstack/<region>.toml file. In other words, if the id parameter of the [[regions]] configuration is us915_0, add us915_0 to the enabled_regions array.
  • Under [api]:
    • Update the secret value used for generating login and API tokens.
    • Make sure this value is never exposed.
  • Create a new, top level [gateway] section:
    • Below, add allow_unknown_gateways=true

An example of the above-mentioned modified sections of chirpstack.toml is provided below. Please note that the these values are exemplary and need to be filled in with the correct information for your ChirpStack configuration. Again, all other sections in chirpstack.toml can be left as is.

# Network related configuration.

# Network identifier (NetID, 3 bytes) encoded as HEX (e.g. 010203).
# Helium net_id="00003C"

# Helium 8 block dev address prefix 29
# If you have multiple blocks you can add them as an array

# Enabled regions.
# Multiple regions can be enabled simultaneously. Each region must match
# the 'id' parameter of the region configuration in '[[regions]]'.

# API interface configuration.

# Secret.
# This secret is used for generating login and API tokens, make sure this
# is never exposed. Changing this secret will invalidate all login and API
# tokens. The following command can be used to generate a random secret:
# openssl rand -base64 32

# Global gateway configuration.
# Please note that backend configuration can be found in the per-region
# configuration in ./chirpstack-docker/configuration/chirpstack/<region>.toml
# Allow unknown gateways.
# If set to true, then uplinks received from gateways not configured in
# ChirpStack will be allowed.

Update docker-compose.yaml

First, remove the entire service definitions for chirpstack-gateway-bridge-basicstation and chirpstack-rest-api as they are not needed.

Second, visit the ChirpStack Docker Hub Image Repository and identify the most recent version tags for chirpstack and chirpstack-gateway-bridge. At the time of writing this manual, the current version of chirpstack is 4.7 and chirpstack-gateway-bridge was 4.0 so these version will be used moving forward.

Third, update image definitions for chirpstack and chirpstack-gateway-bridge with the most recent version tags found in Docker Hub as noted below:

  • image: chirpstack/chirpstack:4.7
  • image: chirpstack/chirpstack-gateway-bridge:4.0

Fourth, to support every region beyond the default EU868 defined in the enabled_regions noted above in the settings.toml file, add chirpstack-gateway-bridge service definitions for each additional LoRaWAN region. Although this tutorial demonstrates adding support for US915 and EU868 these steps can be adapted for other regions.

To do so, amend the chirpstack-gateway-bridge label to be chirpstack-gateway-bridge-eu868 then create a new service definition for chirpstack-gateway-bridge-us915 as provided below:

image: chirpstack/chirpstack-gateway-bridge:4.0
restart: unless-stopped
- 1701:1700/udp # The chirpstack-gateway-bridge-us915 container will bind to host port 1701
- ./configuration/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge
- INTEGRATION__MQTT__EVENT_TOPIC_TEMPLATE=us915_1/gateway/{{ .GatewayID }}/event/{{ .EventType
- INTEGRATION__MQTT__STATE_TOPIC_TEMPLATE=us915_1/gateway/{{ .GatewayID }}/state/{{ .StateType
- INTEGRATION__MQTT__COMMAND_TOPIC_TEMPLATE=us915_1/gateway/{{ .GatewayID }}/command/#
- mosquitto

See the ChirpStack Gateway Bridge documentation for full description on the configuration possibilities for the chirpstack-gateway-bridge service.

An example of a complete docker-compose.yaml file is provided below:

version: '3'

image: chirpstack/chirpstack:4.7
command: -c /etc/chirpstack
restart: unless-stopped
- ./configuration/chirpstack:/etc/chirpstack
- ./lorawan-devices:/opt/lorawan-devices
- postgres
- mosquitto
- redis
- MQTT_BROKER_HOST=mosquitto
- REDIS_HOST=redis
- 8080:8080

image: chirpstack/chirpstack-gateway-bridge:4.0
restart: unless-stopped
- 1700:1700/udp
- ./configuration/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge
- INTEGRATION__MQTT__EVENT_TOPIC_TEMPLATE=eu868/gateway/{{ .GatewayID }}/event/{{ .EventType
- INTEGRATION__MQTT__STATE_TOPIC_TEMPLATE=eu868/gateway/{{ .GatewayID }}/state/{{ .StateType
- INTEGRATION__MQTT__COMMAND_TOPIC_TEMPLATE=eu868/gateway/{{ .GatewayID }}/command/#
- mosquitto

image: chirpstack/chirpstack-gateway-bridge:4.0
restart: unless-stopped
- 1701:1700/udp
- ./configuration/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge
- INTEGRATION__MQTT__EVENT_TOPIC_TEMPLATE=us915_1/gateway/{{ .GatewayID }}/event/{{ .EventType
- INTEGRATION__MQTT__STATE_TOPIC_TEMPLATE=us915_1/gateway/{{ .GatewayID }}/state/{{ .StateType
- INTEGRATION__MQTT__COMMAND_TOPIC_TEMPLATE=us915_1/gateway/{{ .GatewayID }}/command/#
- mosquitto

image: redis:7-alpine
restart: unless-stopped
command: redis-server --save 300 1 --save 60 100 --appendonly no
- /mnt/particle_chirpstack/redis/data:/data

image: eclipse-mosquitto:2
restart: unless-stopped
- 1883:1883
- ./configuration/mosquitto/config/:/mosquitto/config/

image: postgres:14-alpine
restart: unless-stopped

- ./configuration/postgresql/initdb:/docker-entrypoint-initdb.d
- /mnt/particle_chirpstack/postgresql/data:/var/lib/postgresql/data

Run ChirpStack

From the root of the chirpstack-docker directory, run docker compose up --detach to start the containers defining the ChirpStack instance in the background. Container logs can be accessed by running docker compose logs --follow and the ChirpStack instance can be taken down by running docker compose down

The ChirpStack web UI will now be accessible at http://<public_ip_address>:8080. Utilize the default credentials to log in:

Username: admin
Password: admin

Next Steps

Now that the LNS is operational, proceed to establish routing rules. This ensures that the Helium Network accurately directs device packets to the designated LNS. Learn how to implement this in the Configure Routing Rules guide.