Skip to content

Instantly share code, notes, and snippets.

@crueber
Last active September 29, 2023 21:33
Show Gist options
  • Save crueber/57330a0d31206398d43e79df9dd4073e to your computer and use it in GitHub Desktop.
Save crueber/57330a0d31206398d43e79df9dd4073e to your computer and use it in GitHub Desktop.
Copy active docker container named volumes to /opt/volumes
const { execSync } = require('child_process');
const readline = require('readline');
function executeCommand(command) {
try {
const result = execSync(command, { encoding: 'utf-8' });
return result.trim();
} catch (error) {
console.error(`Error executing command: ${command}`);
process.exit(1);
}
}
function waitForUserInput() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
return new Promise((resolve) => {
rl.question('Press Enter to continue...', () => {
rl.close();
resolve();
});
});
}
function stopContainer(name) {
const cmd = `docker stop ${name}`;
console.log(cmd);
executeCommand(cmd);
}
function copyVolumeContents(volumeName, dest) {
const cmds = [
`mkdir -p ${dest}`,
`docker run --rm -v ${volumeName}:/source -v ${dest}:/target busybox sh -c "cp -rp /source/. /target/"`
]
console.log(JSON.stringify(cmds,null,2));
cmds.forEach(executeCommand);
}
async function processContainers() {
const containerNames = executeCommand('docker ps --format "{{.Names}}"').split('\n');
const containers = {};
for (const containerName of containerNames) {
const inspectCommand = `docker inspect --format='{{json .Mounts}}' ${containerName}`;
const volumeInfo = executeCommand(inspectCommand);
const mounts = JSON.parse(volumeInfo);
mounts.forEach((mount) => {
if (mount.Type === 'volume') {
const name = containerName.split('_')[0]
const v = mount.Name.split('_')
v.shift()
if (name === 'portainer') return;
if (!containers[name]) containers[name] = [];
const volumeObject = {
container: containerName,
volume: mount.Name,
dest: `/opt/volumes/${name}/${v.join('_')}`,
};
containers[name].push(volumeObject)
}
});
}
console.log(JSON.stringify(containers, null, 2));
for (const shortname of Object.keys(containers)) {
for (const volume of containers[shortname]) {
stopContainer(volume.container);
}
for (const volume of containers[shortname]) {
copyVolumeContents(volume.volume, volume.dest);
}
await waitForUserInput();
}
for (const shortname of Object.keys(containers)) {
for (const volume of containers[shortname]) {
console.log(`docker volume rm ${volume.volume}`)
}
}
}
processContainers()
@crueber
Copy link
Author

crueber commented Sep 28, 2023

The idea here is to essentially go container by container, and as the volumes are all copied over, you can manually bring the containers up with their new volume location before moving on to the next volume.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment