docker_backup_migration
Backup Docker containers, volumes, and projects for migration or disaster recovery. Export projects, manage backup files, and clean up old backups to maintain storage efficiency.
Instructions
Backup containers, volumes, and entire projects for migration
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Backup action | |
| containerName | No | Container name (required for backup_container) | |
| projectName | No | Project name (required for export_project) | |
| backupPath | No | Backup destination path | |
| days | No | Days to keep backups (for cleanup) |
Implementation Reference
- src/index.ts:908-978 (handler)Primary handler function for the docker_backup_migration tool. It processes the input parameters, sets default backup path, and dispatches to specific actions: backup_container (calls DockerBackup.backupContainer), export_project (calls DockerBackup.exportProject), list_backups, cleanup_backups. Returns formatted content or error.async ({ action, containerName, projectName, backupPath, days }) => { try { const defaultBackupPath = "/tmp/docker-backups"; const path = backupPath || defaultBackupPath; switch (action) { case "backup_container": if (!containerName) { throw new Error("Container name is required for backup"); } const backupResult = await DockerBackup.backupContainer(containerName, path); return { content: [ { type: "text", text: `## Container Backup Complete\n\n${backupResult}` } ] }; case "export_project": if (!projectName) { throw new Error("Project name is required for export"); } const exportResult = await DockerBackup.exportProject(projectName, path); return { content: [ { type: "text", text: exportResult } ] }; case "list_backups": const listResult = await executeDockerCommand(`find ${path} -name "*.tar" -o -name "*-config.json" | head -20`); return { content: [ { type: "text", text: `## Available Backups\n\n\`\`\`\n${listResult.stdout || 'No backups found'}\n\`\`\`` } ] }; case "cleanup_backups": const cleanupDays = days || 7; const cleanupResult = await executeDockerCommand(`find ${path} -type f -mtime +${cleanupDays} -delete`); return { content: [ { type: "text", text: `✅ Cleaned up backups older than ${cleanupDays} days from ${path}` } ] }; } } catch (error) { return { content: [ { type: "text", text: `Error with backup/migration: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } }
- src/index.ts:822-892 (helper)DockerBackup class providing helper methods: backupContainer (exports container to tar, saves inspect JSON, backs up volumes using alpine tar), exportProject (gets project resources, calls backupContainer on each, saves metadata JSON). Used by the tool handler.class DockerBackup { static async backupContainer(containerName: string, backupPath: string): Promise<string> { const results: string[] = []; try { // Create backup directory await executeDockerCommand(`mkdir -p ${backupPath}`); // Export container as tar const exportResult = await executeDockerCommand(`docker export ${containerName} > ${backupPath}/${containerName}-backup.tar`); results.push(`✅ Exported container ${containerName} to ${backupPath}/${containerName}-backup.tar`); // Get container config const inspectResult = await executeDockerCommand(`docker inspect ${containerName}`); const configPath = `${backupPath}/${containerName}-config.json`; await executeDockerCommand(`echo '${inspectResult.stdout}' > ${configPath}`); results.push(`✅ Saved container configuration to ${configPath}`); // Backup volumes if any const config = JSON.parse(inspectResult.stdout)[0]; const mounts = config.Mounts || []; for (const mount of mounts) { if (mount.Type === 'volume') { const volumeBackupPath = `${backupPath}/${mount.Name}-volume.tar`; await executeDockerCommand(`docker run --rm -v ${mount.Name}:/volume -v ${backupPath}:/backup alpine tar czf /backup/${mount.Name}-volume.tar -C /volume .`); results.push(`✅ Backed up volume ${mount.Name} to ${volumeBackupPath}`); } } return results.join('\n'); } catch (error) { throw new Error(`Backup failed: ${error instanceof Error ? error.message : String(error)}`); } } static async exportProject(projectName: string, exportPath: string): Promise<string> { const results: string[] = []; const resources = await ProjectManager.getProjectResources(projectName); try { // Create export directory await executeDockerCommand(`mkdir -p ${exportPath}/${projectName}`); // Export each container for (const container of resources.containers) { const containerName = container.Names || container.name; await this.backupContainer(containerName, `${exportPath}/${projectName}`); results.push(`✅ Exported container ${containerName}`); } // Export project metadata const metadata = { projectName, exportDate: new Date().toISOString(), resources: { containers: resources.containers.length, networks: resources.networks.length, volumes: resources.volumes.length } }; await executeDockerCommand(`echo '${JSON.stringify(metadata, null, 2)}' > ${exportPath}/${projectName}/project-metadata.json`); results.push(`✅ Exported project metadata`); return `## Project Export Complete\n\n${results.join('\n')}\n\nProject ${projectName} has been exported to ${exportPath}/${projectName}`; } catch (error) { throw new Error(`Export failed: ${error instanceof Error ? error.message : String(error)}`); } } }
- src/index.ts:900-906 (schema)Zod input schema defining the tool's parameters with descriptions and optionality.inputSchema: { action: z.enum(["backup_container", "export_project", "list_backups", "cleanup_backups"]).describe("Backup action"), containerName: z.string().optional().describe("Container name (required for backup_container)"), projectName: z.string().optional().describe("Project name (required for export_project)"), backupPath: z.string().optional().describe("Backup destination path"), days: z.number().optional().describe("Days to keep backups (for cleanup)") }
- src/index.ts:895-979 (registration)MCP tool registration call that associates the name 'docker_backup_migration' with its schema and handler implementation.server.registerTool( "docker_backup_migration", { title: "Docker Backup and Migration", description: "Backup containers, volumes, and entire projects for migration", inputSchema: { action: z.enum(["backup_container", "export_project", "list_backups", "cleanup_backups"]).describe("Backup action"), containerName: z.string().optional().describe("Container name (required for backup_container)"), projectName: z.string().optional().describe("Project name (required for export_project)"), backupPath: z.string().optional().describe("Backup destination path"), days: z.number().optional().describe("Days to keep backups (for cleanup)") } }, async ({ action, containerName, projectName, backupPath, days }) => { try { const defaultBackupPath = "/tmp/docker-backups"; const path = backupPath || defaultBackupPath; switch (action) { case "backup_container": if (!containerName) { throw new Error("Container name is required for backup"); } const backupResult = await DockerBackup.backupContainer(containerName, path); return { content: [ { type: "text", text: `## Container Backup Complete\n\n${backupResult}` } ] }; case "export_project": if (!projectName) { throw new Error("Project name is required for export"); } const exportResult = await DockerBackup.exportProject(projectName, path); return { content: [ { type: "text", text: exportResult } ] }; case "list_backups": const listResult = await executeDockerCommand(`find ${path} -name "*.tar" -o -name "*-config.json" | head -20`); return { content: [ { type: "text", text: `## Available Backups\n\n\`\`\`\n${listResult.stdout || 'No backups found'}\n\`\`\`` } ] }; case "cleanup_backups": const cleanupDays = days || 7; const cleanupResult = await executeDockerCommand(`find ${path} -type f -mtime +${cleanupDays} -delete`); return { content: [ { type: "text", text: `✅ Cleaned up backups older than ${cleanupDays} days from ${path}` } ] }; } } catch (error) { return { content: [ { type: "text", text: `Error with backup/migration: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } );