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" }
Note: You can also extension to send simply payloads, refer below gif
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! ππ³





Top comments (0)