Installer for a web server with InnoSetup
- In this post we will
- Create a simple flask web app and bundle it into an exe package using pyinstaller
- Create batch scripts that can register, restart and delete the web app as a windows service using nssm
- Create an Inno Setup script that will bundle the web app package, scripts into an installer
- After installation of the web app with the installer, the web app will be setup and running. Also, windows start menu shortcuts to restart, stop, view logs, edit configuration of the web app will be accessible
Web app
The following is a simple flask web application code
from flask import Flask, render_template
import json
appConf = {}
with open("config/config.json") as f:
appConf = json.load(f)
app = Flask(__name__)
@app.route("/")
def home():
return render_template("home.html")
@app.route("/about")
def about():
return render_template("about.html")
app.run(host=appConf["host"], port=appConf["port"], debug=appConf["debug"])
- The server requires the
configfolder,templatesfolder andstaticfolder

Convert the server to an exe file
- The application is built as an exe using pyinstaller (install it using
pip install pyinstaller) - The following pyinstaller command is used to generate exe
xcopy .\config\ .\dist\config\ /E /Y
rem /E means copy including sub-directories
pyinstaller server.py --onefile --name AwesomeWebApp --add-data "templates;templates" --add-data "static;static"
rem --onefile creates single exe file
rem --name is the name of the exe file generated
rem --add-data bundles a folder into the exe. Syntax is --add-data "sourcepath;bundlepath". for linux/mac, the syntax is --add-data "sourcepath:bundlepath"
-
The
templatesandstaticfolder are bundled into the exe using the--add-dataflag -
The application exe is generated in the
distfolder -
The
configfolder is copied into the dist folder using thexcopycommand
Windows service
- The web app exe file can run as a windows service using
nssm.exe - The following batch scripts make the web server run as a windows background service
- The
serviceRegister.batscript will run the web application exe as a windows background service namedawesome_webapp - It also sets up a logs folder for the web server logs
- The
rem delete service if exists
call net stop awesome_webapp
call net delete awesome_webapp
rem insall service
call nssm.exe install awesome_webapp "%cd%\AwesomeWebApp.exe"
call nssm.exe set awesome_webapp AppStdout "%programdata%\Awesome Web App\awesome_webapp.log"
call nssm.exe set awesome_webapp AppStderr "%programdata%\Awesome Web App\awesome_webapp.log"
call nssm.exe set awesome_webapp AppStdoutCreationDisposition 4
call nssm.exe set awesome_webapp AppStderrCreationDisposition 4
call nssm.exe set awesome_webapp AppRotateFiles 1
call nssm.exe set awesome_webapp AppRotateOnline 1
call nssm.exe set awesome_webapp AppRotateBytes 1048576
call net start awesome_webapp
- The
serviceRestart.batscript will restart the web application windows background service
call net stop awesome_webapp
call net start awesome_webapp
- The
serviceStop.batscript will stop the web application windows background service
call net stop awesome_webapp
- The
serviceDelete.batscript will delete the web application windows background service
call net stop awesome_webapp
call sc delete awesome_webapp
- The
openLogsFolder.batscript will open the logs folder in file explorer
%SystemRoot%\explorer.exe "%programdata%\Awesome Web App\"
Installer for the software
- Inno Setup is used to create an installer for the software files
- It can be downloaded from https://jrsoftware.org/isdl.php#stable
- The installer does the following during software installation
- creates all the required software files and folders in the required locations
- creates the logs folder if not present
- runs the script to register the server as a windows background service
- creates shortcuts for server restart, stop, opening logs folder, opening config file in the start menu
- sets up a software uninstallation script that deletes the web application windows service
- starts the server
- The
installerGenScript.issfile contains the script to generate the software installer - It bundles the exe, bat, readme, favicon and other required files into the installer exe file
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "Awesome Web App"
#define MyAppVersion "1.0"
#define MyAppPublisher "Learning Software"
#define MyAppURL "https://youtube.com/%40learningsoftwareskills"
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{cd25fcca-ce9d-4aea-b753-478dc3ecf11a}}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
; Only allow the installer to run on x64-compatible systems,
; and enable 64-bit install mode.
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
DefaultDirName={autopf}\{#MyAppName}
DefaultGroupName={#MyAppName}
; Uncomment the following line to run in non administrative install mode (install for current user only).
;PrivilegesRequired=lowest
OutputDir=Installer
OutputBaseFilename={#MyAppName} Setup
SolidCompression=yes
WizardStyle=modern
SetupIconFile="..\static\favicon.ico"
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Files]
Source: "..\dist\config\config.json"; DestDir: "{app}\config"; Flags: ignoreversion
Source: "..\dist\AwesomeWebApp.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "nssm.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "serviceRegister.bat"; DestDir: "{app}"; Flags: ignoreversion
Source: "serviceDelete.bat"; DestDir: "{app}"; Flags: ignoreversion
Source: "serviceRestart.bat"; DestDir: "{app}"; Flags: ignoreversion
Source: "serviceStop.bat"; DestDir: "{app}"; Flags: ignoreversion
Source: "openLogsFolder.bat"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
Source: "..\static\favicon.ico"; DestDir: "{app}"
Source: "..\README.md"; DestDir: "{app}"; Flags: isreadme
[Icons]
Name: "{autoprograms}\Configure {#MyAppName}"; Filename: "{app}\config\config.json"; WorkingDir: "{app}\config"; IconFilename: "{app}\favicon.ico"
Name: "{autoprograms}\Restart {#MyAppName}"; Filename: "{app}\serviceRestart.bat"; WorkingDir: "{app}"; IconFilename: "{app}\favicon.ico"
Name: "{autoprograms}\Stop {#MyAppName}"; Filename: "{app}\serviceStop.bat"; WorkingDir: "{app}"; IconFilename: "{app}\favicon.ico"
Name: "{autoprograms}\View Logs of {#MyAppName}"; Filename: "{app}\openLogsFolder.bat"; WorkingDir: "{app}"; IconFilename: "{app}\favicon.ico"
[Dirs]
Name: "{commonappdata}\{#MyAppName}"
[Run]
Filename: "{app}\serviceRegister.bat"
[UninstallRun]
Filename: "{app}\serviceDelete.bat"
#defineis used to define the variables used in the iss script. The installer exe file is generated in theInstallerfolder- The
[Files]section specifies the files that will be bundled into the installer. It also specifies the folders where the files are installed - The
[RUN]section specifies to run the fileserviceRegister.batafter all the application files are installed - The
[UninstallRun]section specifies to run the fileserviceDelete.batbefore removing the installed files - The
[Icons]section creates a shortcut for 2 filesconfig.jsonwhich facilitates configuring the serverserviceRestart.batwhich restarts the server
- The
[Dirs]section specifies the folders that will be ensured during the installation - The
[Setup]section specifies the general configuration of the installer like name, version, icon etc. - The following special variables are used in the script (official docs here)
{autopf}- program files folder{app}- directory where the software files would be present after installation{autoprograms}- Programs folder on the Start Menu{commonappdata}- The path to the Application Data folder
Steps to run the demo
- Run
build.batto create exe files in the dist folder - Open
installerGenScript.issfile in Inno Setup and run Build->Compile from the top menu. This generates the installer exe

- Run the installer to install the server. This will setup and run the server as a windows background service

- Search for “Configure Awesome Web App” in start menu to edit the server’s
config.jsonfile - Search for “Restart Awesome Web App” in start menu to restart the server
- Search for “View logs of Awesome Web App” in start menu to see the logs folder
- Because of nssm, the web app is running as a windows background service as shown in the below image

- The software can be uninstalled just like any other software in the control panel or “Add or remove programs” menu

References
- Inno Setup download - https://jrsoftware.org/isdl.php#stable
- Source code and inno setup script for the demo - https://github.com/nagasudhirpulla/flask_server_installer_demo
- Inno Setup docs - https://jrsoftware.org/ishelp/
- InnoSetup script syntax - https://jrsoftware.org/ishelp/topic_scriptformatoverview.htm
- InnoSetup script constants - https://jrsoftware.org/ishelp/index.php?topic=consts
- Files section in Innosetup - https://jrsoftware.org/ishelp/topic_filessection.htm
- Run & UninstallRun sections in Innosetup - https://jrsoftware.org/ishelp/topic_runsection.htm
- Icons section in Innosetup - https://jrsoftware.org/ishelp/topic_iconssection.htm
- Dirs section in Innosetup - https://jrsoftware.org/ishelp/topic_dirssection.htm
- Setup section in Innosetup - https://jrsoftware.org/ishelp/topic_setupsection.htm
- nssm docs - https://nssm.cc/usage
- Flask server docs - https://flask.palletsprojects.com/en/stable/quickstart/
Comments
Post a Comment