DEV Community

Daniel Jonathan
Daniel Jonathan

Posted on

Containerizing Your Logic Apps In Your DevBox

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
Enter fullscreen mode Exit fullscreen mode

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"]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Note: We're using the full connection string with host.docker.internal to connect to the external Azurite storage emulator, which provides better container networking than the simplified UseDevelopmentStorage=true approach.

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: {}
Enter fullscreen mode Exit fullscreen mode

Run with Docker Compose

docker-compose up --build
Enter fullscreen mode Exit fullscreen mode

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: {}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

This returns a JSON response with the master key:

{
  "name": "_master",
  "value": "your-master-key-here"
}
Enter fullscreen mode Exit fullscreen mode

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}"
Enter fullscreen mode Exit fullscreen mode

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!"}'
Enter fullscreen mode Exit fullscreen mode

Visual Walkthrough

Starting Container via Dev Container Extension

Container startup process

Retrieving Master Key and Callback URL

Master key and callback URL retrieval

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"
Enter fullscreen mode Exit fullscreen mode

Check Container Health

# Container status
docker ps

# Resource usage
docker stats my-logicapp
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Container Logs in Action

Container logs monitoring

The logs show the Logic App initialization process, workflow registration, and runtime status.

Top comments (0)