matplotlib
torch
+
argocd
tls
+
solidity
+
+
+
nomad
swift
+
+
java
+
+
+
+
sails
https
$
+
+
linux
+
unix
+
+
julia
bash
echo
+
+
+
rubymine
+
hugging
+
next
clion
centos
+
+
weaviate
zig
+
kali
istio
+
+
ฯ€
svelte
cosmos
+
koa
kali
ray
tf
influxdb
!
โˆฉ
http
wasm
vim
+
hapi
choo
s3
+
+
+
+
โ‰ 
gentoo
!!
cdn
py
c#
+
+
weaviate
+
influxdb
+
+
npm
+
yaml
groovy
Back to Blog
๐Ÿš€ Dapr Distributed Application Runtime Setup on AlmaLinux 9: Complete Microservices Platform Guide
AlmaLinux Dapr Microservices

๐Ÿš€ Dapr Distributed Application Runtime Setup on AlmaLinux 9: Complete Microservices Platform Guide

Published Sep 6, 2025

Learn how to install and configure Dapr distributed application runtime on AlmaLinux 9. Step-by-step guide with service invocation, pub/sub messaging, state management, and secrets.

5 min read
0 views
Table of Contents

๐Ÿš€ Dapr Distributed Application Runtime Setup on AlmaLinux 9: Complete Microservices Platform Guide

Welcome to the future of distributed applications! ๐ŸŽ‰ Today weโ€™re going to learn how to set up Dapr on AlmaLinux 9, the amazing Cloud Native Computing Foundation (CNCF) graduated project that makes building microservices as easy as building monoliths. Think of Dapr as your microservices superpower that handles all the complex distributed computing patterns for you! ๐Ÿ’ชโœจ

๐Ÿค” Why is Dapr Important?

Building distributed applications is notoriously difficult, with developers spending more time on infrastructure concerns than business logic. Hereโ€™s why Dapr is revolutionary for modern applications:

  • ๐Ÿ› ๏ธ Building Blocks - Pre-built APIs for service invocation, pub/sub, state management, and secrets
  • ๐Ÿ”„ Platform Agnostic - Works on any cloud, edge, or on-premises environment
  • ๐ŸŽฏ Language Neutral - Use any programming language with simple HTTP or gRPC APIs
  • ๐Ÿ”ง Plug & Play - Swap components without changing application code
  • ๐Ÿ›ก๏ธ Production Ready - Battle-tested by Microsoft, Alibaba, and thousands of companies
  • ๐Ÿ“Š Observable - Built-in metrics, tracing, and logging for distributed systems

๐ŸŽฏ What You Need

Before we start our Dapr adventure, letโ€™s make sure you have everything ready:

โœ… AlmaLinux 9 system (fresh installation recommended)
โœ… Root or sudo access for installing packages
โœ… At least 4GB RAM (8GB recommended for multiple services)
โœ… 10GB free disk space for Docker and Dapr components
โœ… Internet connection for downloading packages and container images
โœ… Basic terminal knowledge (donโ€™t worry, weโ€™ll explain everything!)
โœ… Docker or Podman (weโ€™ll install Docker if needed)
โœ… Programming experience (any language works - weโ€™ll use Python and Node.js for examples)

๐Ÿ“ Step 1: Update Your AlmaLinux System

Letโ€™s start by making sure your system is up to date! ๐Ÿš€

# Update all packages to latest versions
sudo dnf update -y

# Install essential development tools
sudo dnf groupinstall "Development Tools" -y

# Install helpful utilities we'll need
sudo dnf install -y curl wget git vim htop jq python3 python3-pip nodejs npm

Perfect! Your system is now ready for Dapr installation! โœจ

๐Ÿ”ง Step 2: Install Docker and Docker Compose

Dapr works great with containers, so letโ€™s set up Docker:

# Install Docker from official repository
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# Install Docker Engine
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Start and enable Docker service
sudo systemctl start docker
sudo systemctl enable docker

# Add your user to docker group (no more sudo needed!)
sudo usermod -aG docker $USER

# Apply group changes (or logout/login)
newgrp docker

# Test Docker installation
docker --version
docker compose version

Great! Docker is ready for Dapr! ๐Ÿณ

๐ŸŒŸ Step 3: Install Dapr CLI

Letโ€™s install the Dapr command-line interface:

# Download and install Dapr CLI using the official installer
wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash

# Add Dapr CLI to your PATH
echo 'export PATH=$PATH:$HOME/.dapr/bin' >> ~/.bashrc
source ~/.bashrc

# Verify Dapr CLI installation
dapr --version

# You should see output like: CLI version: 1.12.0, Runtime version: n/a

Awesome! Dapr CLI is installed! ๐ŸŽฏ

โœ… Step 4: Initialize Dapr Runtime

Letโ€™s initialize Dapr in self-hosted mode (perfect for development and testing):

# Initialize Dapr runtime with default components
dapr init

# This will:
# - Download Dapr runtime binary
# - Install default components (Redis for state store and pub/sub)
# - Set up Zipkin for observability
# - Configure placement service for actors

# Verify Dapr installation
dapr --version

# Check Dapr containers are running
docker ps

# You should see containers for:
# - dapr_redis (state store and pub/sub)
# - dapr_zipkin (tracing)
# - dapr_placement (actor placement)

Amazing! Dapr runtime is now running on your system! ๐Ÿš€

๐Ÿ”ง Step 5: Create Your First Dapr Application

Letโ€™s build a simple microservice to see Dapr in action:

# Create directory for your first Dapr app
mkdir -p ~/dapr-projects/hello-world
cd ~/dapr-projects/hello-world

# Create a simple Python web service
cat > app.py << 'EOF'
from flask import Flask, request, jsonify
import os
import requests
import json

app = Flask(__name__)

# Dapr port for the app
dapr_port = os.getenv("DAPR_HTTP_PORT", 3500)
dapr_url = f"http://localhost:{dapr_port}"

@app.route('/hello', methods=['POST'])
def hello():
    """Handle incoming service invocation"""
    data = request.get_json()
    
    response = {
        'message': f'Hello {data.get("name", "World")}!',
        'service': 'hello-service',
        'timestamp': '2025-09-06T12:00:00Z'
    }
    
    # Save state using Dapr state store
    try:
        state_data = {
            'key': 'last-greeting',
            'value': response
        }
        
        requests.post(
            f"{dapr_url}/v1.0/state/statestore",
            json=[state_data]
        )
        print(f"โœ… State saved: {response}")
    except Exception as e:
        print(f"โŒ Error saving state: {e}")
    
    return jsonify(response)

@app.route('/greetings', methods=['GET'])
def get_greetings():
    """Get last greeting from state store"""
    try:
        response = requests.get(f"{dapr_url}/v1.0/state/statestore/last-greeting")
        
        if response.status_code == 200 and response.text:
            return jsonify(response.json())
        else:
            return jsonify({'message': 'No greetings found'})
            
    except Exception as e:
        return jsonify({'error': f'Error retrieving state: {e}'}), 500

@app.route('/health', methods=['GET'])
def health():
    """Health check endpoint"""
    return jsonify({'status': 'healthy', 'service': 'hello-service'})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)
EOF

# Create requirements.txt
cat > requirements.txt << 'EOF'
Flask==2.3.3
requests==2.31.0
EOF

# Install Python dependencies
pip3 install -r requirements.txt

# Start the service with Dapr
dapr run --app-id hello-service --app-port 5000 --dapr-http-port 3500 python3 app.py &

# Wait for service to start
sleep 5

# Test the service using Dapr service invocation
curl -X POST http://localhost:3500/v1.0/invoke/hello-service/method/hello \
  -H "Content-Type: application/json" \
  -d '{"name": "Dapr Developer"}'

# Get saved state
curl http://localhost:3500/v1.0/invoke/hello-service/method/greetings

Congratulations! Youโ€™ve built your first Dapr-enabled microservice! ๐ŸŽ‰

๐ŸŒŸ Step 6: Build Multi-Service Application

Letโ€™s create a more complex example with multiple services communicating through Dapr:

# Create a new project for multi-service app
mkdir -p ~/dapr-projects/order-system
cd ~/dapr-projects/order-system

# Create Order Service
mkdir order-service
cat > order-service/app.py << 'EOF'
from flask import Flask, request, jsonify
import requests
import json
import os
from datetime import datetime

app = Flask(__name__)
dapr_port = os.getenv("DAPR_HTTP_PORT", 3501)
dapr_url = f"http://localhost:{dapr_port}"

@app.route('/orders', methods=['POST'])
def create_order():
    """Create a new order"""
    try:
        order_data = request.get_json()
        order_id = f"order-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
        
        order = {
            'id': order_id,
            'customer': order_data.get('customer'),
            'items': order_data.get('items', []),
            'status': 'pending',
            'created_at': datetime.now().isoformat()
        }
        
        # Save order to state store
        state_data = {'key': order_id, 'value': order}
        requests.post(f"{dapr_url}/v1.0/state/statestore", json=[state_data])
        
        # Publish order created event
        event_data = {
            'specversion': '1.0',
            'type': 'order.created',
            'source': 'order-service',
            'id': order_id,
            'data': order
        }
        
        requests.post(
            f"{dapr_url}/v1.0/publish/pubsub/order-events",
            json=event_data
        )
        
        print(f"โœ… Order created: {order_id}")
        return jsonify(order), 201
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/orders/<order_id>', methods=['GET'])
def get_order(order_id):
    """Get order by ID"""
    try:
        response = requests.get(f"{dapr_url}/v1.0/state/statestore/{order_id}")
        
        if response.status_code == 200 and response.text:
            return jsonify(response.json())
        else:
            return jsonify({'error': 'Order not found'}), 404
            
    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5001, debug=True)
EOF

# Create Inventory Service
mkdir inventory-service
cat > inventory-service/app.js << 'EOF'
const express = require('express');
const axios = require('axios');
const app = express();

app.use(express.json());

const daprPort = process.env.DAPR_HTTP_PORT || 3502;
const daprUrl = `http://localhost:${daprPort}`;

// Sample inventory data
let inventory = {
    'laptop': { stock: 10, price: 999.99 },
    'mouse': { stock: 50, price: 29.99 },
    'keyboard': { stock: 25, price: 79.99 }
};

// Dapr subscription configuration
app.get('/dapr/subscribe', (req, res) => {
    res.json([
        {
            pubsubname: 'pubsub',
            topic: 'order-events',
            route: '/handle-order'
        }
    ]);
});

// Handle order events
app.post('/handle-order', async (req, res) => {
    try {
        console.log('๐Ÿ“ฆ Received order event:', req.body);
        
        const orderData = req.body.data;
        const items = orderData.items;
        
        // Check inventory for each item
        let allAvailable = true;
        for (const item of items) {
            if (!inventory[item.product] || inventory[item.product].stock < item.quantity) {
                allAvailable = false;
                break;
            }
        }
        
        // Update order status
        const orderUpdateUrl = `${daprUrl}/v1.0/invoke/order-service/method/orders/${orderData.id}/status`;
        const newStatus = allAvailable ? 'confirmed' : 'rejected';
        
        // In a real app, you'd call the order service to update status
        console.log(`โœ… Order ${orderData.id} ${newStatus}`);
        
        res.status(200).send('OK');
        
    } catch (error) {
        console.error('โŒ Error processing order:', error);
        res.status(500).send('Error processing order');
    }
});

app.get('/inventory', (req, res) => {
    res.json(inventory);
});

app.get('/inventory/:product', (req, res) => {
    const product = req.params.product;
    if (inventory[product]) {
        res.json(inventory[product]);
    } else {
        res.status(404).json({ error: 'Product not found' });
    }
});

const port = 5002;
app.listen(port, () => {
    console.log(`๐Ÿช Inventory service listening on port ${port}`);
});
EOF

# Create package.json for inventory service
cat > inventory-service/package.json << 'EOF'
{
  "name": "inventory-service",
  "version": "1.0.0",
  "description": "Inventory management service",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "axios": "^1.5.0"
  }
}
EOF

# Install Node.js dependencies
cd inventory-service && npm install && cd ..

# Create Dapr component configuration
mkdir components
cat > components/pubsub.yaml << 'EOF'
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: pubsub
spec:
  type: pubsub.redis
  version: v1
  metadata:
  - name: redisHost
    value: localhost:6379
  - name: redisPassword
    value: ""
EOF

# Start both services with Dapr
echo "๐Ÿš€ Starting Order Service..."
dapr run --app-id order-service --app-port 5001 --dapr-http-port 3501 --components-path ./components python3 order-service/app.py &

sleep 3

echo "๐Ÿš€ Starting Inventory Service..."
cd inventory-service
dapr run --app-id inventory-service --app-port 5002 --dapr-http-port 3502 --components-path ../components npm start &
cd ..

sleep 5

# Test the multi-service application
echo "๐Ÿ“ Creating a test order..."
curl -X POST http://localhost:3501/v1.0/invoke/order-service/method/orders \
  -H "Content-Type: application/json" \
  -d '{
    "customer": "John Doe",
    "items": [
      {"product": "laptop", "quantity": 1},
      {"product": "mouse", "quantity": 2}
    ]
  }'

echo -e "\n\n๐Ÿ“ฆ Checking inventory..."
curl http://localhost:3502/v1.0/invoke/inventory-service/method/inventory

Incredible! You now have multiple services communicating through Dapr! ๐ŸŒŸ

๐ŸŽฎ Quick Examples

Letโ€™s explore more Dapr capabilities with practical examples! ๐Ÿš€

Example 1: Secrets Management

# Create secrets component
cat > components/secrets.yaml << 'EOF'
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: local-secrets
spec:
  type: secretstores.local.file
  version: v1
  metadata:
  - name: secretsFile
    value: ./secrets.json
  - name: nestedSeparator
    value: ":"
EOF

# Create secrets file
cat > secrets.json << 'EOF'
{
  "database": {
    "connectionString": "postgres://user:pass@localhost:5432/mydb"
  },
  "api": {
    "key": "super-secret-api-key-12345"
  }
}
EOF

# Create service that uses secrets
cat > secrets-demo.py << 'EOF'
import requests
import json

dapr_url = "http://localhost:3500"

def get_secret(store_name, key):
    """Get secret from Dapr secret store"""
    try:
        response = requests.get(f"{dapr_url}/v1.0/secrets/{store_name}/{key}")
        
        if response.status_code == 200:
            return response.json()
        else:
            print(f"โŒ Error getting secret: {response.status_code}")
            return None
            
    except Exception as e:
        print(f"โŒ Error: {e}")
        return None

# Test secrets retrieval
print("๐Ÿ”‘ Getting database secret...")
db_secret = get_secret("local-secrets", "database")
print(f"Database connection: {db_secret}")

print("๐Ÿ”‘ Getting API secret...")
api_secret = get_secret("local-secrets", "api")
print(f"API key: {api_secret}")
EOF

# Run with Dapr
dapr run --app-id secrets-demo --components-path ./components python3 secrets-demo.py

Now you can securely manage secrets with Dapr! ๐Ÿ”

Example 2: Actor Pattern

# Create actor demo
cat > actor-demo.py << 'EOF'
from flask import Flask, request, jsonify
import requests
import json

app = Flask(__name__)
dapr_url = "http://localhost:3500"

# Counter Actor Implementation
class CounterActor:
    def __init__(self, actor_id):
        self.actor_id = actor_id
        
    def get_state(self, key):
        """Get actor state"""
        response = requests.get(
            f"{dapr_url}/v1.0/actors/CounterActor/{self.actor_id}/state/{key}"
        )
        return response.json() if response.status_code == 200 else 0
    
    def set_state(self, key, value):
        """Set actor state"""
        requests.post(
            f"{dapr_url}/v1.0/actors/CounterActor/{self.actor_id}/state",
            json=[{"key": key, "value": value}]
        )

@app.route('/actors/CounterActor/<actor_id>/method/increment', methods=['POST'])
def increment_counter(actor_id):
    """Increment counter actor"""
    actor = CounterActor(actor_id)
    current_value = actor.get_state('count')
    new_value = current_value + 1
    actor.set_state('count', new_value)
    
    return jsonify({'count': new_value})

@app.route('/actors/CounterActor/<actor_id>/method/get', methods=['GET'])
def get_counter(actor_id):
    """Get current counter value"""
    actor = CounterActor(actor_id)
    current_value = actor.get_state('count')
    
    return jsonify({'count': current_value})

@app.route('/dapr/config', methods=['GET'])
def get_dapr_config():
    """Dapr actor configuration"""
    return jsonify({
        "entities": ["CounterActor"],
        "actorIdleTimeout": "1h",
        "actorScanInterval": "30s"
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5003)
EOF

# Start actor service
dapr run --app-id actor-service --app-port 5003 python3 actor-demo.py &

sleep 3

# Test actors
echo "๐ŸŽญ Testing Actor Pattern..."
curl -X POST http://localhost:3500/v1.0/actors/CounterActor/counter1/method/increment
curl -X POST http://localhost:3500/v1.0/actors/CounterActor/counter1/method/increment
curl http://localhost:3500/v1.0/actors/CounterActor/counter1/method/get

You now understand Daprโ€™s Actor pattern for stateful services! ๐ŸŽญ

Example 3: Kubernetes Deployment

# Create Kubernetes deployment manifests
mkdir k8s-deployment

cat > k8s-deployment/order-service.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
  labels:
    app: order-service
spec:
  replicas: 2
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
      annotations:
        dapr.io/enabled: "true"
        dapr.io/app-id: "order-service"
        dapr.io/app-port: "5001"
    spec:
      containers:
      - name: order-service
        image: order-service:latest
        ports:
        - containerPort: 5001
        env:
        - name: DAPR_HTTP_PORT
          value: "3500"
---
apiVersion: v1
kind: Service
metadata:
  name: order-service
spec:
  selector:
    app: order-service
  ports:
  - protocol: TCP
    port: 80
    targetPort: 5001
  type: ClusterIP
EOF

cat > k8s-deployment/redis-state-store.yaml << 'EOF'
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  version: v1
  metadata:
  - name: redisHost
    value: redis-master:6379
  - name: redisPassword
    secretKeyRef:
      name: redis-secret
      key: password
EOF

echo "โš“ Kubernetes manifests created for Dapr deployment!"

Your services are ready for Kubernetes with Dapr! โš“

๐Ÿšจ Fix Common Problems

Here are solutions to the most common Dapr issues you might encounter:

Problem 1: Dapr Init Failed ๐Ÿ”ง

Symptoms: dapr init command fails or containers donโ€™t start

Solutions:

# Check if Docker is running
docker ps

# If Docker daemon isn't running:
sudo systemctl start docker

# Clean up any partial Dapr installation
dapr uninstall
docker system prune -f

# Re-initialize with specific version
dapr init --runtime-version 1.12.0

# Check Dapr status
dapr status

Problem 2: Service Invocation Timeouts โฐ

Symptoms: HTTP requests to services time out or fail

Solutions:

# Check if services are running
dapr list

# Verify service health
curl http://localhost:3500/v1.0/invoke/your-service/method/health

# Check Dapr logs
dapr logs --app-id your-service

# Increase timeout in your code
requests.post(url, json=data, timeout=30)

Problem 3: Redis Connection Issues ๐Ÿ”—

Symptoms: State store or pub/sub operations fail

Solutions:

# Check Redis container is running
docker ps | grep redis

# Test Redis connectivity
docker exec dapr_redis redis-cli ping

# Restart Redis if needed
docker restart dapr_redis

# Check Redis logs
docker logs dapr_redis

# Use custom Redis configuration
cat > components/redis.yaml << 'EOF'
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  version: v1
  metadata:
  - name: redisHost
    value: localhost:6379
  - name: redisPassword
    value: ""
  - name: connectTimeout
    value: "5s"
EOF

Problem 4: Port Conflicts ๐Ÿšช

Symptoms: โ€œPort already in useโ€ errors when starting services

Solutions:

# Check what's using the port
sudo netstat -tulpn | grep :3500

# Kill process using the port
sudo kill -9 $(sudo lsof -t -i:3500)

# Use different ports for services
dapr run --app-id my-service --dapr-http-port 3501 --app-port 5001 python3 app.py

# Check available ports
ss -tuln | grep -E ":(3500|5000|6379)"

๐Ÿ“‹ Simple Commands Summary

Hereโ€™s your quick reference guide for Dapr:

TaskCommandDescription
Initialize Daprdapr initSet up Dapr runtime locally
Run app with Daprdapr run --app-id myapp --app-port 5000 python app.pyStart service with Dapr sidecar
List running appsdapr listShow all Dapr applications
View logsdapr logs --app-id myappGet application logs
Stop applicationdapr stop --app-id myappStop specific Dapr app
Check Dapr statusdapr statusShow Dapr runtime status
Service invocationcurl localhost:3500/v1.0/invoke/app/method/endpointCall service via Dapr
Pub/Sub publishcurl -X POST localhost:3500/v1.0/publish/pubsub/topicPublish message
Get statecurl localhost:3500/v1.0/state/statestore/keyRetrieve state
Uninstall Daprdapr uninstallRemove Dapr runtime

๐Ÿ’ก Tips for Success

Here are some pro tips to master Dapr distributed applications! ๐ŸŒŸ

๐ŸŽฏ Start Simple: Begin with basic service invocation and state management before moving to advanced patterns like actors or workflows.

โšก Use Building Blocks: Leverage Daprโ€™s building blocks (state, pub/sub, bindings, secrets) instead of implementing these patterns yourself.

๐Ÿ“Š Monitor Everything: Enable tracing with Zipkin or Jaeger, and use Dapr dashboard for development debugging.

๐Ÿ” Component Abstraction: Take advantage of Dapr components to switch between Redis, PostgreSQL, AWS, Azure, etc., without code changes.

๐Ÿ’พ State Consistency: Understand Daprโ€™s state consistency models (eventual vs strong) for your use case requirements.

๐Ÿš€ Scale Gradually: Start with self-hosted mode for development, then move to Kubernetes for production with the same application code.

๐Ÿ”— Service Mesh Integration: Combine Dapr with service meshes like Istio for advanced traffic management and security policies.

๐Ÿ›ก๏ธ Security First: Use Daprโ€™s built-in security features like mTLS, token authentication, and secret management from day one.

๐Ÿ† What You Learned

Congratulations! Youโ€™ve successfully mastered Dapr distributed application runtime! ๐ŸŽ‰ Hereโ€™s everything you accomplished:

โœ… Installed and configured Dapr on AlmaLinux 9 with self-hosted mode
โœ… Built microservices using Daprโ€™s service invocation and state management
โœ… Implemented pub/sub messaging for event-driven architecture
โœ… Created multi-service applications with Python and Node.js
โœ… Managed secrets securely with Dapr secret stores
โœ… Explored Actor pattern for stateful distributed objects
โœ… Prepared Kubernetes deployment with Dapr integration
โœ… Troubleshot common issues and optimized service performance
โœ… Learned production best practices for distributed applications

๐ŸŽฏ Why This Matters

Dapr transforms distributed application development from complex to simple! ๐Ÿš€ You can now:

๐Ÿ› ๏ธ Build Microservices Faster: Focus on business logic instead of infrastructure concerns like service discovery, state management, and pub/sub
โšก Deploy Anywhere: Run the same application code on-premises, in the cloud, or at the edge without modifications
๐Ÿ”„ Switch Components Easily: Change from Redis to PostgreSQL or from local file system to AWS S3 with just configuration changes
๐ŸŒ Scale Globally: Build applications that can scale across multiple clouds and regions with consistent behavior
๐Ÿ“Š Observe Everything: Get built-in metrics, tracing, and logging for all distributed communication without additional code
๐Ÿ›ก๏ธ Secure by Default: Benefit from mTLS, token authentication, and secure secret management out of the box

You now possess cutting-edge distributed systems skills that are essential for modern cloud-native development. Companies like Microsoft, Alibaba, and thousands of others use Dapr in production, making your expertise highly valuable for platform engineering, microservices architecture, and cloud-native development roles! โญ

Keep building distributed applications, keep innovating, and remember - with Dapr, building microservices is as easy as building monoliths! ๐Ÿ™Œโœจ