diff --git a/agkyra/gui.py b/agkyra/gui.py
index 540903f8d17f90a680d2ffc905ebaab2bcc3affb..c13ca35e9d20531cf1c20981ca87f97e2f59f470 100644
--- a/agkyra/gui.py
+++ b/agkyra/gui.py
@@ -18,17 +18,28 @@ from agkyra.protocol import SessionHelper, launch_server
 from agkyra.config import AGKYRA_DIR
 from agkyra.syncer import utils
 import subprocess
+import sys
 import os
 import stat
 import json
 import logging
 
-CURPATH = os.path.dirname(os.path.abspath(__file__))
+if getattr(sys, 'frozen', False):
+    # we are running in a |PyInstaller| bundle
+    BASEDIR = sys._MEIPASS
+    ISFROZEN = True
+else:
+    # we are running in a normal Python environment
+    BASEDIR = os.path.dirname(os.path.realpath(__file__))
+    ISFROZEN = False
+
+RESOURCES = os.path.join(BASEDIR, 'resources')
+
 LOG = logging.getLogger(__name__)
 
 OSX_DEFAULT_NW_PATH = os.path.join(
-    CURPATH, 'nwjs', 'nwjs.app', 'Contents', 'MacOS', 'nwjs')
-STANDARD_DEFAULT_NW_PATH = os.path.join(CURPATH, 'nwjs', 'nw')
+    RESOURCES, 'nwjs', 'nwjs.app', 'Contents', 'MacOS', 'nwjs')
+STANDARD_DEFAULT_NW_PATH = os.path.join(RESOURCES, 'nwjs', 'nw')
 DEFAULT_NW_PATH = OSX_DEFAULT_NW_PATH if utils.isosx() \
     else STANDARD_DEFAULT_NW_PATH
 
@@ -45,7 +56,7 @@ class GUI(WebSocketBaseClient):
             'session_file', os.path.join(AGKYRA_DIR, 'session.info'))
         self.start = self.connect
         self.nw = kwargs.get('nw', DEFAULT_NW_PATH)
-        self.gui_code = kwargs.get('gui_code', os.path.join(CURPATH, 'nwgui'))
+        self.gui_code = kwargs.get('gui_code', os.path.join(RESOURCES, 'nwgui'))
         assert not self._gui_running(session), (
             'Failed to initialize GUI, because another GUI is running')
         self._dump_session_file(session)
@@ -85,9 +96,9 @@ class GUI(WebSocketBaseClient):
         LOG.debug('GUI finished, close GUI wrapper connection')
 
 
-def run():
+def run(callback):
     """Prepare SessionHelper and GUI and run them in the proper order"""
-    launch_server()
+    launch_server(callback)
     LOG.info('Client blocks until session is ready')
     session = SessionHelper().wait_session_to_load()
     assert session, 'UI server failed to load...'
diff --git a/agkyra/protocol.py b/agkyra/protocol.py
index 60348a751ea074e9d55a98aacbd379c37faf7a8f..dcedfcbb1c897db762bd3d681c672525dc7eeabf 100644
--- a/agkyra/protocol.py
+++ b/agkyra/protocol.py
@@ -22,6 +22,7 @@ from threading import Thread
 import sqlite3
 import time
 import os
+import sys
 import json
 import logging
 import subprocess
@@ -29,13 +30,21 @@ from agkyra.syncer import (
     syncer, setup, pithos_client, localfs_client, messaging, utils)
 from agkyra.config import AgkyraConfig, AGKYRA_DIR
 
+if getattr(sys, 'frozen', False):
+    # we are running in a |PyInstaller| bundle
+    BASEDIR = sys._MEIPASS
+    ISFROZEN = True
+else:
+    # we are running in a normal Python environment
+    BASEDIR = os.path.dirname(os.path.realpath(__file__))
+    ISFROZEN = False
 
-CURPATH = os.path.dirname(os.path.abspath(__file__))
+RESOURCES = os.path.join(BASEDIR, 'resources')
 
 LOG = logging.getLogger(__name__)
 SYNCERS = utils.ThreadSafeDict()
 
-with open(os.path.join(CURPATH, 'ui_data/common_en.json')) as f:
+with open(os.path.join(RESOURCES, 'ui_data/common_en.json')) as f:
     COMMON = json.load(f)
 STATUS = COMMON['STATUS']
 
@@ -702,14 +711,13 @@ class WebSocketProtocol(WebSocket):
             self.terminate()
 
 
-def launch_server():
+def launch_server(callback):
     """Launch the server in a separate process"""
     LOG.info('Start SessionHelper session')
-    server_path = os.path.join(CURPATH, 'scripts', 'server.py')
     if utils.iswin():
-        subprocess.Popen(["pythonw.exe", server_path],
+        subprocess.Popen([callback, "server"],
                          close_fds=True)
     else:
         pid = os.fork()
         if not pid:
-            os.execlp("python", "python", server_path)
+            os.execlp(callback, callback, "server")
diff --git a/agkyra/scripts/server.py b/agkyra/scripts/agkyra
old mode 100644
new mode 100755
similarity index 76%
rename from agkyra/scripts/server.py
rename to agkyra/scripts/agkyra
index dfbb44c881d41c4ad9fcdd4602c6eebedd735cb2..e76231a22dd34dbbfcc7f4eaaee1110566b628ab
--- a/agkyra/scripts/server.py
+++ b/agkyra/scripts/agkyra
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 # Copyright (C) 2015 GRNET S.A.
 #
 # This program is free software: you can redistribute it and/or modify
@@ -16,13 +17,12 @@
 import os
 import sys
 
-SCRIPTSPATH = os.path.dirname(os.path.realpath(__file__))
-AGKYRAPATH = os.path.dirname(SCRIPTSPATH)
-LIBPATH = os.path.dirname(AGKYRAPATH)
+try:
+    from agkyra import config
+except ImportError:
+    sys.path.insert(0, "lib")
+    from agkyra import config
 
-sys.path.insert(0, LIBPATH)
-
-from agkyra import config
 AGKYRA_DIR = config.AGKYRA_DIR
 
 import logging
@@ -35,8 +35,9 @@ HANDLER.setFormatter(FORMATTER)
 LOGGER.addHandler(HANDLER)
 LOGGER.setLevel(logging.INFO)
 
+CALLBACK = os.path.realpath(sys.argv[0])
 
-def main():
+def run_server():
     from agkyra.protocol import SessionHelper
     LOGGER.debug('Start the session helper')
     helper = SessionHelper()
@@ -45,9 +46,25 @@ def main():
         helper.start()
     else:
         LOGGER.info('Another session is running, aborting')
-        exit(1)
+        return
     LOGGER.debug('Session Helper is now down')
 
 
+def run_gui():
+    from agkyra import gui
+    gui.run(callback=CALLBACK)
+
+DISPATCH = {
+    'server': run_server,
+    'gui': run_gui,
+}
+
+def main():
+    if len(sys.argv) > 1:
+        arg = sys.argv[1]
+    else:
+        arg = 'gui'
+    DISPATCH[arg]()
+
 if __name__ == "__main__":
     main()
diff --git a/agkyra/scripts/gui.py b/agkyra/scripts/gui.py
deleted file mode 100755
index ddc69533d378542e63f104ce2c1803999ae6aa73..0000000000000000000000000000000000000000
--- a/agkyra/scripts/gui.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2015 GRNET S.A.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-import os
-import sys
-
-PATH = os.path.dirname(os.path.realpath(__file__))
-LIBPATH = os.path.join(PATH, "lib")
-
-sys.path.insert(0, LIBPATH)
-
-from agkyra import config
-AGKYRA_DIR = config.AGKYRA_DIR
-
-import logging
-LOGFILE = os.path.join(AGKYRA_DIR, 'agkyra.log')
-LOGGER = logging.getLogger('agkyra')
-HANDLER = logging.FileHandler(LOGFILE)
-FORMATTER = logging.Formatter(
-    "%(name)s:%(lineno)s %(levelname)s:%(asctime)s:%(message)s")
-HANDLER.setFormatter(FORMATTER)
-LOGGER.addHandler(HANDLER)
-LOGGER.setLevel(logging.INFO)
-
-
-def main():
-    from agkyra import gui
-    gui.run()
-
-
-if __name__ == "__main__":
-    main()