From 5826a2c26c6f7fad074f82b5453696837ae06a58 Mon Sep 17 00:00:00 2001 From: Juan Felipe Zapata Moreno Date: Fri, 5 Dec 2025 12:58:37 -0600 Subject: [PATCH] =?UTF-8?q?Correci=C3=B3n=20en=20BackupCron=20para=20asegu?= =?UTF-8?q?rar=20la=20creaci=C3=B3n=20del=20directorio=20de=20backup=20y?= =?UTF-8?q?=20manejo=20de=20errores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Commands/BackupCron.php | 70 ++++++++++++++++++++++++----- dockerfile | 1 + 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/app/Console/Commands/BackupCron.php b/app/Console/Commands/BackupCron.php index 74637f1..3c8fba8 100644 --- a/app/Console/Commands/BackupCron.php +++ b/app/Console/Commands/BackupCron.php @@ -17,11 +17,17 @@ public function handle() { $filename = 'backup-' . date('Y-m-d_H-i-s') . '.sql'; $containerPath = '/tmp/' . $filename; - $hostPath = storage_path('app/backup/' . $filename); + $finalPath = storage_path('app/backup/' . $filename); - // Crear backup dentro del contenedor MySQL + // Asegurar que existe el directorio de backup + $backupDir = storage_path('app/backup'); + if (!file_exists($backupDir)) { + mkdir($backupDir, 0755, true); + } + + // Crear backup ejecutando mysqldump dentro del contenedor MySQL $dumpCommand = sprintf( - 'docker exec repuve-backend-v1-mysql-1 sh -c "mysqldump --no-tablespaces -u%s -p%s %s > %s"', + 'docker exec repuve-backend-v1-mysql-1 sh -c "mysqldump --no-tablespaces -u%s -p%s %s > %s" 2>&1', env('DB_USERNAME'), env('DB_PASSWORD'), env('DB_DATABASE'), @@ -29,17 +35,61 @@ public function handle() ); exec($dumpCommand, $output, $returnCode); - // Copiar del contenedor al host + if ($returnCode !== 0) { + $this->error('Error al crear el backup en MySQL'); + $this->error('Código: ' . $returnCode); + if (!empty($output)) { + $this->error('Salida: ' . implode("\n", $output)); + } + return 1; + } + + // Copiar del contenedor MySQL a /tmp del host + $tempHostPath = '/tmp/' . $filename; $copyCommand = sprintf( - 'docker cp repuve-backend-v1-mysql-1:%s %s', + 'docker cp repuve-backend-v1-mysql-1:%s %s 2>&1', $containerPath, - $hostPath + $tempHostPath ); - exec($copyCommand); + exec($copyCommand, $copyOutput, $copyReturnCode); - // Limpiar archivo temporal del contenedor - exec("docker exec repuve-backend-v1-mysql-1 rm " . $containerPath); + if ($copyReturnCode !== 0) { + $this->error('Error al copiar el backup'); + if (!empty($copyOutput)) { + $this->error('Salida: ' . implode("\n", $copyOutput)); + } + return 1; + } - $this->info('Backup creado: ' . $filename); + // Mover de /tmp a storage y establecer permisos + if (file_exists($tempHostPath)) { + rename($tempHostPath, $finalPath); + chmod($finalPath, 0644); + + // Limpiar archivo temporal del contenedor MySQL + exec('docker exec repuve-backend-v1-mysql-1 rm ' . $containerPath); + + $size = filesize($finalPath); + $this->info('Backup creado exitosamente: ' . $filename); + $this->info('Tamaño: ' . $this->formatBytes($size)); + + return 0; + } else { + $this->error('Error: el archivo temporal no se creó'); + return 1; + } + } + + /** + * Formatear bytes a tamaño legible + */ + private function formatBytes($bytes, $precision = 2) + { + $units = ['B', 'KB', 'MB', 'GB']; + $bytes = max($bytes, 0); + $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); + $pow = min($pow, count($units) - 1); + $bytes /= pow(1024, $pow); + return round($bytes, $precision) . ' ' . $units[$pow]; } } diff --git a/dockerfile b/dockerfile index beca185..8bc2b49 100644 --- a/dockerfile +++ b/dockerfile @@ -14,6 +14,7 @@ RUN apk add --no-cache \ nano \ openssl \ bash \ + mysql-client \ && docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip COPY --from=composer:latest /usr/bin/composer /usr/bin/composer