ChirpStack on Docker Compose | Helium Documentation

On this page

This guide describes using Docker Compose to run ChirpStack in a non-production setting on AWS EC2.

Infrastructure Requirements

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.

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 https://download.docker.com/linux/ubuntu/gpg -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] https://download.docker.com/linux/ubuntu \
  $(. /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 containerd.io 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 https://github.com/chirpstack/chirpstack-docker.git

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
  2. 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.
  3. 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 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.

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]

# Network identifier (NetID, 3 bytes) encoded as HEX (e.g. 010203).

# Helium net_id="00003C"

net_id="00003C"

# Helium 8 block dev address prefix 29

# If you have multiple blocks you can add them as an array

dev_addr_prefixes=[
    "78000000/29"
  ]

# Enabled regions.

# Multiple regions can be enabled simultaneously. Each region must match

# the 'id' parameter of the region configuration in '[[regions]]'.

enabled_regions=[
    "eu868",
    "us915_1"
  ]

# API interface configuration.

[api]

# 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
  secret="REPLACE-WITH-YOUR-SECRET-HERE"

# Global gateway configuration.
# Please note that backend configuration can be found in the per-region
# configuration in ./chirpstack-docker/configuration/chirpstack/<region>.toml
[gateway]

# Allow unknown gateways.

# If set to true, then uplinks received from gateways not configured in
  # ChirpStack will be allowed.
  allow_unknown_gateways=true

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:

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:

chirpstack-gateway-bridge-us915:
  image: chirpstack/chirpstack-gateway-bridge:4.0
  restart: unless-stopped
  ports:
    - 1701:1700/udp # The chirpstack-gateway-bridge-us915 container will bind to host port 1701
  volumes:
    - ./configuration/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge
  environment:
    - 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/#
  depends_on:
    - 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'

services:

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

chirpstack-gateway-bridge-eu868:
    image: chirpstack/chirpstack-gateway-bridge:4.0
    restart: unless-stopped
    ports:
      - 1700:1700/udp
    volumes:
      - ./configuration/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge
    environment:
      - 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/#
    depends_on:
      - mosquitto

chirpstack-gateway-bridge-us915:
    image: chirpstack/chirpstack-gateway-bridge:4.0
    restart: unless-stopped
    ports:
      - 1701:1700/udp
    volumes:
      - ./configuration/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge
    environment:
      - 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/#
    depends_on:
      - mosquitto

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

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

postgres:
    image: postgres:14-alpine
    restart: unless-stopped
    volumes:
      - ./configuration/postgresql/initdb:/docker-entrypoint-initdb.d
      - /mnt/particle_chirpstack/postgresql/data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=root

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 console 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.