This content originally appeared on DEV Community and was authored by Daniel Jonathan
Run Azure Logic Apps Standard with Service Bus Emulator completely in Docker – zero Azure resources needed.
This guide covers:
Complete Docker setup with memory optimization
Logic Apps configuration for Service Bus
Queue and Topic messaging patterns
SQL filters for message routing
Real working examples (wf4, wf5, wf6, wf7)
Why This Setup?
Fast local development
Zero Azure costs
Works offline
Safe testing environment
Same behavior as Azure Service Bus
Everything containerized
Prerequisites
Docker Memory Configuration
Critical: Service Bus Emulator requires significant memory.
Minimum Requirements:
- Docker Desktop: 15-16GB RAM
- Service Bus container: 8GB
- SQL Server: 2GB
Configure Docker Desktop:
- Open Docker Desktop → Settings → Resources
- Set Memory to 15.6GB or higher
- Click Apply & Restart
Without sufficient memory, the Service Bus emulator will crash with Out of memory errors (exit code 133).
Project Structure
LADevStuff2/ # Logic App project
├── connections.json # Service Bus connection config
├── local.settings.json # Connection strings
├── wf4/
│ └── workflow.json # Queue receiver
├── wf5/
│ └── workflow.json # Topic subscriber (TypeA filter)
├── wf6/
│ └── workflow.json # Topic subscriber (TypeB filter)
└── wf7_sb_send/
└── workflow.json # Message sender
DockerFiles/
├── docker-compose.yml # Container orchestration
└── ServiceBus/
├── Config.json # Queue, Topic, Filters
└── .env # SQL Server credentials
Step 1: Service Bus Configuration
DockerFiles/ServiceBus/Config.json
This defines your Service Bus entities with SQL filters:
{
"UserConfig": {
"Namespaces": [
{
"Name": "sbemulatorns",
"Queues": [
{
"Name": "local-orders-queue",
"Properties": {
"DeadLetteringOnMessageExpiration": false,
"DefaultMessageTimeToLive": "PT1H",
"LockDuration": "PT1M",
"MaxDeliveryCount": 10,
"RequiresDuplicateDetection": false,
"RequiresSession": false
}
}
],
"Topics": [
{
"Name": "local-orders-topic",
"Properties": {
"DefaultMessageTimeToLive": "PT1H",
"RequiresDuplicateDetection": false
},
"Subscriptions": [
{
"Name": "local-orders-sub",
"Properties": {
"DeadLetteringOnMessageExpiration": false,
"DefaultMessageTimeToLive": "PT1H",
"LockDuration": "PT1M",
"MaxDeliveryCount": 10,
"RequiresSession": false
}
},
{
"Name": "wf5-sub",
"Properties": {
"DeadLetteringOnMessageExpiration": false,
"DefaultMessageTimeToLive": "PT1H",
"LockDuration": "PT1M",
"MaxDeliveryCount": 10,
"RequiresSession": false
},
"Rules": [
{
"Name": "TypeAFilter",
"Properties": {
"FilterType": "Sql",
"SqlFilter": {
"SqlExpression": "user.orderType = 'TypeA'"
}
}
}
]
},
{
"Name": "wf6-sub",
"Properties": {
"DeadLetteringOnMessageExpiration": false,
"DefaultMessageTimeToLive": "PT1H",
"LockDuration": "PT1M",
"MaxDeliveryCount": 10,
"RequiresSession": false
},
"Rules": [
{
"Name": "TypeBFilter",
"Properties": {
"FilterType": "Sql",
"SqlFilter": {
"SqlExpression": "user.orderType = 'TypeB'"
}
}
}
]
}
]
}
]
}
],
"Logging": {
"Type": "File"
}
}
}
SQL Filter Syntax: Use
user.propertyNamefor custom properties in filters.
DockerFiles/ServiceBus/.env
ACCEPT_EULA=Y
MSSQL_SA_PASSWORD=StrongPassword123!
Step 2: Docker Compose Setup
DockerFiles/docker-compose.yml
services:
# Azure Storage Emulator
azurite:
image: mcr.microsoft.com/azure-storage/azurite
container_name: azurite-shared
ports:
- "10000:10000" # Blob
- "10001:10001" # Queue
- "10002:10002" # Table
networks:
- shared-network
# SQL Server 2022 (Service Bus backend)
mssql:
container_name: mssql-shared
image: mcr.microsoft.com/mssql/server:2022-latest
platform: linux/amd64
env_file:
- ./ServiceBus/.env
mem_limit: 2g
memswap_limit: 2g
networks:
- shared-network
# Service Bus Emulator
servicebus-emulator:
container_name: servicebus-emulator-shared
platform: linux/amd64
image: mcr.microsoft.com/azure-messaging/servicebus-emulator:latest
pull_policy: always
depends_on:
- mssql
volumes:
- ./ServiceBus/Config.json:/ServiceBus_Emulator/ConfigFiles/Config.json
ports:
- "5672:5672" # AMQP
- "5300:5300" # Management
env_file:
- ./ServiceBus/.env
environment:
SQL_SERVER: mssql
ACCEPT_EULA: Y
mem_limit: 8g
memswap_limit: 8g
shm_size: 2g
networks:
- shared-network
# Logic App Container
logicapp2:
platform: linux/amd64
build:
context: ../LADevStuff2
container_name: logicapp2
ports:
- "7072:7072"
environment:
AzureWebJobsStorage: "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://azurite:10000/devstoreaccount1;QueueEndpoint=http://azurite:10001/devstoreaccount1;TableEndpoint=http://azurite:10002/devstoreaccount1"
WORKFLOWS_STORAGE_PROVIDER: "AzureStorage"
WORKFLOWS_STORAGE_CONNECTION_STRING: "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://azurite:10000/devstoreaccount1;QueueEndpoint=http://azurite:10001/devstoreaccount1;TableEndpoint=http://azurite:10002/devstoreaccount1"
FUNCTIONS_WORKER_RUNTIME: "node"
AzureWebJobsFeatureFlags: "EnableMultiLanguageWorker"
AzureWebJobsSecretStorageType: "Files"
APP_KIND: "workflowapp"
WEBSITE_SITE_NAME: "logicapp-local2"
extra_hosts:
- "localhost:host-gateway"
depends_on:
- azurite
- servicebus-emulator
networks:
- shared-network
networks:
shared-network:
driver: bridge
Key Configuration Notes:
-
mem_limit: 8g– Critical for Service Bus stability -
platform: linux/amd64– Required for Apple Silicon (ARM) Macs -
extra_hosts: localhost:host-gateway– Enables Logic Apps to reach Service Bus emulator - MSSQL Server 2022 – Use this, not SQL Edge (SQL Edge causes crashes)
Step 3: Logic App Configuration
3.1 Connection String Setup
LADevStuff2/local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "node",
"servicebusconnection": "Endpoint=sb://localhost:5672;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;"
}
}
Important: Use
localhost:5672, not the container name, due toextra_hostsconfiguration.
3.2 Service Bus Connection
LADevStuff2/connections.json
Critical: You cannot create Service Bus connections in the Logic App Designer for queues and topics.
Workaround: Manually edit this file:
{
"managedApiConnections": {},
"serviceProviderConnections": {
"serviceBus": {
"parameterValues": {
"connectionString": "@appsetting('servicebusconnection')"
},
"parameterSetName": "connectionString",
"serviceProvider": {
"id": "/serviceProviders/serviceBus"
},
"displayName": "sbConnection"
}
}
}
Then specify queue/topic/subscription names as custom values in your workflow triggers.
Step 4: Workflow Examples
4.1 Message Sender (wf7_sb_send)
LADevStuff2/wf7_sb_send/workflow.json
Key Point:
userProperties.orderTypeis used by SQL filters to route messages.
4.2 SB Receivers (wf4,wf5,wf6)
LADevStuff2/wf4/workflow.json
Note:
queueName,topicName, andsubscriptionNameare specified as custom values in the trigger, not selected from a dropdown.
wf5 : Receives only messages where
user.orderType = 'TypeA'(defined in Config.json)
wf6 : Receives only messages where
user.orderType = 'TypeB'(defined in Config.json)
Step 5: Start Everything
cd DockerFiles
docker compose up -d
Verify Service Bus is running:
docker logs servicebus-emulator-shared --tail 20
Look for:
info: Emulator Service is Successfully Up!
info: Creating queue: local-orders-queue
info: Creating topic: local-orders-topic
info: Entity Sync complete; Operation Result:True
Check all containers:
docker compose ps
All should show status “Up”.
Step 6: Test the Workflows
Send TypeA Order
Making the HTTP Request
Use Postman (or curl) to send a POST request to the wf7_sb_send workflow:
What happens:
-
HTTP POST triggers wf7_sb_send with payload
{"OrderType": "TypeA"} - The workflow sends the message to:
-
Queue:
local-orders-queue(no filtering) -
Topic:
local-orders-topicwith userProperties.orderType = “TypeA”
-
Queue:
- The
userPropertiesfield is what SQL filters use for message routing
Workflow Execution
RunHistory Viewer shows the send workflow successfully completed:

Expected behavior:
wf4 processes message from queue (all messages go here)
wf5 processes message from topic (TypeA filter matches)
wf6 does NOT process (TypeB filter doesn’t match)
Send TypeB Order
Follow the same process as TypeA, but change the payload to:
{ "OrderType": "TypeB" }
Expected behavior:
wf4 processes message from queue (receives all messages)
wf5 does NOT process (TypeA filter doesn’t match)
wf6 processes message from topic (TypeB filter matches)
The SQL filters ensure each workflow only receives messages matching its subscription criteria.
Step 7: Verify Execution
Use the RunHistory Viewer in VS Code to verify workflow executions:
Topic Subscriber (wf5) – TypeA Filter

The screenshot shows the workflow successfully received and processed messages filtered by user.orderType = 'TypeA'.
Queue Receiver (wf4) – All Messages

The screenshot shows the workflow processing all messages from the queue, regardless of message properties.
Key Takeaways
Memory is critical – 15.6GB Docker, 8GB Service Bus, 2GB MSSQL
Use MSSQL Server 2022 – Not SQL Edge
extra_hosts configuration – Required for Docker networking
SQL filters use user. prefix – For custom properties
Manually edit connections.json – Designer doesn’t support queue/topic setup
localhost:5672 connection string – Due to extra_hosts configuration
Rebuild containers – After workflow changes
Summary
You now have a complete local development environment with:
Service Bus Emulator running in Docker
Queue for point-to-point messaging
Topic with SQL-filtered subscriptions for pub/sub
Multiple Logic Apps in containers
Proper memory configuration for stability
Working examples (wf4, wf5, wf6, wf7)
This setup is perfect for:
- Local development and testing
- Learning Logic Apps and Service Bus patterns
- Integration demos
- Offline development
You can later swap the emulator connection string for Azure Service Bus without changing your workflows!
Happy integrating! 

This content originally appeared on DEV Community and was authored by Daniel Jonathan
SQL Filter Syntax: Use
Important: Use 


Note: 