πŸš€ DevOps & SRE Certification Program πŸ“… Starting: 1st of Every Month 🀝 +91 8409492687 πŸ” Contact@DevOpsSchool.com

Upgrade & Secure Your Future with DevOps, SRE, DevSecOps, MLOps!

We spend hours on Instagram and YouTube and waste money on coffee and fast food, but won’t spend 30 minutes a day learning skills to boost our careers.
Master in DevOps, SRE, DevSecOps & MLOps!

Learn from Guru Rajesh Kumar and double your salary in just one year.


Get Started Now!

Step-by-Step Tutorial: Dynamic Container URL Routing using Apache (XAMPP) for Multi-User Laravel App

This tutorial guides you through setting up a multi-user container-based architecture using:

  • Laravel (running on Apache via XAMPP in Ubuntu VM)
  • Docker (to spawn a container for each user)
  • Apache (as a reverse proxy)
  • Domain: wizbrand.com

We’ll configure Apache to dynamically proxy subdomains like user123.wizbrand.com to each user’s container (e.g., port 9123).


🏠 1. Environment Setup

1.1. Prerequisites

  • Ubuntu VM
  • XAMPP (with Apache)
  • Docker installed
  • Laravel app running in XAMPP (htdocs/myapp)

πŸ”§ 2. Laravel: Container Creation Endpoint

Create a route and controller in Laravel to spawn a Docker container and generate a proxy URL.

Example Laravel Controller

public function createUserContainer()
{
    $user = auth()->user();
    $containerName = 'user-' . $user->id;
    $port = 9000 + $user->id;

    // Start Docker container with mapped port
    shell_exec("docker run -d -p $port:80 --name $containerName my-image");

    // Create Apache virtualhost config
    $vhost = "
<VirtualHost *:80>
    ServerName $containerName.wizbrand.com
    ProxyPreserveHost On
    ProxyPass / http://localhost:$port/
    ProxyPassReverse / http://localhost:$port/
</VirtualHost>
    ";

    file_put_contents("/opt/lampp/etc/extra/vhosts/$containerName.conf", $vhost);
    
    // Append hosts file (for local dev only)
    file_put_contents("/etc/hosts", "\n127.0.0.1 $containerName.wizbrand.com", FILE_APPEND);

    // Reload Apache
    shell_exec("sudo /opt/lampp/lampp reloadapache");

    return response()->json(['url' => "http://$containerName.wizbrand.com"]);
}

Replace my-image with your actual Docker image name


🌐 3. Apache Configuration

3.1 Enable Apache Modules

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo systemctl restart apache2  # or /opt/lampp/lampp restart

3.2 Main Apache Config File

Ensure it includes:

# In httpd.conf or extra/httpd-vhosts.conf
IncludeOptional etc/extra/vhosts/*.conf

Create folder:

sudo mkdir /opt/lampp/etc/extra/vhosts

🌎 4. Domain & Local Setup

4.1 Production DNS Setup

  • Add one wildcard DNS record:
*.wizbrand.com β†’ your_server_ip

4.2 Local Development Setup

  • Edit /etc/hosts on host system (your laptop):
127.0.0.1 user-123.wizbrand.com
127.0.0.1 user-456.wizbrand.com

πŸ€– 5. Laravel Route (routes/web.php)

Route::get('/create-container', [ContainerController::class, 'createUserContainer'])->middleware('auth');

πŸ”„ 6. Workflow Summary

  1. User logs into Laravel app
  2. Clicks button to create container
  3. Laravel creates Docker container on a unique port
  4. Laravel generates Apache virtualhost config
  5. Apache proxies userXYZ.wizbrand.com β†’ user’s container
  6. User accesses the unique subdomain URL

πŸš€ Optional Enhancements

  • Use Laravel queue to create containers async
  • Setup SSL (Let’s Encrypt + wildcard)
  • Add container expiry/auto-deletion scheduler
  • Store container info in DB

🚨 Caveats

  • Apache config reload is needed for each new subdomain (downtime may be noticeable)
  • Traefik/Nginx are more scalable but not used here as per your request
  • Ensure ports are not reused across containers

πŸ“Š Tools Used

  • Laravel (PHP Backend)
  • Docker (User environment containers)
  • Apache (Reverse proxy)
  • XAMPP (AMP stack)

πŸŽ“ Conclusion

This setup allows you to offer per-user container environments with unique URLs, using Apache as a reverse proxy without requiring manual DNS records for each user. It’s great for development, testing, or isolated workspaces.

You’re absolutely right β€” the solution I gave does involve creating a new Apache VirtualHost config per container, which works but is not scalable for hundreds of users.

Since you’re looking for a better, scalable approach using Apache only (no Traefik or Nginx), here’s the optimized solution you’re likely aiming for:


βœ… Improved Approach: One Wildcard VirtualHost + Rewrite Rules

Instead of generating a new VirtualHost file for every container/user, we’ll use one single wildcard-based VirtualHost that dynamically reverse-proxies based on the subdomain.


🧠 Concept

Assume:

  • Each user gets a subdomain like user123.wizbrand.com
  • Each container listens on a unique port like 91XXX (e.g., 9123 for user 123)

We’ll use mod_rewrite and mod_proxy to extract the subdomain and map it to the corresponding port dynamically.


πŸ”§ Step-by-Step: Dynamic Apache Reverse Proxy Using Subdomains

βœ… 1. Enable Required Apache Modules

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod rewrite
sudo systemctl restart apache2

βœ… 2. Single Wildcard VirtualHost Configuration

Edit your Apache config (XAMPP: /opt/lampp/etc/extra/httpd-vhosts.conf or Ubuntu default: /etc/apache2/sites-available/000-default.conf):

<VirtualHost *:80>
    ServerName wizbrand.com
    ServerAlias *.wizbrand.com

    ProxyPreserveHost On
    RewriteEngine On

    # Extract username from subdomain (user123)
    RewriteCond %{HTTP_HOST} ^user([0-9]+)\.wizbrand\.com$ [NC]
    RewriteRule ^/(.*)$ http://127.0.0.1:9%1/\ [P,L]

    ProxyPassReverse / http://127.0.0.1/
</VirtualHost>

βœ… This does the magic:

  • Matches user123.wizbrand.com
  • Extracts 123 from the subdomain
  • Proxies to localhost:9123

βœ… 3. Docker Container Port Strategy

Each container should expose port 80 to a host port like 9123.

Example command from Laravel:

$containerName = "user-{$user->id}";
$hostPort = 9000 + $user->id;

shell_exec("docker run -d -p {$hostPort}:80 --name {$containerName} my-image");

βœ… 4. DNS Setup (Production)

In your domain DNS provider (for wizbrand.com), create:

TypeNameValue
A*your_server_ip

This allows *.wizbrand.com to point to your server automatically.


βœ… 5. Local Development (/etc/hosts)

For testing on your local machine or VM:

127.0.0.1 user123.wizbrand.com
127.0.0.1 user456.wizbrand.com

Or use dynamic wildcard resolution services like:

  • nip.io: user123.127.0.0.1.nip.io
  • sslip.io: user123.127.0.0.1.sslip.io

πŸ” Summary: Why This is Better

FeaturePrevious MethodImproved Method βœ…
VHost per userYes ❌No βœ…
Apache reload for each userYes ❌No βœ…
Scalable for 100+ usersNot practical ❌Fully scalable βœ…
Performance-friendlyNo ❌Yes βœ…
Maintains Apache-only setupYes βœ…Yes βœ…

πŸ“˜ Laravel Integration Recap

$port = 9000 + $user->id;
shell_exec("docker run -d -p {$port}:80 --name user-{$user->id} my-image");

return response()->json([
    'url' => "http://user{$user->id}.wizbrand.com"
]);

Subscribe
Notify of
guest


0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

Certification Courses

DevOpsSchool has introduced a series of professional certification courses designed to enhance your skills and expertise in cutting-edge technologies and methodologies. Whether you are aiming to excel in development, security, or operations, these certifications provide a comprehensive learning experience. Explore the following programs:

DevOps Certification, SRE Certification, and DevSecOps Certification by DevOpsSchool

Explore our DevOps Certification, SRE Certification, and DevSecOps Certification programs at DevOpsSchool. Gain the expertise needed to excel in your career with hands-on training and globally recognized certifications.

0
Would love your thoughts, please comment.x
()
x