📅 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.