Docker App

Tushar Jain
6 min readSep 2, 2021

Task Description

⚡ Till date whatever we have learnt in Flutter ,is need to be implemented in some way integrating other technologies with it

⚡Hint :1. Create attractive GUI
2.Make sure you implement other technologies if possible
3.Show your creativity (Optional: Animations, Responsive UI,DB connection ,etc.)

In this blog going to create a flutter app where you can run any Linux or Docker commands

1. Create attractive GUI

2.Make sure you implement other technologies if possible

3.Show your creativity (Optional: Animations, Responsive UI,DB connection , etc.)

So, let’s integrate Flutter with Docker:

#Concepts Used:

  • Basic knowledge of Dart, Flutter, OOPS.
  • Python CGI
  • Launching Apache Server

#Service provided:

  • Creation of Docker Container inside the RedHat8.
  • Information regarding docker.

NOTE: →We created CGI in RHEL8 .

→I launched the Apache server using:

# systemctl start httpd

Firstly I used the concept of Python-CGI to act as the back-end server:

I have written this in python, so that the user can interact with CLI internally and fetch the output on web-page.

Now comes the most exciting part that was to create the Frontend, look and feel or the interface of the App.

Now for writing any code in dart language and finally making it executable I used the “material.dart” package so make it simpler for me do write the code. So for imprting the package I used the command : “ import ‘package:flutter/material.dart’ “; .

For creating the App I created a Stateless widget Class and used the MaterialApp() widget and as the child of the widget I used Scaffold, and inside the body of the Scaffold I used the container widget to give the appearance to my desired app.

Inside Container all the properties of the app are comprised by me, whether its the Text widget, TextField(), Image(), Circle Avatar() ,etc and I have also used some more small woidgets that gave the final touch to the first/ home page of my app, some of which were SizedBox(), BoxDecoration(), TextStyle(), and much more.

I also added a button on pressing which will take us to the next page . But for that you have to write the name of the service you want to use in the text field provided.

After creating the look and feel of my home page , I used the concept of Page Navigation to move from one page to another page of my app and to accomplish this I used the widget MaterialPageRoute() and to make this run I used Navigator.push() which will enable me to reach to the next page of my app. And I also saved the entire widget tree in a variable called “context”, so that I can easily navigate through the pages of the app.

So, after doing all the above specified things I can move to the next page by typing the name of the service in the text field , and clicking the “SERVICE” TextButton().

Now, for creating the second page I used “ import ‘package:http/http.dart’; “ package to use the Python-CGI code written in the backend server. And for making this package executable I added “ http: ^0.13.3 “ to my app dependencies.

I created a Stateful widget class so that anything that comes from the backend and needs to be changed on the fly , can be displayed on the app screen.

Mainly in the second page I kept two TextField() of enter the name and image, button to send the input to the backend, FloatingActionButton() to move back to the home page and one info icon floating button to give information about Docker . On pressing the “OUTPUT” button the name and image of the container was sent to the backend using the command given below.

Uri.http("192.168.1.9", "/cgi-bin/app1.py", {"x": cmd, "y": name});

Then after the creation of the container with the given name and image I needed to display the confirmation message that came from the backend in the front end I used “$” with the variable in which the message from the backend was saved.

This is the code of docker.dart file which I used for creating front-end:

import 'package:flutter/material.dart';import 'package:flutter_statusbarcolor/flutter_statusbarcolor.dart';import 'package:http/http.dart' as http;String containername, osname, version, port, volume, network;String imagename, pullversion;String x;one() async {var url ='http://192.168.1.9/cgi-bin/web.py?x=$containername&y=$osname&z=$version';var resp = await http.get(url);print(resp.body);}net() async {var url ='http://192.168.1.9/cgi-bin/net.py?CN=$containername&NET=$network&OSN=$osname&VSN=$version';var resp = await http.get(url);print(resp.body);}forport() async {var url ='http://192.168.1.9/cgi-bin/port.py?CN=$containername&PORT=$port&OSN=$osname&VSN=$version';var resp = await http.get(url);print(resp.body);}forvolume() async {var url ='http://192.168.1.9/cgi-bin/vol.py?CN=$containername&VOL=$volume&OSN=$osname&VSN=$version';var resp = await http.get(url);print(resp.body);}volnet() async {var url ='http://192.168.1.9/cgi-bin/vol_net.py?CN=$containername&VOL=$volume&NET=$network&OSN=$osname&VSN=$version';var resp = await http.get(url);print(resp.body);}portnet() async {var url ='http://192.168.1.9/cgi-bin/port_net.py?CN=$containername&PORT=$port&NET=$network&OSN=$osname&VSN=$version';var resp = await http.get(url);print(resp.body);}volport() async {var url ='http://192.168.1.9/cgi-bin/vol_port.py?CN=$containername&VOL=$volume&PORT=$port&OSN=$osname&VSN=$version';var resp = await http.get(url);print(resp.body);}volnetport() async {var url ='http://192.168.1.9/cgi-bin/vol_net_port.py?CN=$containername&VOL=$volume&NET=$network&PORT=$port&OSN=$osname&VSN=$version';var resp = await http.get(url);print(resp.body);}web(imagename, pullversion) async {var url ='http://192.168.1.9/cgi-bin/pulll.py?image=$imagename&version=$pullversion';var response = await http.get(url);print(response.body);}appdocker() {print("container launched");}mydocker() {FlutterStatusbarcolor.setStatusBarColor(Colors.blue[900]);var forCMD = Container(width: double.infinity,height: double.infinity,decoration: BoxDecoration(image: DecorationImage(image: AssetImage('images/8.JPG'), fit: BoxFit.cover)),child: SingleChildScrollView(scrollDirection: Axis.vertical,child: Column(children: <Widget>[SizedBox(height: 40),Container(width: 300,decoration: BoxDecoration(color: Colors.white70,borderRadius: BorderRadius.circular(20.7),border: Border.all(color: Colors.black87,width: 2,),),child: TextField(onChanged: (value) {x = value;},autocorrect: false,style: TextStyle(fontSize: 22.0, color: Colors.black),textAlign: TextAlign.center,decoration: InputDecoration(focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black26),borderRadius: BorderRadius.circular(25.7),),enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.red),borderRadius: BorderRadius.circular(25.7),),hintText: "Docker Command",prefixIcon: Icon(Icons.tablet_android),fillColor: Colors.black),),),SizedBox(height: 40),FlatButton(onPressed: () {appdocker();},child: Container(decoration: BoxDecoration(color: Colors.blueAccent,borderRadius: BorderRadius.circular(10),border: Border.all(color: Colors.black87,width: 2,),),child: Text('Run Command', style: TextStyle(fontSize: 35)),),),],),),);var newbody = Container(width: double.infinity,height: double.infinity,decoration: BoxDecoration(image: DecorationImage(image: AssetImage('images/12.png'), fit: BoxFit.cover)),child: SingleChildScrollView(scrollDirection: Axis.vertical,child: Column(children: <Widget>[SizedBox(height: 40),Container(width: 300,decoration: BoxDecoration(color: Colors.white70,borderRadius: BorderRadius.circular(20.7),border: Border.all(color: Colors.black87,width: 2,),),child: TextField(onChanged: (value) {imagename = value;},autocorrect: false,style: TextStyle(fontSize: 22.0, color: Colors.black),textAlign: TextAlign.center,decoration: InputDecoration(focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black26),borderRadius: BorderRadius.circular(25.7),),enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.red),borderRadius: BorderRadius.circular(25.7),),hintText: "Image",prefixIcon: Icon(Icons.tablet_android),fillColor: Colors.black),),),SizedBox(height: 40),Container(width: 300,decoration: BoxDecoration(color: Colors.white70,borderRadius: BorderRadius.circular(25.7),border: Border.all(color: Colors.black87,width: 2,),),child: TextField(onChanged: (value) {pullversion = value;},autocorrect: false,style: TextStyle(fontSize: 22.0, color: Colors.black),textAlign: TextAlign.center,decoration: InputDecoration(focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black26),borderRadius: BorderRadius.circular(25.7),),enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.red),borderRadius: BorderRadius.circular(25.7),),hintText: "Version",prefixIcon: Icon(Icons.tablet_android),fillColor: Colors.black),),),SizedBox(height: 40),FlatButton(onPressed: () {web(imagename, pullversion);},child: Container(decoration: BoxDecoration(color: Colors.greenAccent,borderRadius: BorderRadius.circular(10),border: Border.all(color: Colors.black87,width: 2,),),child: Text('Pull Image', style: TextStyle(fontSize: 35)),),),],),),);var mybody = Container(width: double.infinity,height: double.infinity,decoration: BoxDecoration(image: DecorationImage(image: AssetImage('images/10.png'), fit: BoxFit.fill)),child: SingleChildScrollView(scrollDirection: Axis.vertical,child: Column(children: <Widget>[SizedBox(height: 40),Container(width: 300,decoration: BoxDecoration(color: Colors.white70,borderRadius: BorderRadius.circular(25.7),border: Border.all(color: Colors.black87,width: 2,),),child: TextField(onChanged: (value) {containername = value;},autocorrect: false,style: TextStyle(fontSize: 22.0, color: Colors.black),textAlign: TextAlign.center,decoration: InputDecoration(focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black26),borderRadius: BorderRadius.circular(25.7),),enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.red),borderRadius: BorderRadius.circular(25.7),),hintText: "Container Name",prefixIcon: Icon(Icons.tablet_android),fillColor: Colors.black),),),SizedBox(height: 40),Container(width: 300,decoration: BoxDecoration(color: Colors.white70,borderRadius: BorderRadius.circular(25.7),border: Border.all(color: Colors.black87,width: 2,),),child: TextField(onChanged: (value) {osname = value;},autocorrect: false,style: TextStyle(fontSize: 22.0, color: Colors.black),textAlign: TextAlign.center,decoration: InputDecoration(focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black26),borderRadius: BorderRadius.circular(25.7),),enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.red),borderRadius: BorderRadius.circular(25.7),),hintText: "Image name",prefixIcon: Icon(Icons.tablet_android),fillColor: Colors.black),),),SizedBox(height: 40),Container(width: 300,decoration: BoxDecoration(color: Colors.white70,borderRadius: BorderRadius.circular(25.7),border: Border.all(color: Colors.black87,width: 2,),),child: TextField(onChanged: (value) {version = value;},autocorrect: false,style: TextStyle(fontSize: 22.0, color: Colors.black),textAlign: TextAlign.center,decoration: InputDecoration(focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black26),borderRadius: BorderRadius.circular(25.7),),enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.red),borderRadius: BorderRadius.circular(25.7),),hintText: "Version",prefixIcon: Icon(Icons.tablet_android),fillColor: Colors.black),),),SizedBox(height: 40),Container(width: 300,decoration: BoxDecoration(color: Colors.white70,borderRadius: BorderRadius.circular(25.7),border: Border.all(color: Colors.black87,width: 2,),),child: TextField(onChanged: (value) {port = value;},autocorrect: false,style: TextStyle(fontSize: 22.0, color: Colors.black),textAlign: TextAlign.center,decoration: InputDecoration(focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black26),borderRadius: BorderRadius.circular(25.7),),enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.red),borderRadius: BorderRadius.circular(25.7),),hintText: "Port Number",prefixIcon: Icon(Icons.tablet_android),fillColor: Colors.black),),),SizedBox(height: 40),Container(width: 300,decoration: BoxDecoration(color: Colors.white70,borderRadius: BorderRadius.circular(25.7),border: Border.all(color: Colors.black87,width: 2,),),child: TextField(onChanged: (value) {volume = value;},autocorrect: false,style: TextStyle(fontSize: 22.0, color: Colors.black),textAlign: TextAlign.center,decoration: InputDecoration(focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black26),borderRadius: BorderRadius.circular(25.7),),enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.red),borderRadius: BorderRadius.circular(25.7),),hintText: "Attach Volume",prefixIcon: Icon(Icons.tablet_android),fillColor: Colors.black),),),SizedBox(height: 40),Container(width: 300,decoration: BoxDecoration(color: Colors.white70,borderRadius: BorderRadius.circular(25.7),border: Border.all(color: Colors.black87,width: 2,),),child: TextField(onChanged: (value) {network = value;},autocorrect: false,style: TextStyle(fontSize: 22.0, color: Colors.black),textAlign: TextAlign.center,decoration: InputDecoration(focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.black26),borderRadius: BorderRadius.circular(25.7),),enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.red),borderRadius: BorderRadius.circular(25.7),),hintText: "Network",prefixIcon: Icon(Icons.tablet_android),fillColor: Colors.black),),),SizedBox(height: 40),FlatButton(onPressed: () => {if (port == "none" && volume == "none" && network == "none"){one(),}else if (port == "none" && volume == "none"){net(),}else if (port == "none" && network == "none"){forvolume(),}else if (volume == "none" && network == "none"){forport(),}else if (port == "none"){volnet(),}else if (volume == "none"){portnet(),}else if (network == "none"){volport(),}else{volnetport(),}},child: Container(decoration: BoxDecoration(color: Colors.blueAccent,borderRadius: BorderRadius.circular(10),border: Border.all(color: Colors.black87,width: 2,),),child: Text('Run Container', style: TextStyle(fontSize: 35)),),),SizedBox(height: 60)],),),);// margin: EdgeInsets.all(20),// color: Colors.blue,// child: Text('second'),return MaterialApp(debugShowCheckedModeBanner: false,home: DefaultTabController(length: 3,child: Scaffold(appBar: PreferredSize(preferredSize: Size.square(90),child: AppBar(title: Center(child: Text('docker',style: TextStyle(fontSize: 50),),),backgroundColor: Colors.lightBlue,leading: Image.asset("images/9.png"),bottom: TabBar(labelColor: Colors.white,unselectedLabelColor: Colors.white30,unselectedLabelStyle: TextStyle(fontSize: 10),tabs: [Tab(child: Container(child: Text('Run', style: TextStyle(fontSize: 23)),),),Tab(child: Container(child: Text('Pull', style: TextStyle(fontSize: 23)),),),Tab(child: Container(child: Text('CMD', style: TextStyle(fontSize: 23)),),),],),),),/*appBar: AppBar(backgroundColor: Colors.white,title: Center(child: Text('Audio Player', style: TextStyle(color: Colors.black)),)),*/body: TabBarView(children: <Widget>[mybody,newbody,forCMD,])),),);}

So, after performing all the above-specified steps , I have completed my Task_11 successfully.

Thanks for Reading !!

Keep Learning !! Keep Sharing !!

Tushar jain

--

--