Creating simple docker swarm management UI using Portainer and Reactjs

Saurabh Mhatre
CodeClassifiers
Published in
4 min readMar 29, 2017
Image Source:Pixabay

In last tutorial we had set up a simple in browser terminal for running docker commands on remote server.In today’s tutorial we are going to create a simple docker swarm using virtualbox and set up a dashboard for its management using portainer. Install docker by following this tutorial if you have not yet set up docker in your system. Next we are going to need docker-machine which can be installed by running the following commands for ubuntu:

curl -L https://github.com/docker/machine/releases/download/v0.10.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/local/bin/docker-machine

Installation commands for mac users can be found here. Next install virtualbox by downloading it from here and running following commands in terminal:

cd Downloads/
sudo dpkg -i virtualbox-*.deb

Docker swarm typically consists of managers(which are like master servers) and workers(which are like slave servers).First we will create a manager and initialize docker swarm within manager:

docker-machine create --driver virtualbox manager1docker-machine ip manager1
192.168.99.100
docker-machine ssh manager1docker swarm init --advertise-addr <MANAGER-IP>
Important output of the above command to be kept for future ref:docker swarm join \
--token sometoken \
192.168.99.100:2377
exit

Replace <MANAGER-IP> with ip address you got from running second command above which was 192.168.99.100 in my case. Copy the swarm join command somewhere, since we are going to require it in some time

Now we will create a worker vm using docker-machine which will act as slave vm and add it to swarm as worker.

docker-machine create --driver virtualbox worker1docker-machine ssh worker1docker swarm join \
--token jointoken \ <--Your join token here
192.168.99.100:2377
exit

If you need to get join token for adding workers or managers in future you can run the following commands:

docker-machine ssh manager1docker swarm join-token workerdocker swarm join-token managerexit

Next we are going to set up portainer in manager1 for managing swarm services and containers:

docker-machine ssh manager1docker run -d -p 9000:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer

Now go to your browser and open the following address: <MANAGER-IP>:9000 where <MANAGER-IP> is the ip address of the manager node. Set up default username and password and login into portainer. Clicking on the swarm tab will give the following output:

Portainer dashboard

You can manage entire docker swarm,launch custom docker containers from app templates and ssh into running containers from containers tab from the portainer dashboard.

We can use portainer as a standalone application or we can launch it from the in browser terminal we created in previous tutorial. We simply need to add a new command definition in extensions to get portainer/manger ip from server as follows:

Install react-iframe module to display portainer window inside modal popup:

npm install --save react-iframe

First we create a simple modal popup to display portainer window which is hidden by default.

import Dialog from 'material-ui/Dialog';
import FlatButton from 'material-ui/FlatButton';
import RaisedButton from 'material-ui/RaisedButton';
import Iframe from 'react-iframe';
...
export default class TerminalAccess extends Component {
constructor(props) {
super(props);
this.state = {
commandData: '',
dialogOpen:false,
applicationState:[]
}
}
}
...
render() {
...
const actions = [

<FlatButton
label="Close"
primary={true}
keyboardFocused={true}
onTouchTap={(event) => this.handleClose(event)}
/>,
];
}
return (
<MuiThemeProvider>
<Tabs>
<Tab label="Docker Administration" >
<div className="parentContainer">
....
<div>
{this.state.commandData}
<MuiThemeProvider>
<Dialog
title="Application Launcher"
actions={actions}
modal={true}
contentClassName="customDialog2"
open={this.state.dialogOpen}
onRequestClose={(event)=>this.handleClose(event)}
>
{this.state.applicationState}
</Dialog>
</MuiThemeProvider>
</div>
</div>
</Tab>
</Tabs>
</MuiThemeProvider>
)
}

Now we need to add an extension in previous tutorials setup to handle portainer command:

portainer: {
exec: ({ structure, history, cwd }, command) => {
let fetchData = getData("docker-machine ip manager1", (res) => {
var response = JSON.parse(res.text).result.split("\n")[0];
let embedUrl = "http://" + response + ":9000/"
console.log("embedUrl", embedUrl)
let applicationState = [];
applicationState.push(
<div className="customDialog">
<Iframe url={embedUrl} height="400" width="1100"/>
</div>
)
this.setState({ applicationState, dialogOpen:true })
})
return { structure, cwd, history: history.concat({ value: 'Nice try...' }), };
}
}

Going step by step the extension first runs “docker-machine ip manager1” on remote server and gets the ip address of manager in callback response.Next we format the response to remove newline character and append port 9000 to the ip address. Finally we push the address in an iframe within dialog and make modal popup visible by setting dialogOpen to true.

Next define handleClose function to hide modal on click of Close button.

handleClose(event){
this.setState({dialogOpen:false})
}

In a nutshell we are simply retrieving manager ip from server and opening portainer ui in an Iframe. The output looks like this:

That concludes today’s tutorial on docker administration.

Bonus Tips:

The goal of this tutorial was not only to get the reader acquainted with basic docker administration but also to show how we can further extend the capabilities of terminal to launch remote desktop apps within the browser thereby fading the line between terminal commands and dedicated softwares by adding useful capabilities to existing terminals.

A couple of experiments that could be done are to show complete file browser window in popup when user types ls command or phpmyadmin/apache/mysqladmin page access on typing appropriate commands or setup openstack dashboard for managing cloud instances on remote host and giving restricted access to users for managing their cloud instances.

The eventual goal of this project on github is to provide similar such features for extending in browser terminal capabilities.You can see/fork the experimental source code for the project on github here

Connect Deeper:

In the next tutorial I will try to cover setting up custom dashboard for monitoring system performance when user runs top command in terminal using grafana. So follow our facebook page: Technoetics to get notified about future articles

--

--