diff --git a/docker/docker-py3-kms-minimal/Dockerfile b/docker/docker-py3-kms-minimal/Dockerfile
index 883d12e..adabdab 100644
--- a/docker/docker-py3-kms-minimal/Dockerfile
+++ b/docker/docker-py3-kms-minimal/Dockerfile
@@ -12,6 +12,7 @@ ENV HWID RANDOM
 ENV LOGLEVEL INFO
 ENV LOGFILE STDOUT
 ENV LOGSIZE ""
+ENV WEBUI 0
 
 COPY docker/docker-py3-kms-minimal/requirements.txt /home/py-kms/requirements.txt
 RUN apk add --no-cache --update \
@@ -21,7 +22,6 @@ bash \
   ca-certificates \
   shadow \
   tzdata \
-  netcat-openbsd \
   && pip3 install --no-cache-dir -r /home/py-kms/requirements.txt \
   && adduser -S py-kms -G users -s /bin/bash \
   && chown py-kms:users /home/py-kms \
@@ -30,14 +30,14 @@ bash \
 
 COPY ./py-kms /home/py-kms
 COPY docker/entrypoint.py /usr/bin/entrypoint.py
+COPY docker/healthcheck.py /usr/bin/healthcheck.py
 COPY docker/start.py /usr/bin/start.py
-
-RUN chmod 755 /usr/bin/entrypoint.py
+RUN chmod 555 /usr/bin/entrypoint.py /usr/bin/healthcheck.py /usr/bin/start.py
 
 WORKDIR /home/py-kms
 
 EXPOSE ${PORT}/tcp
 
-HEALTHCHECK --interval=5m --timeout=3s --start-period=10s --retries=4 CMD echo | nc -z ${IP%% *} ${PORT} || exit 1
+HEALTHCHECK --interval=5m --timeout=10s --start-period=10s --retries=3 CMD /usr/bin/python3 /usr/bin/healthcheck.py
 
 ENTRYPOINT ["/usr/bin/python3", "-u", "/usr/bin/entrypoint.py"]
diff --git a/docker/docker-py3-kms/Dockerfile b/docker/docker-py3-kms/Dockerfile
index 996da01..7bfb256 100644
--- a/docker/docker-py3-kms/Dockerfile
+++ b/docker/docker-py3-kms/Dockerfile
@@ -16,6 +16,7 @@ ENV LOGLEVEL INFO
 ENV LOGFILE STDOUT
 ENV LOGSIZE ""
 ENV TZ America/Chicago
+ENV WEBUI 1
 
 COPY docker/docker-py3-kms/requirements.txt /home/py-kms/
 RUN apk add --no-cache --update \
@@ -26,7 +27,6 @@ RUN apk add --no-cache --update \
   ca-certificates \
   tzdata \
   shadow \
-  netcat-openbsd \
   && pip3 install --no-cache-dir -r /home/py-kms/requirements.txt \
   #&& apk del git build-base python3-dev \
   && mkdir /db/ \
@@ -37,19 +37,19 @@ RUN apk add --no-cache --update \
 
 COPY py-kms /home/py-kms/
 COPY docker/entrypoint.py /usr/bin/entrypoint.py
+COPY docker/healthcheck.py /usr/bin/healthcheck.py
 COPY docker/start.py /usr/bin/start.py
+RUN chmod 555 /usr/bin/entrypoint.py /usr/bin/healthcheck.py /usr/bin/start.py
 
 # Web-interface specifics
 COPY LICENSE /LICENSE
 RUN echo "$BUILD_COMMIT" > /VERSION && echo "$BUILD_BRANCH" >> /VERSION
 
-RUN chmod 755 /usr/bin/entrypoint.py
-
 WORKDIR /home/py-kms
 
 EXPOSE ${PORT}/tcp
 EXPOSE 8080/tcp
 
-HEALTHCHECK --interval=5m --timeout=3s --start-period=10s --retries=4 CMD echo | nc -z ${IP%% *} ${PORT} || exit 1
+HEALTHCHECK --interval=5m --timeout=10s --start-period=10s --retries=3 CMD /usr/bin/python3 /usr/bin/healthcheck.py
 
 ENTRYPOINT [ "/usr/bin/python3", "-u", "/usr/bin/entrypoint.py" ]
diff --git a/docker/docker-py3-kms/requirements.txt b/docker/docker-py3-kms/requirements.txt
index 7bdfb22..0c301de 100644
--- a/docker/docker-py3-kms/requirements.txt
+++ b/docker/docker-py3-kms/requirements.txt
@@ -1,5 +1,5 @@
 dnspython==2.2.1
 tzlocal==4.2
 
-Flask==2.1.2
+Flask==2.3.2
 gunicorn==20.1.0
\ No newline at end of file
diff --git a/docker/entrypoint.py b/docker/entrypoint.py
index 34a7e9a..8035cd0 100755
--- a/docker/entrypoint.py
+++ b/docker/entrypoint.py
@@ -13,22 +13,10 @@ import time
 
 PYTHON3 = '/usr/bin/python3'
 dbPath = os.path.join(os.sep, 'home', 'py-kms', 'db') # Do not include the database file name, as we must correct the folder permissions (the db file is recursively reachable)
-log_level_bootstrap = log_level = os.getenv('LOGLEVEL', 'INFO')
-if log_level_bootstrap == "MININFO":
-  log_level_bootstrap = "INFO"
-loggersrv = logging.getLogger('logsrv')
-loggersrv.setLevel(log_level_bootstrap)
-streamhandler = logging.StreamHandler(sys.stdout)
-streamhandler.setLevel(log_level_bootstrap)
-formatter = logging.Formatter(fmt = '\x1b[94m%(asctime)s %(levelname)-8s %(message)s',
-                              datefmt = '%a, %d %b %Y %H:%M:%S',)
-streamhandler.setFormatter(formatter)
-loggersrv.addHandler(streamhandler)
 
-
-def change_uid_grp():
+def change_uid_grp(logger):
   if os.geteuid() != 0:
-    loggersrv.info(f'not root user, cannot change uid/gid.')
+    logger.info(f'not root user, cannot change uid/gid.')
     return None
   user_db_entries = pwd.getpwnam("py-kms")
   user_grp_db_entries = grp.getgrnam("users")
@@ -40,43 +28,52 @@ def change_uid_grp():
   os.chown("/usr/bin/start.py", new_uid, new_gid)
   if os.path.isdir(dbPath):
     # Corret permissions recursively, as to access the database file, also its parent folder must be accessible
-    loggersrv.debug(f'Correcting owner permissions on {dbPath}.')
+    logger.debug(f'Correcting owner permissions on {dbPath}.')
     os.chown(dbPath, new_uid, new_gid)
     for root, dirs, files in os.walk(dbPath):
       for dName in dirs:
         dPath = os.path.join(root, dName)
-        loggersrv.debug(f'Correcting owner permissions on {dPath}.')
+        logger.debug(f'Correcting owner permissions on {dPath}.')
         os.chown(dPath, new_uid, new_gid)
       for fName in files:
         fPath = os.path.join(root, fName)
-        loggersrv.debug(f'Correcting owner permissions on {fPath}.')
+        logger.debug(f'Correcting owner permissions on {fPath}.')
         os.chown(fPath, new_uid, new_gid)
-    loggersrv.debug(subprocess.check_output(['ls', '-la', dbPath]).decode())
+    logger.debug(subprocess.check_output(['ls', '-la', dbPath]).decode())
   if 'LOGFILE' in os.environ and os.path.exists(os.environ['LOGFILE']):
     # Oh, the user also wants a custom log file -> make sure start.py can access it by setting the correct permissions (777)
     os.chmod(os.environ['LOGFILE'], 0o777)
-    loggersrv.error(str(subprocess.check_output(['ls', '-la', os.environ['LOGFILE']])))
-  loggersrv.info("Setting gid to '%s'." % str(new_gid))
+    logger.error(str(subprocess.check_output(['ls', '-la', os.environ['LOGFILE']])))
+  logger.info("Setting gid to '%s'." % str(new_gid))
   os.setgid(new_gid)
 
-  loggersrv.info("Setting uid to '%s'." % str(new_uid))
+  logger.info("Setting uid to '%s'." % str(new_uid))
   os.setuid(new_uid)
 
-
-def change_tz():
+def change_tz(logger):
   tz = os.getenv('TZ', 'etc/UTC')
   # TZ is not symlinked and defined TZ exists
   if tz not in os.readlink('/etc/localtime') and os.path.isfile('/usr/share/zoneinfo/' + tz) and hasattr(time, 'tzset'):
-    loggersrv.info("Setting timzeone to %s" % tz )
+    logger.info("Setting timzeone to %s" % tz )
     # time.tzet() should be called on Unix, but doesn't exist on Windows.
     time.tzset()
 
-# Main
-if (__name__ == "__main__"):
+if __name__ == "__main__":
+  log_level_bootstrap = log_level = os.getenv('LOGLEVEL', 'INFO')
+  if log_level_bootstrap == "MININFO":
+    log_level_bootstrap = "INFO"
+  loggersrv = logging.getLogger('entrypoint.py')
+  loggersrv.setLevel(log_level_bootstrap)
+  streamhandler = logging.StreamHandler(sys.stdout)
+  streamhandler.setLevel(log_level_bootstrap)
+  formatter = logging.Formatter(fmt = '\x1b[94m%(asctime)s %(levelname)-8s %(message)s', datefmt = '%a, %d %b %Y %H:%M:%S',)
+  streamhandler.setFormatter(formatter)
+  loggersrv.addHandler(streamhandler)
   loggersrv.info("Log level: %s" % log_level)
   loggersrv.debug("user id: %s" % os.getuid())
-  change_tz()
-  childProcess = subprocess.Popen(PYTHON3 + " -u /usr/bin/start.py", preexec_fn=change_uid_grp(), shell=True)
+
+  change_tz(loggersrv)
+  childProcess = subprocess.Popen(PYTHON3 + " -u /usr/bin/start.py", preexec_fn=change_uid_grp(loggersrv), shell=True)
   def shutdown(signum, frame):
     loggersrv.info("Received signal %s, shutting down..." % signum)
     childProcess.terminate() # This will also cause communicate() from below to continue
diff --git a/docker/healthcheck.py b/docker/healthcheck.py
new file mode 100755
index 0000000..0ad45ca
--- /dev/null
+++ b/docker/healthcheck.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python3 -u
+import os
+import sys
+import logging
+
+def do_check(logger):
+  import socket
+  listen_ip = os.environ.get('IP', '::').split()
+  listen_ip.insert(0, '127.0.0.1') # always try to connect to localhost first
+  listen_port = os.environ.get('PORT', '1688')
+  for ip in listen_ip:
+    try:
+      s = socket.socket(socket.AF_INET6 if ':' in ip else socket.AF_INET, socket.SOCK_STREAM)
+      s.settimeout(1) # 1 second timeout
+      address = ip if ':' in ip else (ip, int(listen_port))
+      logger.debug(f"Trying to connect to {address}...")
+      s.connect(address)
+      s.close()
+      return True
+    except:
+      pass
+  return False # no connection could be established
+
+
+if __name__ == '__main__':
+  log_level_bootstrap = log_level = os.getenv('LOGLEVEL', 'INFO')
+  if log_level_bootstrap == "MININFO":
+    log_level_bootstrap = "INFO"
+  loggersrv = logging.getLogger('healthcheck.py')
+  loggersrv.setLevel(log_level_bootstrap)
+  streamhandler = logging.StreamHandler(sys.stdout)
+  streamhandler.setLevel(log_level_bootstrap)
+  formatter = logging.Formatter(fmt='\x1b[94m%(asctime)s %(levelname)-8s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S')
+  streamhandler.setFormatter(formatter)
+  loggersrv.addHandler(streamhandler)
+  
+  sys.exit(0 if do_check(loggersrv) else 1)
diff --git a/docker/start.py b/docker/start.py
old mode 100644
new mode 100755
index fd8a546..f5e2df3
--- a/docker/start.py
+++ b/docker/start.py
@@ -21,15 +21,12 @@ argumentVariableMapping = {
 }
 
 db_path = os.path.join(os.sep, 'home', 'py-kms', 'db', 'pykms_database.db')
-log_level_bootstrap = log_level = os.environ.get('LOGLEVEL', 'INFO')
-if log_level_bootstrap == "MININFO":
-  log_level_bootstrap = "INFO"
 log_file = os.environ.get('LOGFILE', 'STDOUT')
 listen_ip = os.environ.get('IP', '::').split()
 listen_port = os.environ.get('PORT', '1688')
-want_webui = os.environ.get('WEBUI', '0')
+want_webui = os.environ.get('WEBUI', '0') == '1' # if the variable is not provided, we assume the user does not want the webui
 
-def start_kms():
+def start_kms(logger):
   # Make sure the full path to the db exists
   if want_webui and not os.path.exists(os.path.dirname(db_path)):
     os.makedirs(os.path.dirname(db_path), exist_ok=True)
@@ -40,16 +37,16 @@ def start_kms():
     if env in os.environ and os.environ.get(env) != '':
       command.append(arg)
       command.append(os.environ.get(env))
+  if want_webui: # add this command directly before the "connect" subparser - otherwise you'll get silent crashes!
+    command.append('-s')
+    command.append(db_path)
   if len(listen_ip) > 1:
     command.append("connect")
     for i in range(1, len(listen_ip)):
       command.append("-n")
       command.append(listen_ip[i] + "," + listen_port)
-  if want_webui:
-    command.append('-s')
-    command.append(db_path)
 
-  loggersrv.debug("server_cmd: %s" % (" ".join(str(x) for x in command).strip()))
+  logger.debug("server_cmd: %s" % (" ".join(str(x) for x in command).strip()))
   pykms_process = subprocess.Popen(command)
   pykms_webui_process = None
 
@@ -63,7 +60,7 @@ def start_kms():
       pykms_webui_env['PYKMS_VERSION_PATH'] = '/VERSION'
       pykms_webui_process = subprocess.Popen(['gunicorn', '--log-level', os.environ.get('LOGLEVEL'), 'pykms_WebUI:app'], env=pykms_webui_env)
   except Exception as e:
-    loggersrv.error("Failed to start webui: %s" % e)
+    logger.error("Failed to start webui (ignoring and continuing anyways): %s" % e)
 
   try:
     pykms_process.wait()
@@ -79,14 +76,17 @@ def start_kms():
 
 
 # Main
-if (__name__ == "__main__"):
-  loggersrv = logging.getLogger('logsrv')
+if __name__ == "__main__":
+  log_level_bootstrap = log_level = os.environ.get('LOGLEVEL', 'INFO')
+  if log_level_bootstrap == "MININFO":
+    log_level_bootstrap = "INFO"
+  loggersrv = logging.getLogger('start.py')
   loggersrv.setLevel(log_level_bootstrap)
   streamhandler = logging.StreamHandler(sys.stdout)
   streamhandler.setLevel(log_level_bootstrap)
-  formatter = logging.Formatter(fmt='\x1b[94m%(asctime)s %(levelname)-8s %(message)s',
-                                datefmt='%a, %d %b %Y %H:%M:%S')
+  formatter = logging.Formatter(fmt='\x1b[94m%(asctime)s %(levelname)-8s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S')
   streamhandler.setFormatter(formatter)
   loggersrv.addHandler(streamhandler)
   loggersrv.debug("user id: %s" % os.getuid())
-  start_kms()
+
+  start_kms(loggersrv)
diff --git a/docs/Getting Started.md b/docs/Getting Started.md
index d66a051..f066153 100644
--- a/docs/Getting Started.md	
+++ b/docs/Getting Started.md	
@@ -46,9 +46,9 @@ services:
       - 1688:1688
       - 8080:8080
     environment:
-      - IP='::'
-      - HWID=RANDOM
-      - LOGLEVEL=INFO
+      IP: "::"
+      HWID: RANDOM
+      LOGLEVEL: INFO
     restart: always
     volumes:
       - ./db:/home/py-kms/db
diff --git a/docs/Usage.md b/docs/Usage.md
index 6586386..fbe590d 100644
--- a/docs/Usage.md
+++ b/docs/Usage.md
@@ -28,7 +28,7 @@ You may want to select the locale ID of your country instead.
 See [here](https://msdn.microsoft.com/en-us/library/cc233982.aspx) for a list of valid _LCIDs_.
 
     -w or --hwid <HWID>
-> Use specified _HWID_ for all products. Use `-w RANDOM` to generate a random HWID. Default is _364F463A8863D35F_.
+> Use specified _HWID_ for all products. Use `-w RANDOM` to generate a random HWID. Default is random.
 Hardware Identification is a security measure used by Microsoft upon the activation of 
 the Windows operating system. As part of the Product Activation system, a unique
 HWID number is generated when the operating system is first installed. The _HWID_ identifies the hardware components that the system 
@@ -232,8 +232,8 @@ ENV RENEWAL_INTERVAL 10080
 # hwid
 # Use this flag to specify a HWID. 
 # The HWID must be an 16-character string of hex characters.
-# The default is "364F463A8863D35F" or type "RANDOM" to auto generate the HWID.
-ENV HWID 364F463A8863D35F
+# The default is "RANDOM" to auto-generate the HWID or type a specific value.
+ENV HWID RANDOM
 
 # log level ("CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG")
 # Use this flag to set a Loglevel. The default is "ERROR".
diff --git a/py-kms/pykms_Server.py b/py-kms/pykms_Server.py
index f506455..cbe96a8 100755
--- a/py-kms/pykms_Server.py
+++ b/py-kms/pykms_Server.py
@@ -192,8 +192,8 @@ for server OSes and Office >=5', 'def' : None, 'des' : "clientcount"},
         'sql'        : {'help' : 'Use this option to store request information from unique clients in an SQLite database. Deactivated by default.', 'def' : False,
                         'file': os.path.join('.', 'pykms_database.db'), 'des' : "sqlite"},
         'hwid'       : {'help' : 'Use this option to specify a HWID. The HWID must be an 16-character string of hex characters. \
-The default is \"364F463A8863D35F\" or type \"RANDOM\" to auto generate the HWID.',
-                        'def' : "364F463A8863D35F", 'des' : "hwid"},
+Type \"RANDOM\" to auto-generate the HWID.',
+                        'def' : "RANDOM", 'des' : "hwid"},
         'time0'      : {'help' : 'Maximum inactivity time (in seconds) after which the connection with the client is closed. If \"None\" (default) serve forever.',
                         'def' : None, 'des' : "timeoutidle"},
         'time1'      : {'help' : 'Set the maximum time to wait for sending / receiving a request / response. Default is no timeout.',
@@ -481,7 +481,7 @@ class kmsServerHandler(socketserver.BaseRequestHandler):
                         try:
                                 self.data = self.request.recv(1024)
                                 if self.data == '' or not self.data:
-                                        pretty_printer(log_obj = loggersrv.warning,
+                                        pretty_printer(log_obj = loggersrv.debug, # use debug, as the healthcheck will spam this
                                                        put_text = "{reverse}{yellow}{bold}No data received.{end}")
                                         break
                         except socket.error as e: