hosting-backend/app/Console/Commands/DeployStaticSite.php
Alexis Bruneteau c813386e18 working
2025-06-04 21:53:28 +02:00

130 lines
3.3 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Symfony\Component\Process\Process;
class DeployStaticSite extends Command
{
protected $signature = 'deploy:static-site {name} {host} {id}';
protected $description = 'Generate K8s manifests, copy files with Ansible, and deploy to cluster';
public function handle()
{
$name = $this->argument('name');
$host = $this->argument('host');
$id = $this->argument('id');
$namespace = 'hosting-deploy';
$kubeDir = storage_path("app/kube/{$name}");
File::ensureDirectoryExists($kubeDir);
// 1. Generate K8s YAMLs
File::put("{$kubeDir}/deployment.yaml", $this->deployment($name,$id, $namespace));
File::put("{$kubeDir}/service.yaml", $this->service($name,$id, $namespace));
File::put("{$kubeDir}/ingress.yaml", $this->ingress($name,$host,$id, $namespace));
$this->info("✅ K8s manifests generated.");
// 2. Run Ansible to copy files and apply kube
$ansiblePlaybook = base_path("ansible/deploy_site.yml");
$process = new Process([
'ansible-playbook',
$ansiblePlaybook,
'-i', base_path('ansible/inventory/hosts.ini'),
'--extra-vars', "sitename={$name}",'--extra-vars', "siteid={$id}"
]);
$process->setTimeout(300);
$process->run(function ($type, $buffer) {
echo $buffer;
});
if ($process->isSuccessful()) {
$this->info("🚀 Site '{$name}' deployed successfully.");
} else {
$this->error("❌ Ansible deployment failed.");
}
}
private function deployment(string $name,string $id, string $namespace): string
{
return <<<YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: {$name}-{$id}-deployment
namespace: {$namespace}
labels:
app: {$name}-{$id}
spec:
replicas: 1
selector:
matchLabels:
app: {$name}-{$id}
template:
metadata:
labels:
app: {$name}-{$id}
spec:
containers:
- name: {$name}-{$id}
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: static-content
mountPath: /usr/share/nginx/html
volumes:
- name: static-content
hostPath:
path: /var/www/{$name}/{$id}
type: Directory
YAML;
}
private function service(string $name, string $id, string $namespace): string
{
return <<<YAML
apiVersion: v1
kind: Service
metadata:
name: {$name}-{$id}-service
namespace: {$namespace}
spec:
selector:
app: {$name}-{$id}
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
YAML;
}
private function ingress(string $name,string $host,string $id, string $namespace): string
{
return <<<YAML
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {$name}-{$id}-ingress
namespace: {$namespace}
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: {$host}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {$name}-{$id}-service
port:
number: 80
YAML;
}
}