feat(Production): Complete production deployment infrastructure

- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
This commit is contained in:
2025-10-25 19:18:37 +02:00
parent caa85db796
commit fc3d7e6357
83016 changed files with 378904 additions and 20919 deletions

View File

@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace App\Framework\Deployment\Ssl\Commands;
use App\Framework\Config\Environment;
use App\Framework\Console\Attributes\ConsoleCommand;
use App\Framework\Console\ConsoleInput;
use App\Framework\Console\ConsoleOutput;
use App\Framework\Console\ExitCode;
use App\Framework\Deployment\Ssl\Services\SslCertificateService;
use App\Framework\Deployment\Ssl\ValueObjects\SslConfiguration;
/**
* Console command to renew SSL certificates
*/
#[ConsoleCommand(
name: 'ssl:renew',
description: 'Renew Let\'s Encrypt SSL certificates'
)]
final readonly class SslRenewCommand
{
public function __construct(
private SslCertificateService $sslService,
private Environment $environment,
private ConsoleOutput $output
) {}
public function execute(ConsoleInput $input): int
{
$this->output->writeln('🔄 Renewing SSL Certificates...');
$this->output->writeln('');
try {
// Load configuration from environment
$config = SslConfiguration::fromEnvironment($this->environment);
$this->output->writeln('Domain: ' . $config->domain->value);
$this->output->writeln('');
// Check current status
$this->output->write('Checking current certificate status... ');
$currentStatus = $this->sslService->getStatus(
$config->domain,
$config->certbotConfDir->toString()
);
if (!$currentStatus->exists) {
$this->output->writeln('❌ Not found');
$this->output->writeln('');
$this->output->writeln('No certificate exists for this domain.');
$this->output->writeln('Run "ssl:init" to obtain a new certificate first.');
return ExitCode::FAILURE;
}
$this->output->writeln('✅ Found');
$this->output->writeln('');
// Display current status
$this->output->writeln('Current Status:');
$this->output->writeln(' Valid Until: ' . $currentStatus->notAfter?->format('Y-m-d H:i:s'));
$this->output->writeln(' Days Until Expiry: ' . $currentStatus->daysUntilExpiry);
$this->output->writeln(' Health: ' . $currentStatus->getHealthStatus());
$this->output->writeln('');
// Check if renewal is needed
if (!$currentStatus->needsRenewal()) {
$this->output->writeln(' Certificate does not need renewal yet.');
$this->output->writeln(' Certificates are automatically renewed 30 days before expiry.');
$this->output->writeln('');
$this->output->writeln('Use --force flag to force renewal anyway (not implemented yet).');
return ExitCode::SUCCESS;
}
// Renew certificate
$this->output->writeln('Renewing certificate...');
$status = $this->sslService->renew($config);
$this->output->writeln('');
$this->output->writeln('✅ Certificate renewed successfully!');
$this->output->writeln('');
// Display new status
$this->output->writeln('New Certificate Information:');
$this->output->writeln(' Valid Until: ' . $status->notAfter?->format('Y-m-d H:i:s'));
$this->output->writeln(' Days Until Expiry: ' . $status->daysUntilExpiry);
$this->output->writeln(' Health: ' . $status->getHealthStatus());
$this->output->writeln('');
$this->output->writeln('Next step: Reload/restart your web server to use the new certificate');
return ExitCode::SUCCESS;
} catch (\Exception $e) {
$this->output->writeln('');
$this->output->writeln('❌ Error: ' . $e->getMessage());
$this->output->writeln('');
return ExitCode::FAILURE;
}
}
}