├── Screenshots ├── login.png ├── create.png ├── Container.png └── networks.png ├── runapp.sh ├── README.md ├── dockerLib.py ├── login.html ├── user.py └── admin.html /Screenshots/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinkyamhatre/Docker-Dashboard/HEAD/Screenshots/login.png -------------------------------------------------------------------------------- /Screenshots/create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinkyamhatre/Docker-Dashboard/HEAD/Screenshots/create.png -------------------------------------------------------------------------------- /Screenshots/Container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinkyamhatre/Docker-Dashboard/HEAD/Screenshots/Container.png -------------------------------------------------------------------------------- /Screenshots/networks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajinkyamhatre/Docker-Dashboard/HEAD/Screenshots/networks.png -------------------------------------------------------------------------------- /runapp.sh: -------------------------------------------------------------------------------- 1 | mkdir templates 2 | cp login.html templates 3 | cp admin.html templates 4 | rm login.html 5 | rm admin.html 6 | python user.py 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker-Dashboard 2 |
3 |

Note :


4 | Install following prerequsit to run this app 5 |
6 | Install docker url: 7 |
8 | https://docs.docker.com/engine/installation/linux/ubuntulinux/
9 | 10 | Install python dependencies with pip: 11 | 12 | ``` 13 | pip install docker-py 14 | ``` 15 | 16 | ``` 17 | sudo pip install Flask 18 | ``` 19 | 20 | download the zip: 21 |
22 | https://github.com/ajinkyamhatre/Docker-Dashboard/archive/master.zip 23 |

24 | 25 | if you are using this dashboard remotely change the ip in Docker-Dashboard/user.py in below line 26 |
27 | `app.run(‘[ip]’,8080,debug=True)` 28 |
29 | and use url `http://[ip]:8080/login` 30 |
31 | otherwise if you are running this code locally, don’t change Docker-Dashboard/user.py file 32 |
33 | and access url is http://localhost:8080/login 34 |
35 |

To run Server :

36 | 37 | ``` 38 | ./runapp.sh 39 | ``` 40 |

Login :


41 |

Id :

admin@gmail.com
42 |

Pass:

admin 43 |
44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /dockerLib.py: -------------------------------------------------------------------------------- 1 | from docker import Client 2 | 3 | connection = Client(base_url='unix://var/run/docker.sock') 4 | 5 | 6 | def containers_list(running): 7 | if running: 8 | return connection.containers() 9 | else: 10 | return connection.containers(all=True) 11 | 12 | 13 | def images_list(): 14 | return connection.images() 15 | 16 | 17 | def docker_info(): 18 | return connection.info() 19 | 20 | 21 | def memory(): 22 | """ 23 | Get node total memory and memory usage 24 | """ 25 | with open('/proc/meminfo', 'r') as mem: 26 | ret = {} 27 | tmp = 0 28 | for i in mem: 29 | sline = i.split() 30 | if str(sline[0]) == 'MemTotal:': 31 | ret['total'] = int(sline[1]) 32 | elif str(sline[0]) in ('MemFree:', 'Buffers:', 'Cached:'): 33 | tmp += int(sline[1]) 34 | ret['free'] = tmp 35 | ret['used'] = int(ret['total']) - int(ret['free']) 36 | return ret 37 | 38 | 39 | def remove(mycont): 40 | connection.remove_container(mycont) 41 | 42 | 43 | def start(mycont): 44 | connection.start(mycont) 45 | 46 | 47 | def stop(mycont): 48 | connection.stop(mycont) 49 | 50 | 51 | def create_container(image, command, name): 52 | connection.create_container(image=image, command=command, name=name) 53 | 54 | 55 | def test(): 56 | return connection.networks() 57 | 58 | 59 | def network(): 60 | return connection.networks() 61 | -------------------------------------------------------------------------------- /login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Login Page 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 |
20 |
21 | 45 |
46 |
47 |
48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /user.py: -------------------------------------------------------------------------------- 1 | from dockerLib import docker_info, containers_list, images_list, memory, remove, start, stop, create_container, test, network 2 | import subprocess 3 | from flask import * 4 | 5 | app = Flask(__name__) 6 | app.secret_key = 'my key' 7 | 8 | 9 | @app.route('/login', methods=['GET', 'POST']) 10 | def login(): 11 | session['logged_in'] = False 12 | if request.method == 'POST': 13 | if request.form['email'] == 'admin@gmail.com' and request.form['password'] == 'admin': 14 | session['logged_in'] = True 15 | return redirect(url_for('admin')) 16 | else: 17 | return "

wrong password

" 18 | else: 19 | return render_template('login.html') 20 | 21 | 22 | @app.route('/admin', methods=['GET', 'POST']) 23 | def admin(): 24 | action_list = [] 25 | all_containers_list = containers_list(running=False) 26 | if session['logged_in']: 27 | myimg = '' 28 | if request.method == 'POST' or 'GET': 29 | for container in containers_list(running=False): 30 | if request.form.getlist(container['Id'][0:12]): 31 | action_list.append(container['Id'][0:12]) 32 | if request.form.getlist('remove'): 33 | for container in action_list: 34 | remove(container) 35 | if request.form.getlist('start'): 36 | for container in action_list: 37 | start(container) 38 | if request.form.getlist('stop'): 39 | for container in action_list: 40 | stop(container) 41 | for image in images_list(): 42 | if request.form.getlist(image['Id'][7:19]): 43 | image_name = (image['Id'][7:19]) 44 | create_container(image=image_name, command=request.form['command'], name=request.form['name']) 45 | return render_template('admin.html', mymemory=memory(), cont=docker_info(), lst=all_containers_list) 46 | else: 47 | return redirect(url_for('myrequest')) 48 | 49 | 50 | @app.route('/create', methods=['GET', 'POST']) 51 | def image_admin(): 52 | lst = containers_list(running=False) 53 | img_lst = images_list() 54 | action_list = [] 55 | if session['logged_in']: 56 | myimg = '' 57 | if request.method == 'POST': 58 | for i in img_lst: 59 | if request.form.getlist(i['Id'][7:19]): 60 | myimg = (i['Id'][7:19]) 61 | create_container(image=myimg, command=request.form['command'], name=str(request.form['name'])) 62 | 63 | return render_template('admin.html', mymemory=memory(), cont=docker_info(), img=images_list()) 64 | else: 65 | return redirect(url_for('myrequest')) 66 | 67 | 68 | @app.route('/network', methods=['GET', 'POST']) 69 | def network_admin(): 70 | lst = containers_list(running=False) 71 | img_lst = images_list() 72 | action_list = [] 73 | if session['logged_in']: 74 | myimg = '' 75 | if request.method == 'POST': 76 | for i in img_lst: 77 | if request.form.getlist(i['Id'][7:19]): 78 | myimg = (i['Id'][7:19]) 79 | create_container(image=myimg, command=request.form['command'], name=str(request.form['name'])) 80 | 81 | return render_template('admin.html', mymemory=memory(), cont=docker_info(), net=network()) 82 | else: 83 | return redirect(url_for('login')) 84 | 85 | 86 | @app.route('/logout') 87 | def logout(): 88 | session['logged_in'] = False 89 | return redirect(url_for('login')) 90 | 91 | 92 | @app.route('/') 93 | def first(): 94 | session['logged_in'] = False 95 | return redirect(url_for('login')) 96 | 97 | 98 | if __name__ == "__main__": 99 | app.run('localhost', 8080, debug=True) 100 | -------------------------------------------------------------------------------- /admin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | System Admin 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 | 34 | 35 | 305 | 306 | 307 |
308 |
309 |
310 |
311 |

Resource Monitoring

312 |
313 | 314 |
315 | 316 | 317 |
318 |
319 |
320 |
321 |
322 |
323 | 324 |
325 |
326 |
RAM
327 |
{{ mymemory['free']/1024-((mymemory['free']/1024)%1) }} MB
328 |
329 |
330 |
331 | 332 | 337 | 338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 | 346 |
347 |
348 |
{{ cont['ContainersRunning'] }}
349 |
Active Containers
350 |
351 |
352 |
353 | 354 | 359 | 360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 | 368 |
369 |
370 |
124
371 |
Network Nodes
372 |
373 |
374 |
375 | 376 | 381 | 382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 | 390 |
391 |
392 |
13
393 |
394 |
395 |
396 |
397 | 398 | 403 | 404 |
405 |
406 |
407 | 408 | 409 |
410 | 411 | 412 | 413 | 414 | {% if net %} 415 |
416 |

Networks

417 |
418 |
419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | {% for c in net %} 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | {% endfor %} 443 | 444 | 445 | {% endif %} 446 | 447 | 448 | 449 | 450 | 451 | {% if lst %} 452 |
453 |

Containers

454 | 455 |
456 |
NameIPAMScopeIdContainers
{{ c['Name'] }} Subnet :
Config : {{ c['IPAM']['Config'][0] }}
Driver : {{ c['IPAM']['Driver'] }}
Options : {{ c['IPAM']['Options'] }}
{{ c['Scope'] }}{{ c['Id'][0:12] }}{% for n in c['Containers'] %}-------------
IPv4Address : {{ c['Containers'][n]['IPv4Address'] }}
MacAddress : {{ c['Containers'][n]['MacAddress'] }}
Name : {{ c['Containers'][n]['Name'] }}
Id : {{ n[0:12] }}
{% endfor %}
457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | {% for c in lst %} 472 | 473 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | {% endfor %} 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 |
CHECKCREATEDIMAGESTATUSCOMMANDNAMEPORTSCONTAINER ID
474 | 475 | {{ c['Created'] }}{{ c['Image'] }}{{ c['Status'] }}{{ c['Command'] }}{{ c['Names'][0] }}{{ c['Ports'][0] }}{{ c['Id'][0:12] }}
494 |
495 |
496 | 497 |
498 | 501 |
502 |
503 | 506 |
507 |
508 | 511 |
512 |
513 | 514 |
515 | 516 | {% endif %} 517 | 518 | {% if img %} 519 |
520 |

Create Containers

521 |
522 |

Images

523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | {% for i in img %} 535 | 536 | 539 | 540 | 541 | 542 | 543 | 544 | {% endfor %} 545 | 546 |
CHECKCREATEDSIZERepoTagsIMAGE ID
537 | 538 |
{{ i['Created'] }}{{ (i['Size']/1000000)-(i['Size']/1000000)%1 }}MB{{ i['RepoTags'][0] }}{{ i['Id'][7:19] }}
547 |
548 | 549 | 550 |
551 |
552 | 553 | 554 |
555 |
556 | 557 | 558 |
559 | 560 |
561 | 562 | 563 | {% endif %} 564 |
565 | 566 |
567 | 568 |
569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 |
592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | --------------------------------------------------------------------------------