- 📅 2025-03-10T14:47:43.959Z
- 👁️ 21 katselukertaa
- 🔓 Julkinen
Orchestrating a Multi-Instance Laravel Application with Custom Domains (customer.product.fi)
Since each customer gets their own Laravel instance with a unique subdomain (customer.product.fi), we need to handle:
1. Automated instance deployment (K3s, Ansible, Helm).
2. Subdomain routing & TLS certificates (Traefik, Nginx).
3. Isolated storage & databases per customer.
4. Automated scaling & updates.
---
1. Architecture Overview
Each customer gets:
✅ A separate Laravel instance (K3s Pod).
✅ A unique subdomain (customer.product.fi).
✅ A dedicated MySQL/PostgreSQL database.
✅ Custom branding (logos, colors, styles).
🛠️ Tech Stack:
K3s (Lightweight Kubernetes) → Deploy Laravel instances.
Helm (K8s package manager) → Manage Laravel configurations.
Ansible (Automation) → Automate new customer instances.
Traefik (Ingress + SSL) → Route traffic for customer.product.fi.
Nix (Package management) → Consistent Laravel environment.
---
2. Dynamic Subdomain Handling (customer.product.fi)
Since each customer has a unique subdomain, we need:
✅ Automatic DNS registration.
✅ Ingress controller to route requests to the correct Laravel instance.
✅ TLS certificates for secure HTTPS (Let's Encrypt).
A. Using Traefik as Ingress Controller
Traefik automatically routes subdomains and handles SSL certificates.
1️⃣ Install Traefik in K3s:
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/main/kubernetes/crds.yaml
kubectl create namespace traefik
kubectl apply -f traefik-deployment.yaml
2️⃣ Create a dynamic Ingress rule (ingress.yaml):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: customer-ingress
namespace: customer1
annotations:
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: customer1.product.fi
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: customer1-laravel
port:
number: 80
tls:
- hosts:
- customer1.product.fi
secretName: customer1-tls
3️⃣ Automate TLS Certificates with Let's Encrypt:
Traefik automatically issues Let's Encrypt certificates for each customer.
Use cert-manager for better certificate handling.
---
3. Automating Laravel Instance Deployment
Each time a new customer signs up, we need to:
✅ Create a new Laravel instance in K3s.
✅ Assign a database & storage.
✅ Configure the correct subdomain (customer.product.fi).
A. Define a Helm Chart for Laravel Instances
Helm allows us to dynamically deploy Laravel per customer.
Example values.yaml template:
replicaCount: 1
image:
repository: myrepo/laravel-app
tag: latest
env:
APP_NAME: "Customer Portal"
APP_URL: "https://{{ .Values.customerName }}.product.fi"
DB_DATABASE: "{{ .Values.customerName }}_db"
DB_USERNAME: "{{ .Values.customerName }}_user"
DB_PASSWORD: "{{ .Values.dbPassword }}"
ingress:
enabled: true
hostname: "{{ .Values.customerName }}.product.fi"
B. Automate New Instance Deployment (Ansible + Helm)
Use Ansible to deploy a new customer instance.
- name: Deploy new Laravel instance for customer
hosts: localhost
tasks:
- name: Create new K8s namespace
command: kubectl create namespace customer-{{ customer_name }}
- name: Deploy Laravel using Helm
command: helm install customer-{{ customer_name }} ./helm-chart --set customerName={{ customer_name }} --set dbPassword={{ db_password }}
✅ Now, when a new customer signs up, Ansible automatically:
1. Creates a new Laravel pod in K3s.
2. Sets up a subdomain (customer.product.fi).
3. Creates a separate database.
4. Routes traffic using Traefik.
---
4. Managing Custom Logos & Styles
Each customer has their own branding (logos, colors).
A. Store Customizations in config/branding.php
Define custom settings per customer:
return [
'logo' => env('CUSTOM_LOGO_URL', '/storage/default-logo.png'),
'theme_color' => env('CUSTOM_THEME_COLOR', '#FF5733'),
];
Then in your Blade templates:
<img src="{{ config('branding.logo') }}" alt="Logo">
<style>
:root { --theme-color: {{ config('branding.theme_color') }}; }
</style>
B. Use Persistent Storage for Customer Logos
Mount persistent volumes in K3s for customer-specific files:
volumeMounts:
- name: customer-storage
mountPath: /var/www/html/storage
volumes:
- name: customer-storage
persistentVolumeClaim:
claimName: customer1-storage
---
5. Database Management for Each Customer
Each customer needs their own MySQL/PostgreSQL database.
A. Use MySQL Operator for Kubernetes
Instead of manually creating databases, use an operator that automatically provisions a DB for each Laravel instance.
apiVersion: mysql.oracle.com/v1alpha1
kind: MySQLDatabase
metadata:
name: customer1-db
spec:
secretName: customer1-db-secret
instanceRef:
name: mysql-instance
✅ When a new customer is created, a new MySQL database is automatically provisioned.
---
6. CI/CD Pipeline for Auto-Scaling Laravel Instances
To automate updates & scaling:
1️⃣ Use GitHub Actions to build Laravel images
2️⃣ Use ArgoCD to deploy new versions to K3s
3️⃣ Use Horizontal Pod Autoscaler (HPA) for scaling
---
Final Workflow:
1. New customer signs up → Ansible triggers new deployment.
2. A new Laravel pod is created in K3s with a unique subdomain.
3. Traefik routes traffic & generates SSL certificates (customer.product.fi).
4. A new MySQL database is provisioned for the customer.
5. Logos, styles, and data are isolated per customer.
6. CI/CD auto-deploys updates without downtime.
✅ Fully automated, scalable, and secure multi-instance Laravel application.