ChirpStack Architecture and Components
ChirpStack provides an open-source LoRaWAN network server stack suitable for both private and public deployments. It exposes gRPC and REST APIs for external integrations and offers a web-based management console. The ecosystem relies on several distinct microservices:
- LoRaWAN Network Server: Manages core MAC layer operations, including device activation, downlink scheduling, and uplink data processing from gateways.
- Application Server: Handles payload decoding, device provisioning, and exposes the user interface alongside integration APIs.
- Gateway Bridge: Translates native gateway packet forwarder protocols into standardized Protobuf/JSON formats compatible with the network server.
- PostgreSQL: Disk-based relational database persisting network configurations, device states, and application metadata.
- Redis: In-memory data store acting as a message broker and high-speed cache for real-time network state tracking.
- Mosquitto: MQTT broker facilitating pub/sub messaging between gateways and the ChirpStack internals.
Docker Compose Deployment
Containerizing ChirpStack isolates dependencies and streamlines multi-service orchestration. A single Compose file defines the entire stack, ensuring consistent environments across development and production.
Environment Setup
Retrieve the version 4 configuration repository:
git clone https://github.com/chirpstack/chirpstack-docker.git -b v4 cs_docker_env
cd cs_docker_env
Compose Configuration
The docker-compose.yml file orchestrates the interconnected services. Customizing frequency plans and port mappings is typically the only required adjustment. Below is a refactored Compose definition mapping the stack to custom local ports and renamed service dependencies:
version: "3.8"
services:
cs_server:
image: chirpstack/chirpstack:4
command: -c /etc/chirpstack
restart: unless-stopped
volumes:
- ./configuration/chirpstack:/etc/chirpstack
- ./lorawan-devices:/opt/lorawan-devices
depends_on:
- cs_db
- cs_mqtt
- cs_cache
environment:
- MQTT_BROKER_HOST=cs_mqtt
- REDIS_HOST=cs_cache
- POSTGRESQL_HOST=cs_db
ports:
- 8888:8080
cs_gateway_bridge:
image: chirpstack/chirpstack-gateway-bridge:4
restart: unless-stopped
ports:
- 1701:1700/udp
volumes:
- ./configuration/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge
environment:
- INTEGRATION__MQTT__EVENT_TOPIC_TEMPLATE=cn470_10/gw/{{ .GatewayID }}/evt/{{ .EventType }}
- INTEGRATION__MQTT__STATE_TOPIC_TEMPLATE=cn470_10/gw/{{ .GatewayID }}/state/{{ .StateType }}
- INTEGRATION__MQTT__COMMAND_TOPIC_TEMPLATE=cn470_10/gw/{{ .GatewayID }}/cmd/#
depends_on:
- cs_mqtt
cs_basicstation_bridge:
image: chirpstack/chirpstack-gateway-bridge:4
restart: unless-stopped
command: -c /etc/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-cn470_10.conf
ports:
- 3002:3001
volumes:
- ./configuration/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge
depends_on:
- cs_mqtt
cs_api:
image: chirpstack/chirpstack-rest-api:4
restart: unless-stopped
command: --server cs_server:8080 --bind 0.0.0.0:8090 --insecure
ports:
- 8091:8090
depends_on:
- cs_server
cs_db:
image: postgres:14-alpine
restart: unless-stopped
volumes:
- ./configuration/postgresql/initdb:/docker-entrypoint-initdb.d
- db_storage:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=changeme
cs_cache:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --save 300 1 --save 60 100 --appendonly no
volumes:
- cache_storage:/data
cs_mqtt:
image: eclipse-mosquitto:2
restart: unless-stopped
ports:
- 1884:1883
volumes:
- ./configuration/mosquitto/config/:/mosquitto/config/
volumes:
db_storage:
cache_storage:
Launching the Stack
docker compose up -d
Web Console Configuration
Access the administration panel via the mapped port (e.g., http://<server-ip>:8888). Default login credentials are admin / admin.
- Gateway Registration: Define a new gateway and record its MAC address, which must align with the physical gateway configuration.
- Device Profiles: Create profiles specifying the LoRaWAN MAC and PHY versions matching your end-device capabilities.
- Application Setup: Construct an application to group devices, configure payload decoders, and establish data integration endpoints.
Resolving Database Volume Conflicts During Upgrades
Replacing containers and images during a version upgrade does not automatically remove named Docker volumes. Orphaned volumes from prior deployments can cause mount conflicts, preventing PostgreSQL and Redis from initializing correctly in the updated stack.
To resolve initialization failures caused by stale data mounts, prune the specific legacy volumes before relaunching the composition:
docker volume rm cs_docker_env_db_storage
docker volume rm cs_docker_env_cache_storage
docker compose up -d