Overview
In previous article of this series, we covered how to create and develop Logic Apps locally using VS Code. Now we'll focus on containerizing your Logic Apps to enhance your local development experience.
Containerizing Logic Apps makes your local development more consistent, portable, and easier to perform end-to-end testing when you have multiple Logic Apps working together.
Prerequisites
π Before you start: Complete Part 1 of this series where we created Logic Apps with VS Code.
For this containerization tutorial, you'll need:
- Docker Desktop installed and running
- Existing Logic App project (from Part 1)
- Azure Functions Core Tools v4+ (if not already installed)
- Basic Docker knowledge (helpful but not required)
Getting Started
1. Using Your Existing Logic App Project
You should have a Logic App project with this structure:
βββ .vscode/
βββ wf1/ # Your HTTP workflow
β βββ workflow.json
βββ wf2/ # Additional workflows
β βββ workflow.json
βββ wf3/
β βββ workflow.json
βββ workflow-designtime/
βββ Artifacts/
β βββ Maps/
β βββ Rules/
β βββ Schemas/
βββ lib/
βββ connections.json # Blob & Queue connections
βββ host.json
βββ local.settings.json # Azurite configuration
New to Logic Apps? You'll need an existing Logic App project to containerize. Check the prerequisites section above.
2. Containerizing Your Logic App
Now let's containerize your existing Logic App project. Create a Dockerfile in your project root:
# Use .NET SDK 8.0 (works on ARM/x86)
FROM mcr.microsoft.com/dotnet/sdk:8.0
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /home/site/wwwroot
# Install Node 18 LTS and Azure Functions Core Tools v4
RUN apt-get update && \
apt-get install -y curl gnupg unzip coreutils && \
curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \
apt-get install -y nodejs && \
npm install -g azure-functions-core-tools@4 --unsafe-perm=true && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Copy workflows/app files
COPY . .
# Runtime configuration
ENV FUNCTIONS_WORKER_RUNTIME="node"
ENV FUNCTIONS_WORKER_RUNTIME_VERSION="~4"
ENV AzureWebJobsFeatureFlags="EnableMultiLanguageWorker"
ENV AzureWebJobsSecretStorageType="Files"
ENV APP_KIND="workflowapp"
ENV WEBSITE_SITE_NAME="logicapp-local"
# Expose the Functions host port
EXPOSE 7074
# Start the Functions/Logic Apps host
ENTRYPOINT ["func", "start", "--verbose", "--port", "7074"]
3. Build and Run Your Containerized Logic App
Navigate to your Logic App project directory and build the container:
# Navigate to your project directory
cd /Users/danieljonathan/Workspace/LearnDJ/LABlog/LocalLADevVSCode/LADev/LABasicDemo
# Build the Docker image
docker build -t my-logicapp .
# Run with connection to external Azurite container
docker run -p 7074:7074 \
-e AzureWebJobsStorage="DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://host.docker.internal:10000/devstoreaccount1;QueueEndpoint=http://host.docker.internal:10001/devstoreaccount1;TableEndpoint=http://host.docker.internal:10002/devstoreaccount1" \
-e FUNCTIONS_WORKER_RUNTIME="node" \
-e APP_KIND="workflowapp" \
my-logicapp
# Alternative: If Azurite is running in a Docker network
docker run -p 7074:7074 \
--network azurite-network \
-e AzureWebJobsStorage="DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://azurite:10000/devstoreaccount1;QueueEndpoint=http://azurite:10001/devstoreaccount1;TableEndpoint=http://azurite:10002/devstoreaccount1" \
-e FUNCTIONS_WORKER_RUNTIME="node" \
-e APP_KIND="workflowapp" \
my-logicapp
Note: We're using the full connection string with
host.docker.internalto connect to the external Azurite storage emulator, which provides better container networking than the simplifiedUseDevelopmentStorage=trueapproach.
Local Development with Azurite
For local development without Azure costs, use Azurite storage emulator:
docker-compose.yml
version: "3.8"
services:
azurite:
image: mcr.microsoft.com/azure-storage/azurite
ports:
- "10000:10000"
- "10001:10001"
- "10002:10002"
volumes:
- azurite_data:/data
command: azurite --location /data --blobHost 0.0.0.0 --queueHost 0.0.0.0 --tableHost 0.0.0.0
logicapp:
build: .
ports:
- "7074:7074"
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"
APP_KIND: "workflowapp"
depends_on:
- azurite
volumes:
azurite_data: {}
Run with Docker Compose
docker-compose up --build
Multiple Logic Apps Setup
version: "3.8"
services:
azurite:
image: mcr.microsoft.com/azure-storage/azurite
ports:
- "10000:10000"
- "10001:10001"
- "10002:10002"
volumes:
- azurite_data:/data
command: azurite --location /data --blobHost 0.0.0.0 --queueHost 0.0.0.0 --tableHost 0.0.0.0
logicapp1:
build:
context: ./LogicApp1
ports:
- "7074:7074"
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"
WEBSITE_SITE_NAME: "logicapp1"
APP_KIND: "workflowapp"
FUNCTIONS_WORKER_RUNTIME: "node"
depends_on:
- azurite
logicapp2:
build:
context: ./LogicApp2
ports:
- "7075:7074"
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"
WEBSITE_SITE_NAME: "logicapp2"
APP_KIND: "workflowapp"
FUNCTIONS_WORKER_RUNTIME: "node"
depends_on:
- azurite
volumes:
azurite_data: {}
Getting Workflow URLs
1. Get Master Key
Retrieve the master key directly from the Logic App admin endpoint:
# Get the master key from your running Logic App
curl http://localhost:7074/admin/host/systemkeys/_master
This returns a JSON response with the master key:
{
"name": "_master",
"value": "your-master-key-here"
}
2. Get Workflow URL
# Replace {master_key} and {workflow_name} with actual values
curl -X POST "http://localhost:7074/runtime/webhooks/workflow/api/management/workflows/{workflow_name}/triggers/{trigger_actionname}/listCallbackUrl?api-version=2020-05-01-preview&code={master_key}"
3. Test Your Workflow
Use the URL from step 2 to test:
curl -X POST "your_callback_url_here" \
-H "Content-Type: application/json" \
-d '{"message": "Hello Logic App!"}'
Visual Walkthrough
Starting Container via Dev Container Extension
Retrieving Master Key and Callback URL
Why Containerize Your Logic Apps?
β Benefits of Containerized Local Development
- Consistency: Same environment across all team members
-
Easy Setup: Quick start with
docker-compose up - Isolation: No conflicts with other projects
- Portability: Run anywhere Docker is available
- Cost-effective: Use local storage emulator
- Testing: Spin up multiple instances easily
β οΈ Local Development Trade-offs
- Slightly more complex setup compared to direct VS Code development
- Need basic Docker knowledge for troubleshooting
- Container logs vs. direct VS Code debugging experience
- Additional resource usage on your development machine
Debugging Tips
View Container Logs
# Real-time logs
docker logs -f my-logicapp
# Search logs
docker logs my-logicapp | grep "workflow_name"
Check Container Health
# Container status
docker ps
# Resource usage
docker stats my-logicapp
Storage Explorer
- Connect Azure Storage Explorer to Azurite
- View workflow execution data in storage tables
- Monitor blob/queue activity
Common Issues
Container won't start:
- Check Docker logs:
docker logs container_name - Verify storage connection string
- Ensure port isn't already in use
Workflow doesn't trigger:
- Verify master key is correct
- Check workflow URL format
- Validate JSON payload
Performance issues:
- Monitor with
docker stats - Check Azurite logs
- Verify container resources
Quick Commands
# Build and run
docker build -t logicapp . && docker run -p 7074:7074 logicapp
# Run with compose
docker-compose up --build
# View logs
docker logs -f logicapp
# Clean up
docker-compose down -v
docker system prune
Container Logs in Action
The logs show the Logic App initialization process, workflow registration, and runtime status.



Top comments (0)