/*! dockerui - v0.6.0 - 2015-01-18 * https://github.com/crosbymichael/dockerui * Copyright (c) 2015 Michael Crosby; * Licensed MIT */ angular.module('dockerui', ['dockerui.templates', 'ngRoute', 'dockerui.services', 'dockerui.filters', 'masthead', 'footer', 'dashboard', 'container', 'containers', 'images', 'image', 'startContainer', 'sidebar', 'settings', 'builder', 'containerLogs']) .config(['$routeProvider', function ($routeProvider) { 'use strict'; $routeProvider.when('/', {templateUrl: 'app/components/dashboard/dashboard.html', controller: 'DashboardController'}); $routeProvider.when('/containers/', {templateUrl: 'app/components/containers/containers.html', controller: 'ContainersController'}); $routeProvider.when('/containers/:id/', {templateUrl: 'app/components/container/container.html', controller: 'ContainerController'}); $routeProvider.when('/containers/:id/logs/', {templateUrl: 'app/components/containerLogs/containerlogs.html', controller: 'ContainerLogsController'}); $routeProvider.when('/images/', {templateUrl: 'app/components/images/images.html', controller: 'ImagesController'}); $routeProvider.when('/images/:id/', {templateUrl: 'app/components/image/image.html', controller: 'ImageController'}); $routeProvider.when('/settings', {templateUrl: 'app/components/settings/settings.html', controller: 'SettingsController'}); $routeProvider.otherwise({redirectTo: '/'}); }]) // This is your docker url that the api will use to make requests // You need to set this to the api endpoint without the port i.e. http://192.168.1.9 .constant('DOCKER_ENDPOINT', '/dockerapi') .constant('DOCKER_PORT', '') // Docker port, leave as an empty string if no port is requred. If you have a port, prefix it with a ':' i.e. :4243 .constant('UI_VERSION', 'v0.6.0') .constant('DOCKER_API_VERSION', 'v1.15'); angular.module('builder', []) .controller('BuilderController', ['$scope', 'Dockerfile', 'Messages', function($scope, Dockerfile, Messages) { $scope.template = 'app/components/builder/builder.html'; }]); angular.module('container', []) .controller('ContainerController', ['$scope', '$routeParams', '$location', 'Container', 'Messages', 'ViewSpinner', function($scope, $routeParams, $location, Container, Messages, ViewSpinner) { $scope.changes = []; var update = function() { ViewSpinner.spin(); Container.get({id: $routeParams.id}, function(d) { $scope.container = d; ViewSpinner.stop(); }, function(e) { if (e.status === 404) { $('.detail').hide(); Messages.error("Not found", "Container not found."); } else { Messages.error("Failure", e.data); } ViewSpinner.stop(); }); }; $scope.start = function(){ ViewSpinner.spin(); Container.start({ id: $scope.container.Id, HostConfig: $scope.container.HostConfig }, function(d) { update(); Messages.send("Container started", $routeParams.id); }, function(e) { update(); Messages.error("Failure", "Container failed to start." + e.data); }); }; $scope.stop = function() { ViewSpinner.spin(); Container.stop({id: $routeParams.id}, function(d) { update(); Messages.send("Container stopped", $routeParams.id); }, function(e) { update(); Messages.error("Failure", "Container failed to stop." + e.data); }); }; $scope.kill = function() { ViewSpinner.spin(); Container.kill({id: $routeParams.id}, function(d) { update(); Messages.send("Container killed", $routeParams.id); }, function(e) { update(); Messages.error("Failure", "Container failed to die." + e.data); }); }; $scope.pause = function() { ViewSpinner.spin(); Container.pause({id: $routeParams.id}, function(d) { update(); Messages.send("Container paused", $routeParams.id); }, function(e) { update(); Messages.error("Failure", "Container failed to pause." + e.data); }); }; $scope.unpause = function() { ViewSpinner.spin(); Container.unpause({id: $routeParams.id}, function(d) { update(); Messages.send("Container unpaused", $routeParams.id); }, function(e) { update(); Messages.error("Failure", "Container failed to unpause." + e.data); }); }; $scope.remove = function() { ViewSpinner.spin(); Container.remove({id: $routeParams.id}, function(d) { update(); Messages.send("Container removed", $routeParams.id); }, function(e){ update(); Messages.error("Failure", "Container failed to remove." + e.data); }); }; $scope.hasContent = function(data) { return data !== null && data !== undefined; }; $scope.getChanges = function() { ViewSpinner.spin(); Container.changes({id: $routeParams.id}, function(d) { $scope.changes = d; ViewSpinner.stop(); }); }; update(); $scope.getChanges(); }]); angular.module('containerLogs', []) .controller('ContainerLogsController', ['$scope', '$routeParams', '$location', '$anchorScroll', 'ContainerLogs', 'Container', 'ViewSpinner', function($scope, $routeParams, $location, $anchorScroll, ContainerLogs, Container, ViewSpinner) { $scope.stdout = ''; $scope.stderr = ''; $scope.showTimestamps = false; ViewSpinner.spin(); Container.get({id: $routeParams.id}, function(d) { $scope.container = d; ViewSpinner.stop(); }, function(e) { if (e.status === 404) { Messages.error("Not found", "Container not found."); } else { Messages.error("Failure", e.data); } ViewSpinner.stop(); }); function getLogs() { ContainerLogs.get($routeParams.id, {stdout: 1, stderr: 0, timestamps: $scope.showTimestamps}, function(data, status, headers, config) { // Replace carriage returns twith newlines to clean up output $scope.stdout = data.replace(/[\r]/g, '\n'); }); ContainerLogs.get($routeParams.id, {stdout: 0, stderr: 1}, function(data, status, headers, config) { $scope.stderr = data.replace(/[\r]/g, '\n'); }); } // initial call getLogs(); var logIntervalId = window.setInterval(getLogs, 5000); $scope.$on("$destroy", function(){ // clearing interval when view changes clearInterval(logIntervalId); }); $scope.scrollTo = function(id) { $location.hash(id); $anchorScroll(); }; $scope.toggleTimestamps = function() { getLogs(); }; }]); angular.module('containers', []) .controller('ContainersController', ['$scope', 'Container', 'Settings', 'Messages', 'ViewSpinner', function($scope, Container, Settings, Messages, ViewSpinner) { $scope.predicate = '-Created'; $scope.toggle = false; $scope.displayAll = Settings.displayAll; var update = function(data) { ViewSpinner.spin(); Container.query(data, function(d) { $scope.containers = d.map(function(item) { return new ContainerViewModel(item); }); ViewSpinner.stop(); }); }; var batch = function(items, action, msg) { ViewSpinner.spin(); var counter = 0; var complete = function() { counter = counter -1; if (counter === 0) { ViewSpinner.stop(); update({all: Settings.displayAll ? 1 : 0}); } }; angular.forEach(items, function(c) { if (c.Checked) { counter = counter + 1; action({id: c.Id}, function(d) { Messages.send("Container " + msg, c.Id); var index = $scope.containers.indexOf(c); complete(); }, function(e) { Messages.error("Failure", e.data); complete(); }); } }); if (counter === 0) { ViewSpinner.stop(); } }; $scope.toggleSelectAll = function() { angular.forEach($scope.containers, function(i) { i.Checked = $scope.toggle; }); }; $scope.toggleGetAll = function() { Settings.displayAll = $scope.displayAll; update({all: Settings.displayAll ? 1 : 0}); }; $scope.startAction = function() { batch($scope.containers, Container.start, "Started"); }; $scope.stopAction = function() { batch($scope.containers, Container.stop, "Stopped"); }; $scope.killAction = function() { batch($scope.containers, Container.kill, "Killed"); }; $scope.pauseAction = function() { batch($scope.containers, Container.pause, "Paused"); }; $scope.unpauseAction = function() { batch($scope.containers, Container.unpause, "Unpaused"); }; $scope.removeAction = function() { batch($scope.containers, Container.remove, "Removed"); }; update({all: Settings.displayAll ? 1 : 0}); }]); angular.module('dashboard', []) .controller('DashboardController', ['$scope', 'Container', 'Image', 'Settings', 'LineChart', function($scope, Container, Image, Settings, LineChart) { $scope.predicate = '-Created'; $scope.containers = []; var getStarted = function(data) { $scope.totalContainers = data.length; LineChart.build('#containers-started-chart', data, function(c) { return new Date(c.Created * 1000).toLocaleDateString(); }); var s = $scope; Image.query({}, function(d) { s.totalImages = d.length; LineChart.build('#images-created-chart', d, function(c) { return new Date(c.Created * 1000).toLocaleDateString(); }); }); }; var opts = {animation:false}; if (Settings.firstLoad) { $('#stats').hide(); opts.animation = true; Settings.firstLoad = false; $('#masthead').show(); setTimeout(function() { $('#masthead').slideUp('slow'); $('#stats').slideDown('slow'); }, 5000); } Container.query({all: 1}, function(d) { var running = 0; var ghost = 0; var stopped = 0; for (var i = 0; i < d.length; i++) { var item = d[i]; if (item.Status === "Ghost") { ghost += 1; } else if (item.Status.indexOf('Exit') !== -1) { stopped += 1; } else { running += 1; $scope.containers.push(new ContainerViewModel(item)); } } getStarted(d); var c = new Chart($('#containers-chart').get(0).getContext("2d")); var data = [ { value: running, color: '#5bb75b', title: 'Running' }, // running { value: stopped, color: '#C7604C', title: 'Stopped' }, // stopped { value: ghost, color: '#E2EAE9', title: 'Ghost' } // ghost ]; c.Doughnut(data, opts); var lgd = $('#chart-legend').get(0); legend(lgd, data); }); }]); angular.module('footer', []) .controller('FooterController', ['$scope', 'Settings', function($scope, Settings) { $scope.template = 'app/components/footer/statusbar.html'; $scope.uiVersion = Settings.uiVersion; $scope.apiVersion = Settings.version; }]); angular.module('image', []) .controller('ImageController', ['$scope', '$q', '$routeParams', '$location', 'Image', 'Container', 'Messages', 'LineChart', function($scope, $q, $routeParams, $location, Image, Container, Messages, LineChart) { $scope.history = []; $scope.tag = {repo: '', force: false}; $scope.remove = function() { Image.remove({id: $routeParams.id}, function(d) { Messages.send("Image Removed", $routeParams.id); }, function(e) { $scope.error = e.data; $('#error-message').show(); }); }; $scope.getHistory = function() { Image.history({id: $routeParams.id}, function(d) { $scope.history = d; }); }; $scope.updateTag = function() { var tag = $scope.tag; Image.tag({id: $routeParams.id, repo: tag.repo, force: tag.force ? 1 : 0}, function(d) { Messages.send("Tag Added", $routeParams.id); }, function(e) { $scope.error = e.data; $('#error-message').show(); }); }; function getContainersFromImage($q, Container, tag) { var defer = $q.defer(); Container.query({all:1, notruc:1}, function(d) { var containers = []; for (var i = 0; i < d.length; i++) { var c = d[i]; if (c.Image === tag) { containers.push(new ContainerViewModel(c)); } } defer.resolve(containers); }); return defer.promise; } Image.get({id: $routeParams.id}, function(d) { $scope.image = d; $scope.tag = d.id; var t = $routeParams.tag; if (t && t !== ":") { $scope.tag = t; var promise = getContainersFromImage($q, Container, t); promise.then(function(containers) { LineChart.build('#containers-started-chart', containers, function(c) { return new Date(c.Created * 1000).toLocaleDateString(); }); }); } }, function(e) { if (e.status === 404) { $('.detail').hide(); $scope.error = "Image not found.
" + $routeParams.id; } else { $scope.error = e.data; } $('#error-message').show(); }); $scope.getHistory(); }]); angular.module('images', []) .controller('ImagesController', ['$scope', 'Image', 'ViewSpinner', 'Messages', function($scope, Image, ViewSpinner, Messages) { $scope.toggle = false; $scope.predicate = '-Created'; $scope.showBuilder = function() { $('#build-modal').modal('show'); }; $scope.removeAction = function() { ViewSpinner.spin(); var counter = 0; var complete = function() { counter = counter - 1; if (counter === 0) { ViewSpinner.stop(); } }; angular.forEach($scope.images, function(i) { if (i.Checked) { counter = counter + 1; Image.remove({id: i.Id}, function(d) { angular.forEach(d, function(resource) { Messages.send("Image deleted", resource.Deleted); }); var index = $scope.images.indexOf(i); $scope.images.splice(index, 1); complete(); }, function(e) { Messages.error("Failure", e.data); complete(); }); } }); }; $scope.toggleSelectAll = function() { angular.forEach($scope.images, function(i) { i.Checked = $scope.toggle; }); }; ViewSpinner.spin(); Image.query({}, function(d) { $scope.images = d.map(function(item) { return new ImageViewModel(item); }); ViewSpinner.stop(); }, function (e) { Messages.error("Failure", e.data); ViewSpinner.stop(); }); }]); angular.module('masthead', []) .controller('MastheadController', ['$scope', function($scope) { $scope.template = 'app/components/masthead/masthead.html'; }]); angular.module('settings', []) .controller('SettingsController', ['$scope', 'System', 'Docker', 'Settings', 'Messages', function($scope, System, Docker, Settings, Messages) { $scope.info = {}; $scope.docker = {}; $scope.endpoint = Settings.endpoint; $scope.apiVersion = Settings.version; Docker.get({}, function(d) { $scope.docker = d; }); System.get({}, function(d) { $scope.info = d; }); }]); angular.module('sidebar', []) .controller('SideBarController', ['$scope', 'Container', 'Settings', function($scope, Container, Settings) { $scope.template = 'partials/sidebar.html'; $scope.containers = []; $scope.endpoint = Settings.endpoint; Container.query({all: 0}, function(d) { $scope.containers = d; }); }]); angular.module('startContainer', []) .controller('StartContainerController', ['$scope', '$routeParams', '$location', 'Container', 'Messages', function($scope, $routeParams, $location, Container, Messages) { $scope.template = 'app/components/startContainer/startcontainer.html'; $scope.config = { name: '', memory: 0, memorySwap: 0, cpuShares: 1024, env: '', commands: '', volumesFrom: '' }; $scope.commandPlaceholder = '["/bin/echo", "Hello world"]'; function failedRequestHandler(e, Messages) { Messages.send({class: 'text-error', data: e.data}); } $scope.create = function() { var cmds = null; if ($scope.config.commands !== '') { cmds = angular.fromJson($scope.config.commands); } var id = $routeParams.id; var ctor = Container; var loc = $location; var s = $scope; Container.create({ Image: id, name: $scope.config.name, Memory: $scope.config.memory, MemorySwap: $scope.config.memorySwap, CpuShares: $scope.config.cpuShares, Cmd: cmds, VolumesFrom: $scope.config.volumesFrom }, function(d) { if (d.Id) { ctor.start({id: d.Id}, function(cd) { $('#create-modal').modal('hide'); loc.path('/containers/' + d.Id + '/'); }, function(e) { failedRequestHandler(e, Messages); }); } else { failedRequestHandler(d, Messages); } }, function(e) { failedRequestHandler(e, Messages); }); }; }]); angular.module('dockerui.filters', []) .filter('truncate', function() { 'use strict'; return function(text, length, end) { if (isNaN(length)) { length = 10; } if (end === undefined){ end = '...'; } if (text.length <= length || text.length - end.length <= length) { return text; } else { return String(text).substring(0, length - end.length) + end; } }; }) .filter('statusbadge', function() { 'use strict'; return function(text) { if (text === 'Ghost') { return 'important'; } else if (text.indexOf('Exit') !== -1 && text !== 'Exit 0') { return 'warning'; } return 'success'; }; }) .filter('getstatetext', function() { 'use strict'; return function(state) { if (state === undefined) { return ''; } if (state.Ghost && state.Running) { return 'Ghost'; } if (state.Running && state.Paused) { return 'Running (Paused)'; } if (state.Running) { return 'Running'; } return 'Stopped'; }; }) .filter('getstatelabel', function() { 'use strict'; return function(state) { if (state === undefined) { return ''; } if (state.Ghost && state.Running) { return 'label-important'; } if (state.Running) { return 'label-success'; } return ''; }; }) .filter('humansize', function() { 'use strict'; return function(bytes) { var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; if (bytes === 0) { return 'n/a'; } var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10); return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[[i]]; }; }) .filter('containername', function() { 'use strict'; return function(container) { var name = container.Names[0]; return name.substring(1, name.length); }; }) .filter('repotag', function() { 'use strict'; return function(image) { if (image.RepoTags && image.RepoTags.length > 0) { var tag = image.RepoTags[0]; if (tag === ':') { tag = ''; } return tag; } return ''; }; }) .filter('getdate', function() { 'use strict'; return function(data) { //Multiply by 1000 for the unix format var date = new Date(data * 1000); return date.toDateString(); }; }); angular.module('dockerui.services', ['ngResource']) .factory('Container', function($resource, Settings) { 'use strict'; // Resource for interacting with the docker containers // http://docs.docker.io/en/latest/api/docker_remote_api.html#containers return $resource(Settings.url + '/containers/:id/:action', { name: '@name' }, { query: {method: 'GET', params:{ all: 0, action: 'json'}, isArray: true}, get: {method: 'GET', params: { action:'json'}}, start: {method: 'POST', params: {id: '@id', action: 'start'}}, stop: {method: 'POST', params: {id: '@id', t: 5, action: 'stop'}}, restart: {method: 'POST', params: {id: '@id', t: 5, action: 'restart' }}, kill: {method: 'POST', params: {id: '@id', action: 'kill'}}, pause: {method: 'POST', params: {id: '@id', action: 'pause'}}, unpause: {method: 'POST', params: {id: '@id', action: 'unpause'}}, changes: {method: 'GET', params: {action:'changes'}, isArray: true}, create: {method: 'POST', params: {action:'create'}}, remove: {method: 'DELETE', params: {id: '@id', v:0}} }); }) .factory('ContainerLogs', function($resource, $http, Settings) { 'use strict'; return { get: function(id, params, callback) { $http({ method: 'GET', url: Settings.url + '/containers/'+id+'/logs', params: {'stdout': params.stdout || 0, 'stderr': params.stderr || 0, 'timestamps': params.timestamps || 0, 'tail': params.tail || 'all'} }).success(callback).error(function(data, status, headers, config) { console.log(error, data); }); } }; }) .factory('Image', function($resource, Settings) { 'use strict'; // Resource for docker images // http://docs.docker.io/en/latest/api/docker_remote_api.html#images return $resource(Settings.url + '/images/:id/:action', {}, { query: {method: 'GET', params:{ all: 0, action: 'json'}, isArray: true}, get: {method: 'GET', params: { action:'json'}}, search: {method: 'GET', params: { action:'search'}}, history: {method: 'GET', params: { action:'history'}, isArray: true}, create: {method: 'POST', params: {action:'create'}}, insert: {method: 'POST', params: {id: '@id', action:'insert'}}, push: {method: 'POST', params: {id: '@id', action:'push'}}, tag: {method: 'POST', params: {id: '@id', action:'tag', force: 0, repo: '@repo'}}, remove: {method: 'DELETE', params: {id: '@id'}, isArray: true} }); }) .factory('Docker', function($resource, Settings) { 'use strict'; // Information for docker // http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information return $resource(Settings.url + '/version', {}, { get: {method: 'GET'} }); }) .factory('Auth', function($resource, Settings) { 'use strict'; // Auto Information for docker // http://docs.docker.io/en/latest/api/docker_remote_api.html#set-auth-configuration return $resource(Settings.url + '/auth', {}, { get: {method: 'GET'}, update: {method: 'POST'} }); }) .factory('System', function($resource, Settings) { 'use strict'; // System for docker // http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information return $resource(Settings.url + '/info', {}, { get: {method: 'GET'} }); }) .factory('Settings', function(DOCKER_ENDPOINT, DOCKER_PORT, DOCKER_API_VERSION, UI_VERSION) { 'use strict'; var url = DOCKER_ENDPOINT; if (DOCKER_PORT) { url = url + DOCKER_PORT + '\\' + DOCKER_PORT; } return { displayAll: false, endpoint: DOCKER_ENDPOINT, version: DOCKER_API_VERSION, rawUrl: DOCKER_ENDPOINT + DOCKER_PORT + '/' + DOCKER_API_VERSION, uiVersion: UI_VERSION, url: url, firstLoad: true }; }) .factory('ViewSpinner', function() { 'use strict'; var spinner = new Spinner(); var target = document.getElementById('view'); return { spin: function() { spinner.spin(target); }, stop: function() { spinner.stop(); } }; }) .factory('Messages', function($rootScope) { 'use strict'; return { send: function(title, text) { $.gritter.add({ title: title, text: text, time: 2000, before_open: function() { if($('.gritter-item-wrapper').length === 3) { return false; } } }); }, error: function(title, text) { $.gritter.add({ title: title, text: text, time: 6000, before_open: function() { if($('.gritter-item-wrapper').length === 4) { return false; } } }); } }; }) .factory('Dockerfile', function(Settings) { 'use strict'; var url = Settings.rawUrl + '/build'; return { build: function(file, callback) { var data = new FormData(); var dockerfile = new Blob([file], { type: 'text/text' }); data.append('Dockerfile', dockerfile); var request = new XMLHttpRequest(); request.onload = callback; request.open('POST', url); request.send(data); } }; }) .factory('LineChart', function(Settings) { 'use strict'; var url = Settings.rawUrl + '/build'; return { build: function(id, data, getkey){ var chart = new Chart($(id).get(0).getContext("2d")); var map = {}; for (var i = 0; i < data.length; i++) { var c = data[i]; var key = getkey(c); var count = map[key]; if (count === undefined) { count = 0; } count += 1; map[key] = count; } var labels = []; data = []; var keys = Object.keys(map); for (i = keys.length - 1; i > -1; i--) { var k = keys[i]; labels.push(k); data.push(map[k]); } var dataset = { fillColor : "rgba(151,187,205,0.5)", strokeColor : "rgba(151,187,205,1)", pointColor : "rgba(151,187,205,1)", pointStrokeColor : "#fff", data : data }; chart.Line({ labels: labels, datasets: [dataset] }, { scaleStepWidth: 1, pointDotRadius:1, scaleOverride: true, scaleSteps: labels.length }); } }; }); function ImageViewModel(data) { this.Id = data.Id; this.Tag = data.Tag; this.Repository = data.Repository; this.Created = data.Created; this.Checked = false; this.RepoTags = data.RepoTags; this.VirtualSize = data.VirtualSize; } function ContainerViewModel(data) { this.Id = data.Id; this.Image = data.Image; this.Command = data.Command; this.Created = data.Created; this.SizeRw = data.SizeRw; this.Status = data.Status; this.Checked = false; this.Names = data.Names; } angular.module('dockerui.templates', ['app/components/builder/builder.html', 'app/components/container/container.html', 'app/components/containerLogs/containerlogs.html', 'app/components/containers/containers.html', 'app/components/dashboard/dashboard.html', 'app/components/footer/statusbar.html', 'app/components/image/image.html', 'app/components/images/images.html', 'app/components/masthead/masthead.html', 'app/components/settings/settings.html', 'app/components/sidebar/sidebar.html', 'app/components/startContainer/startcontainer.html']); angular.module("app/components/builder/builder.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/builder/builder.html", "
\n" + "
\n" + "
\n" + "
\n" + " \n" + "

Build Image

\n" + "
\n" + "
\n" + "
\n" + "

{{ messages }}

\n" + "
\n" + "
\n" + " Build\n" + "
\n" + "
\n" + "
\n" + "
\n" + ""); }]); angular.module("app/components/container/container.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/container/container.html", "
\n" + " \n" + "

Container: {{ container.Name }}

\n" + "\n" + "
\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
Created:{{ container.Created }}
Path:{{ container.Path }}
Args:{{ container.Args }}
Exposed Ports:\n" + "
    \n" + "
  • {{ k }}
  • \n" + "
\n" + "
Environment:\n" + "
    \n" + "
  • {{ k }}
  • \n" + "
\n" + "
Publish All:{{ container.HostConfig.PublishAllPorts }}
Ports:\n" + "
    \n" + "
  • \n" + " {{ containerport }} => {{ v.HostIp }}:{{ v.HostPort }}\n" + "
  • \n" + "
\n" + "
Hostname:{{ container.Config.Hostname }}
IPAddress:{{ container.NetworkSettings.IPAddress }}
Cmd:{{ container.Config.Cmd }}
Entrypoint:{{ container.Config.Entrypoint }}
Volumes:{{ container.Volumes }}
SysInitpath:{{ container.SysInitPath }}
Image:{{ container.Image }}
State:{{ container.State|getstatetext }}
Logs:stdout/stderr
\n" + " \n" + "
\n" + "
\n" + " Changes:\n" + "
\n" + "
\n" + " \n" + "
\n" + "
\n" + "\n" + "
\n" + "
    \n" + "
  • \n" + " {{ change.Path }} {{ change.Kind }}\n" + "
  • \n" + "
\n" + "
\n" + "\n" + "
\n" + "\n" + "
\n" + " \n" + "
\n" + "
\n" + ""); }]); angular.module("app/components/containerLogs/containerlogs.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/containerLogs/containerlogs.html", "
\n" + "
\n" + "

Logs for container: {{ container.Name }}

\n" + "
\n" + " \n" + " \n" + "
\n" + "
\n" + " \n" + "
\n" + "
\n" + "\n" + "
\n" + "
\n" + "
\n" + "

STDOUT

\n" + "
\n" + "
\n" + "
{{stdout}}
\n" + "
\n" + "
\n" + "
\n" + "
\n" + "
\n" + "
\n" + "

STDERR

\n" + "
\n" + "
\n" + "
{{stderr}}
\n" + "
\n" + "
\n" + "
\n" + "
\n" + ""); }]); angular.module("app/components/containers/containers.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/containers/containers.html", "\n" + "

Containers:

\n" + "\n" + "
\n" + " \n" + "\n" + "
\n" + " Display All\n" + "
\n" + "
\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
ActionNameImageCommandCreatedStatus
{{ container|containername}}{{ container.Image }}{{ container.Command|truncate:40 }}{{ container.Created|getdate }}{{ container.Status }}
\n" + ""); }]); angular.module("app/components/dashboard/dashboard.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/dashboard/dashboard.html", " \n" + "
\n" + " \n" + "
\n" + "
\n" + "
\n" + "

DockerUI

\n" + "

The Linux container engine

\n" + " Learn more.\n" + "
\n" + "
\n" + "
\n" + " \n" + "
\n" + "
\n" + "
\n" + "

Running Containers

\n" + " \n" + "
\n" + "
\n" + "

Status

\n" + " \n" + " Get a better browser... Your holding everyone back.\n" + " \n" + "
\n" + "
\n" + "
\n" + "
\n" + "\n" + "
\n" + "
\n" + "

Containers created

\n" + " \n" + " Get a better browser... You're holding everyone back.\n" + " \n" + "

Images created

\n" + " \n" + " Get a better browser... You're holding everyone back.\n" + " \n" + "
\n" + "
\n" + "
\n" + ""); }]); angular.module("app/components/footer/statusbar.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/footer/statusbar.html", "
\n" + "

Docker API Version: {{ apiVersion }} UI Version: {{ uiVersion }} dockerui

\n" + "
\n" + ""); }]); angular.module("app/components/image/image.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/image/image.html", "
\n" + "\n" + "
\n" + " {{ error }}\n" + "
\n" + "\n" + "
\n" + " \n" + "

Image: {{ tag }}

\n" + "\n" + "
\n" + " \n" + "
\n" + "\n" + "
\n" + "

Containers created:

\n" + " \n" + " Get a better broswer... Your holding everyone back.\n" + " \n" + "
\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + "
Created:{{ image.created }}
Parent:{{ image.parent }}
Size:{{ image.Size|humansize }}
Hostname:{{ image.container_config.Hostname }}
User:{{ image.container_config.User }}
Cmd:{{ image.container_config.Cmd }}
Volumes:{{ image.container_config.Volumes }}
Volumes from:{{ image.container_config.VolumesFrom }}
Comment:{{ image.comment }}
\n" + "\n" + "
\n" + "
\n" + " History:\n" + "
\n" + "
\n" + " \n" + "
\n" + "
\n" + "\n" + "
\n" + "
    \n" + "
  • \n" + " {{ change.Id }}: Created: {{ change.Created|getdate }} Created by: {{ change.CreatedBy }}\n" + "
  • \n" + "
\n" + "
\n" + "\n" + "
\n" + "\n" + "
\n" + "
\n" + "
\n" + " Tag image\n" + "
\n" + " \n" + " \n" + "
\n" + "
\n" + " \n" + "
\n" + " \n" + "
\n" + "
\n" + "
\n" + "\n" + "
\n" + "\n" + "
\n" + " \n" + "
\n" + "
\n" + ""); }]); angular.module("app/components/images/images.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/images/images.html", "\n" + "
\n" + "\n" + "

Images:

\n" + "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
ActionIdRepositoryVirtualSizeCreated
{{ image.Id|truncate:20}}{{ image|repotag }}{{ image.VirtualSize|humansize }}{{ image.Created|getdate }}
\n" + ""); }]); angular.module("app/components/masthead/masthead.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/masthead/masthead.html", "
\n" + "

DockerUI

\n" + " \n" + "
\n" + ""); }]); angular.module("app/components/settings/settings.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/settings/settings.html", "
\n" + "

Docker Information

\n" + "
\n" + "

\n" + " Endpoint: {{ endpoint }}
\n" + " Api Version: {{ apiVersion }}
\n" + " Version: {{ docker.Version }}
\n" + " Git Commit: {{ docker.GitCommit }}
\n" + " Go Version: {{ docker.GoVersion }}
\n" + "

\n" + "
\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
Containers:{{ info.Containers }}
Images:{{ info.Images }}
Debug:{{ info.Debug }}
NFd:{{ info.NFd }}
NGoroutines:{{ info.NGoroutines }}
MemoryLimit:{{ info.MemoryLimit }}
SwapLimit:{{ info.SwapLimit }}
NFd:{{ info.NFd }}
\n" + "
\n" + ""); }]); angular.module("app/components/sidebar/sidebar.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/sidebar/sidebar.html", "
\n" + " Running containers:\n" + "
\n" + " Endpoint: {{ endpoint }}\n" + " \n" + "
\n" + ""); }]); angular.module("app/components/startContainer/startcontainer.html", []).run(["$templateCache", function($templateCache) { $templateCache.put("app/components/startContainer/startcontainer.html", "
\n" + "
\n" + "
\n" + "
\n" + " \n" + "

Create And Start Container From Image

\n" + "
\n" + "
\n" + "
\n" + "
\n" + "
\n" + " \n" + " \n" + " Input commands as an array\n" + "
\n" + "
\n" + " \n" + " \n" + "
\n" + "
\n" + " \n" + " \n" + "
\n" + "
\n" + " \n" + " \n" + "
\n" + "
\n" + " \n" + " \n" + "
\n" + "
\n" + " \n" + " \n" + "
\n" + "
\n" + "
\n" + "
\n" + "
\n" + " Create\n" + "
\n" + "
\n" + "
\n" + "
\n" + ""); }]);