%s" 2>&1', env('DB_USERNAME'), env('DB_PASSWORD'), env('DB_DATABASE'), $containerPath ); exec($dumpCommand, $output, $returnCode); 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 2>&1', $containerPath, $tempHostPath ); exec($copyCommand, $copyOutput, $copyReturnCode); if ($copyReturnCode !== 0) { $this->error('Error al copiar el backup'); if (!empty($copyOutput)) { $this->error('Salida: ' . implode("\n", $copyOutput)); } return 1; } // 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]; } }