var Dockerode = require('dockerode'); var async = require('async'); var exec = require('exec'); var path = require('path'); var fs = require('fs'); Docker = {}; Docker.hostIp = null; Docker.hostPort = '2376'; Docker.setHost = function (host) { Docker.hostIp = host; }; Docker.client = function () { var certDir = path.join(process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'], '.boot2docker/certs/boot2docker-vm'); if (!fs.existsSync(certDir)) { return null; } return new Dockerode({ protocol: 'https', host: Docker.hostIp, port: Docker.hostPort, ca: fs.readFileSync(path.join(certDir, 'ca.pem')), cert: fs.readFileSync(path.join(certDir, 'cert.pem')), key: fs.readFileSync(path.join(certDir, 'key.pem')) }); }; Docker.removeContainer = function (containerId, callback) { var container = Docker.client().getContainer(containerId); container.kill(function (err) { if (err) { callback(err); return; } container.remove({v:1}, function (err) { if (err) { callback(err); return; } console.log('Deleted container: ' + containerId); callback(null); }); }); }; Docker.listContainers = function (callback) { Docker.client().listContainers({all: true}, function (err, containers) { if (err) { callback(err, null); } else { var cbList = _.map(containers, function (container) { return function (cb) { Docker.getContainerData(container.Id, function (err, data) { if (err) { cb(err, null); } else { cb(null, data); } }); }; }); async.parallel(cbList, function (err, results) { if (err) { callback(err, null); } else { callback(null, results); } }); } }); }; Docker.getContainerData = function (containerId, callback) { var container = Docker.client().getContainer(containerId); container.inspect(function (err, data) { if (err) { callback(err, null); return; } else { if (data.Config && data.Config.Volumes) { data.Config.Volumes = convertVolumeObjToArray(data.Config.Volumes); } if (data.Volumes) { data.Volumes = convertVolumeObjToArray(data.Volumes); } if (data.VolumesRW) { data.VolumesRW = convertVolumeObjToArray(data.VolumesRW); } callback(null, data); return; } }); }; Docker.runContainer = function (app, image, callback) { var envParam = []; _.each(_.keys(app.config), function (key) { var builtStr = key + '=' + app.config[key]; envParam.push(builtStr); }); var containerOpts = { Image: image.docker.Id, Tty: false, Env: envParam, Hostname: app.name, name: app.name }; if (app.docker && app.docker.NetworkSettings.Ports) { containerOpts.ExposedPorts = app.docker.NetworkSettings.Ports; } console.log(containerOpts); Docker.client().createContainer(containerOpts, function (err, container) { if (err) { callback(err, null); return; } console.log('Created container: ' + container.id); // Bind volumes var binds = []; if (app.volumesEnabled && image.docker.Config.Volumes && image.docker.Config.Volumes.length > 0) { _.each(image.docker.Config.Volumes, function (vol) { binds.push([Util.getHomePath(), 'Kitematic', app.name, vol.Path].join('/') + ':' + vol.Path); }); } var startOpts = { Binds: binds }; if (app.docker && app.docker.NetworkSettings.Ports) { startOpts.PortBindings = app.docker.NetworkSettings.Ports; } else { startOpts.PublishAllPorts = true; } console.log(startOpts); container.start(startOpts, function (err) { if (err) { callback(err, null); return; } console.log('Started container: ' + container.id); callback(null, container); }); }); }; Docker.startContainer = function (containerId, callback) { var container = Docker.client().getContainer(containerId); container.start(function (err) { if (err) { console.log(err); callback(err); return; } console.log('Started container: ' + containerId); callback(null); }); }; Docker.stopContainer = function (containerId, callback) { var container = Docker.client().getContainer(containerId); container.stop(function (err) { if (err) { console.log(err); callback(err); return; } console.log('Stopped container: ' + containerId); callback(null); }); }; var convertVolumeObjToArray = function (obj) { var result = []; if (obj !== null && typeof obj === 'object') { _.each(_.keys(obj), function (key) { var volumeObj = {}; volumeObj.Path = key; volumeObj.Value = obj[key]; result.push(volumeObj); }); } return result; }; Docker.getImageData = function (imageId, callback) { var image = Docker.client().getImage(imageId); image.inspect(function (err, data) { if (err) { callback(err, null); return; } if (data.Config && data.Config.Volumes) { data.Config.Volumes = convertVolumeObjToArray(data.Config.Volumes); } if (data.ContainerConfig && data.ContainerConfig.Volumes) { data.ContainerConfig.Volumes = convertVolumeObjToArray(data.ContainerConfig.Volumes); } callback(null, data); }); }; Docker.listImages = function (opts, callback) { Docker.client().listImages(opts, function (err, images) { if (err) { callback(err, null); } else { var cbList = _.map(images, function (image) { return function (cb) { Docker.getImageData(image.Id, function (err, data) { if (err) { cb(err, null); } else { cb(null, _.extend(image, data)); } }); }; }); async.parallel(cbList, function (err, results) { if (err) { callback(err, null); } else { callback(null, results); } }); } }); }; Docker.removeImage = function (imageId, callback) { var image = Docker.client().getImage(imageId); image.remove({force: true}, function (err) { if (err) { callback(err); return; } console.log('Deleted image: ' + imageId); callback(null); }); };