• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Orchestrating Microservices with Docker Swarm and Laravel Octane: A High-Performance, Scalable Architecture for Modern Web Applications

Orchestrating Microservices with Docker Swarm and Laravel Octane: A High-Performance, Scalable Architecture for Modern Web Applications

Docker Swarm Initialization and Node Setup

To orchestrate our Laravel Octane microservices, Docker Swarm provides a robust and integrated solution. We’ll begin by initializing a Swarm on our manager node and then join worker nodes. This setup assumes you have Docker installed on all your machines.

On your designated manager node, execute the following command:

This command initializes a new Swarm and outputs a join token for worker nodes. It’s crucial to secure this token as it grants access to your Swarm.

docker swarm init --advertise-addr 

After initialization, you’ll see output similar to this, including the command to join worker nodes:

Swarm initialized: current node (...) is now a manager.

To add a worker to this Swarm, run the following command:

    docker swarm join --token  :2377

To add a manager to this Swarm, run 'docker swarm join-token manager' and follow the instructions.

On each of your worker nodes, use the provided join token to connect them to the Swarm:

docker swarm join --token  :2377

Verify the nodes are part of the Swarm by running this command on the manager node:

docker node ls

Containerizing Laravel Octane Microservices

Each microservice built with Laravel Octane needs a Dockerfile to define its image. For an Octane-powered application, the key is to ensure the Octane server is running correctly within the container. We’ll use a multi-stage build for efficiency.

Consider a microservice named ‘auth-service’. Its Dockerfile might look like this:

# Stage 1: Build dependencies
FROM php:8.2-fpm AS builder

WORKDIR /var/www/html

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    unzip \
    libzip-dev \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    nginx \
    supervisor \
    && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install gd pdo pdo_mysql zip

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

# Copy application code
COPY . .

# Install dependencies and optimize autoloader
RUN composer install --no-dev --optimize-autoloader

# Pre-register Octane
RUN php artisan octane:install --force
RUN php artisan octane:start --host=0.0.0.0 --port=8000 --workers=4 --max-requests=500 --watch=false

# Stage 2: Production image
FROM php:8.2-fpm

WORKDIR /var/www/html

# Install only necessary runtime dependencies
RUN apt-get update && apt-get install -y \
    libzip4 \
    libpng-dev \
    libjpeg-dev \
    libfreetype6 \
    nginx \
    supervisor \
    && rm -rf /var/lib/apt/lists/*

# Copy PHP extensions from builder stage if needed, or re-install minimal set
RUN docker-php-ext-install pdo pdo_mysql zip

# Copy application code from builder stage
COPY --from=builder /var/www/html /var/www/html

# Copy pre-compiled Octane assets
COPY --from=builder /var/www/html /var/www/html

# Copy Nginx configuration
COPY docker/nginx/app.conf /etc/nginx/sites-available/default
RUN ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

# Copy Supervisor configuration
COPY docker/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# Expose port
EXPOSE 8000

# Start services
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]

You’ll also need a docker/nginx/app.conf and docker/supervisor/supervisord.conf. The Nginx config will proxy requests to the Octane server, and Supervisor will manage the Octane process and Nginx.

Example docker/nginx/app.conf:

server {
    listen 80;
    server_name localhost;
    root /var/www/html/public;

    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        # This part is crucial: proxy to the Octane server
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 60;
        proxy_send_timeout 60;
        proxy_read_timeout 60;
    }

    location ~ /\.ht {
        deny all;
    }
}

Example docker/supervisor/supervisord.conf:

[supervisord]
nodaemon=true
user=root

[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
priority=10
stdout_logfile=/var/log/supervisor/nginx_stdout.log
stderr_logfile=/var/log/supervisor/nginx_stderr.log

[program:octane]
command=php artisan octane:start --host=0.0.0.0 --port=8000 --workers=4 --max-requests=500
autostart=true
autorestart=true
priority=20
stdout_logfile=/var/log/supervisor/octane_stdout.log
stderr_logfile=/var/log/supervisor/octane_stderr.log
user=www-data

After creating the Dockerfile and configuration files for each microservice, build the Docker images:

# Navigate to the microservice directory
cd /path/to/your/auth-service

# Build the image
docker build -t your-dockerhub-username/auth-service:latest .

Push these images to a Docker registry (e.g., Docker Hub, AWS ECR, Google GCR) so Swarm can pull them.

docker push your-dockerhub-username/auth-service:latest

Defining Services with Docker Compose and Swarm Deploy

Docker Swarm utilizes Docker Compose files (version 3+) for defining multi-container applications and their configurations. This file will specify how our microservices should be deployed, scaled, and networked within the Swarm.

Create a docker-compose.yml file for your Swarm. This example defines two services: auth-service and user-service, both running Laravel Octane.

version: '3.8'

services:
  auth-service:
    image: your-dockerhub-username/auth-service:latest
    ports:
      - "8001:80" # Expose on host port 8001
    deploy:
      replicas: 3 # Start with 3 replicas
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure
    networks:
      - app-network

  user-service:
    image: your-dockerhub-username/user-service:latest
    ports:
      - "8002:80" # Expose on host port 8002
    deploy:
      replicas: 2
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure
    networks:
      - app-network

  # Example of a shared database service (e.g., MySQL)
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: your_root_password
      MYSQL_DATABASE: app_db
      MYSQL_USER: app_user
      MYSQL_PASSWORD: app_password
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - app-network

networks:
  app-network:
    driver: overlay
    attachable: true

volumes:
  db_data:
    driver: local

Key elements in this docker-compose.yml:

  • image: Specifies the Docker image to use for the service.
  • ports: Maps host ports to container ports. Note that Swarm will manage port distribution if multiple replicas are running on the same host.
  • deploy: Contains Swarm-specific configurations like the number of replicas, update_config for rolling updates, and restart_policy.
  • networks: Defines overlay networks, essential for inter-service communication in a multi-host Swarm. attachable: true allows standalone containers to join these overlay networks if needed.
  • volumes: For persistent data like databases.

To deploy these services to your Swarm, navigate to the directory containing your docker-compose.yml file on the manager node and run:

docker stack deploy -c docker-compose.yml my-app-stack

This command deploys the services defined in the Compose file as a “stack” named my-app-stack. Swarm will then pull the images and start the specified number of replicas for each service across your cluster nodes.

Service Discovery and Inter-Service Communication

Docker Swarm provides built-in DNS-based service discovery. When you define services in your docker-compose.yml and connect them to an overlay network (like app-network in the example), Swarm automatically assigns a virtual IP address and DNS entry for each service. Other containers on the same overlay network can reach a service using its service name.

For instance, the auth-service can communicate with the user-service by simply using the hostname user-service. Laravel’s configuration can be updated to reflect this.

In your Laravel application’s .env file for the auth-service, you would configure the user service endpoint like this:

# .env for auth-service
APP_URL=http://auth-service:8000 # Or the host port if accessing externally
USER_SERVICE_URL=http://user-service:80 # Assuming user-service exposes port 80 internally

And in the user-service‘s .env:

# .env for user-service
APP_URL=http://user-service:8000
AUTH_SERVICE_URL=http://auth-service:80 # Assuming auth-service exposes port 80 internally

Your Laravel code can then access these services using these environment variables:

use Illuminate\Support\Facades\Http;

// In AuthServiceImpl.php or similar
public function getUserDetails($userId) {
    $userServiceUrl = env('USER_SERVICE_URL');
    $response = Http::get("{$userServiceUrl}/api/users/{$userId}");
    return $response->json();
}

// In UserService.php or similar
public function authenticateUser($credentials) {
    $authServiceUrl = env('AUTH_SERVICE_URL');
    $response = Http::post("{$authServiceUrl}/api/login", $credentials);
    return $response->json();
}

The overlay network ensures that traffic between services is routed efficiently and securely within the Swarm. For external access, you would typically use a load balancer (like HAProxy, Nginx, or a cloud provider’s LB) pointing to the published ports of your services, or deploy a dedicated ingress service within Swarm.

Scaling and Rolling Updates

Docker Swarm excels at managing the lifecycle of your services, including scaling and updates. To scale a service up or down, you can use the docker service scale command.

For example, to scale the auth-service to 5 replicas:

docker service scale my-app-stack_auth-service=5

To scale the user-service down to 1 replica:

docker service scale my-app-stack_user-service=1

Docker Swarm’s rolling update strategy, configured in the docker-compose.yml under deploy.update_config, allows you to update your services with zero downtime. When you update the Docker image for a service and redeploy the stack (using docker stack deploy -c docker-compose.yml my-app-stack again), Swarm will gradually replace old tasks with new ones according to the defined parallelism and delay.

The parallelism: 1 and delay: 10s in the example mean Swarm will update one container at a time, waiting 10 seconds between each update. This ensures that at least one instance of your service is always available.

You can monitor the status of your services and tasks using:

docker service ls
docker service ps my-app-stack_auth-service

Monitoring and Health Checks

Robust monitoring is critical for any production system. Docker Swarm provides basic health checking capabilities. You can define health checks within your Dockerfile or directly in the docker-compose.yml.

A common approach is to have a dedicated health check endpoint in your Laravel application. For example, a route /health that returns a 200 OK status if the application is healthy.

In your Laravel routes (e.g., routes/api.php):

use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Route;

Route::get('/health', function () {
    // Add checks for database connectivity, external service availability, etc.
    // For simplicity, we'll just return OK.
    try {
        // Example: Check database connection
        DB::connection()->getPdo();
        return response()->json(['status' => 'ok', 'message' => 'Application is healthy']);
    } catch (\Exception $e) {
        return response()->json(['status' => 'error', 'message' => 'Database connection failed'], 500);
    }
});

Then, configure this health check in your docker-compose.yml:

services:
  auth-service:
    image: your-dockerhub-username/auth-service:latest
    ports:
      - "8001:80"
    deploy:
      replicas: 3
      # ... other deploy options
    networks:
      - app-network
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider http://localhost:8000/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s # Give Octane time to start up

When a task fails its health check, Docker Swarm will automatically restart it. For more advanced monitoring, consider integrating with external tools like Prometheus and Grafana, which can scrape metrics from your services and provide comprehensive dashboards and alerting.

For logging, ensure your Supervisor configuration directs logs to files within the container. You can then use a log collection agent (like Fluentd, Logstash, or Filebeat) running as a Daemon Service in Swarm to aggregate logs from all nodes to a central location.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Orchestrating Microservices with Docker Swarm and Laravel Octane: A High-Performance, Scalable Architecture for Modern Web Applications
  • Beyond Containers: Orchestrating High-Availability PHP 8 Applications with Kubernetes and Managed Databases
  • Leveraging PHP 8 JIT and Swoole for High-Performance, Event-Driven Laravel Architectures
  • Achieving Sub-Millisecond API Response Times: A Deep Dive into Laravel, Octane, and AWS Lambda with RDS Proxy
  • Leveraging PHP 8/9 JIT and Vector API for High-Performance Microservices with Laravel and Docker Compose

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (664)
  • Desktop Applications (14)
  • DevOps (14)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (7)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (873)
  • Performance & Security Optimization (1)
  • PHP (27)
  • PHP Development (49)
  • Plugins & Themes (244)
  • Programming Languages (10)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (650)
  • SEO & Growth (492)
  • Server (118)
  • Softwares (1)
  • Ubuntu (9)
  • Uncategorized (37)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (26)
  • WordPress Plugin Development (728)
  • WordPress Theme Development (357)

Recent Posts

  • Orchestrating Microservices with Docker Swarm and Laravel Octane: A High-Performance, Scalable Architecture for Modern Web Applications
  • Beyond Containers: Orchestrating High-Availability PHP 8 Applications with Kubernetes and Managed Databases
  • Leveraging PHP 8 JIT and Swoole for High-Performance, Event-Driven Laravel Architectures

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (873)
  • WordPress Plugin Development (728)
  • Debugging & Troubleshooting (664)
  • Security & Compliance (650)
  • SEO & Growth (492)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala