diff --git a/files/hedgedoc-util.py b/files/hedgedoc-util.py
old mode 100644
new mode 100755
index 5f27a6c1c9ab4cc92e2206cae26aaa8d45c58223..4088070a7b45b31864ab0baba90c7f99253a5747
--- a/files/hedgedoc-util.py
+++ b/files/hedgedoc-util.py
@@ -12,17 +12,21 @@ import pymysql.cursors
 import configparser
 
 class GlobalState():
-	def __init__(self, outputformat):
-		self.outputformat = outputformat
-		self.config = self._load_config()
-		self.db = self._get_connection()
+	def __init__(self, options):
+		self.config = self._load_config(options.get('config'))
+		self.config.update(self._clean_config(options))
+		try:
+			self.db = self._get_connection()
+		except Exception as e:
+			click.echo("Database connection failed: {}".format(repr(e)))
+			sys.exit(2)
 		self._check_schema()
 
 	def _get_connection(self):
-		return pymysql.connect(host=self.config['db']['host'],
-			user=self.config['db']['username'],
-			password=self.config['db']['password'],
-			database=self.config['db']['database'],
+		return pymysql.connect(host=self.config['dbhost'],
+			user=self.config['dbuser'],
+			password=self.config['dbpw'],
+			database=self.config['dbname'],
 			charset='utf8mb4',
 			cursorclass=pymysql.cursors.DictCursor)
 
@@ -30,18 +34,34 @@ class GlobalState():
 		with self.db.cursor() as cursor:
 			cursor.execute('SELECT name from SequelizeMeta ORDER BY name ASC')
 			schema = ','.join([i['name'] for i in cursor.fetchall()])
-		if schema != self.config['db']['schema']:
+		if schema != self.config['dbschema']:
 			click.echo("Unsupportet db schema: {}".format(schema))
 			sys.exit(2)
 
-	def _load_config(self):
-		config = configparser.ConfigParser()
-		config.read('/usr/local/etc/hedgedoc-util/hedgedoc-util.cfg')
-		return config
+	def _load_config(self, path):
+		result = {}
+		try:
+			with open(path, 'r') as f:
+				for line in f.readlines():
+					if line.startswith('#'):
+						continue
+					data = line.replace('\n', '').split('=')
+					if len(data) != 2:
+						continue
+					result[data[0]] = data[1]
+		except:
+			return {}
+		return result
+	def _clean_config(self, d):
+		return {
+				k.replace('HEDGEDOCUTIL_','').lower():v
+				for k, v in d.items()
+				if v is not None
+			}
 
 def _default_template_mail():
 	ctx = click.get_current_context().obj
-	return ctx.config['templates']['mail']
+	return ctx.config['pad_mail_template']
 
 def _date_json_handler(obj):
 	return obj.isoformat() if hasattr(obj, 'isoformat') else obj
@@ -145,12 +165,12 @@ def tsv_escape(value):
 	return value.replace('\\', '\\\\').replace('\t', '\\t').replace('\n', '\\n').replace('\r', '\\r')
 
 def output_object(obj):
-	ctx = click.get_current_context().obj
-	if ctx.outputformat == "text":
+	outputformat = click.get_current_context().obj.config['output']
+	if outputformat == "text":
 		click.echo(obj)
-	elif ctx.outputformat == "json":
+	elif outputformat == "json":
 		click.echo(json.dumps(obj, default=_date_json_handler))
-	elif ctx.outputformat in ("tsv", "tsv-noheader"):
+	elif outputformat in ("tsv", "tsv-noheader"):
 		if not obj:
 			return
 		if type(obj) is dict:
@@ -158,17 +178,23 @@ def output_object(obj):
 		if not type(obj) is list:
 			click.echo(obj)
 		header = obj[0].keys()
-		if not ctx.outputformat == "tsv-noheader":
+		if not outputformat == "tsv-noheader":
 			click.echo('\t'.join(header))
 		for i in obj:
 			click.echo('\t'.join([ tsv_escape(i.get(j,'')) for j in header ]))
 
 
 @click.group()
-@click.option('-o', '--output', type=click.Choice(['text', 'json', 'tsv', 'tsv-noheader']), default='text', help='Select output format', show_default=True)
+@click.option('-o', '--output', type=click.Choice(['text', 'json', 'tsv', 'tsv-noheader']), default='text', help='Select output format', show_default=True, show_envvar=True)
+@click.option('--config', default='/usr/local/etc/hedgedoc-util/hedgedoc-util.cfg', type=click.Path(), help='Config to load db and template default settings from', show_envvar=True, show_default=True)
+@click.option('--dbuser', help='User name used for the db connection', show_envvar=True)
+@click.option('--dbpw', help='Password used for the db connection', show_envvar=True)
+@click.option('--dbname', help='Database used', show_envvar=True)
+@click.option('--dbhost', help='Host the db is running on', show_envvar=True)
+@click.option('--dbschema', help='Schema string to verify the db schema against', show_envvar=True)
 @click.pass_context
-def cli(ctx, output):
-	ctx.obj = GlobalState(output)
+def cli(ctx, **kwargs):
+	ctx.obj = GlobalState(kwargs)
 
 @cli.command(name="test-connect", help="Checks wether the connection to the db works and if we support the used schema")
 @click.pass_obj
@@ -185,9 +211,9 @@ def cli_pad():
 	pass
 
 @cli_pad.command(name="list", help="List all pads")
-@click.option('-c', '--columns', default=['id'], type=click.Choice(['id', 'title', 'ownerId', 'createdAt', 'updatedAt', 'shortid', 'permission', 'viewcount', 'lastchangeuserId', 'lastchangeAt', 'alias', 'deletedAt', 'authorship']), help="Select what data to display. Can be passed multiple times.", multiple=True, show_default=True)
-@click.option('--last-change-older', type=click.INT, default=0, help='Only list those pads which are older than this value. In days.')
-@click.option('--owner', type=click.STRING, default='', help='Only list pads with this owner, pass the user id')
+@click.option('-c', '--columns', default=['id'], type=click.Choice(['id', 'title', 'content', 'ownerId', 'createdAt', 'updatedAt', 'shortid', 'permission', 'viewcount', 'lastchangeuserId', 'lastchangeAt', 'alias', 'deletedAt', 'authorship']), help="Select what data to display. Can be passed multiple times.", multiple=True, show_default=True, show_envvar=True)
+@click.option('--last-change-older', type=click.INT, default=0, help='Only list those pads which are older than this value. In days.', show_envvar=True)
+@click.option('--owner', type=click.STRING, default='', help='Only list pads with this owner, pass the user id', show_envvar=True)
 @click.pass_obj
 def _pad_list(obj, columns, last_change_older, owner):
 	output_object(pad_list(obj.db, columns, last_change_older=last_change_older, owner=owner))
@@ -211,8 +237,8 @@ def _pad_get_content(obj, id):
 	output_object(pad_get_content(obj.db, id))
 
 @cli_pad.command(name="mail", help="Send a pad to its creator via mail")
-@click.option('--template', type=click.File(), default=_default_template_mail, help='The template file to use', show_default=True)
-@click.option('--convert', default=['markdown'], type=click.Choice(['markdown', 'dokuwiki']), help="Add the pad as attachment to the mail. Can be passed multiple times.", multiple=True, show_default=True)
+@click.option('--template', type=click.File(), default=_default_template_mail, help='The template file to use', show_default=True, show_envvar=True)
+@click.option('--convert', default=['markdown'], type=click.Choice(['markdown', 'dokuwiki']), help="Add the pad as attachment to the mail. Can be passed multiple times.", multiple=True, show_default=True, show_envvar=True)
 @click.argument('id')
 @click.pass_obj
 def _pad_mail(obj, id, template, convert):
@@ -233,7 +259,7 @@ def cli_user():
 	pass
 
 @cli_user.command(name="list", help="List all user")
-@click.option('-c', '--columns', default=['id'], type=click.Choice(['id', 'profileid', 'profile', 'history', 'createdAt', 'updatedAt', 'accessToken', 'refreshToken', 'email', 'password', 'deleteToken']), help="Select what data to display. Can be passed multiple times.", multiple=True, show_default=True)
+@click.option('-c', '--columns', default=['id'], type=click.Choice(['id', 'profileid', 'profile', 'history', 'createdAt', 'updatedAt', 'accessToken', 'refreshToken', 'email', 'password', 'deleteToken']), help="Select what data to display. Can be passed multiple times.", multiple=True, show_default=True, show_envvar=True)
 @click.pass_obj
 def _user_list(obj, columns):
 	output_object(user_list(obj.db, columns))
@@ -251,4 +277,4 @@ def _user_get_mail(obj, id):
 	output_object(user_get_mail(obj.db, id))
 
 if __name__ == '__main__':
-	cli()
+	cli(auto_envvar_prefix='HEDGEDOCUTIL')
diff --git a/templates/hedgedoc-util.cfg.j2 b/templates/hedgedoc-util.cfg.j2
index 05a06c749108e14c4b770a3c2a87a54216bfcdaa..84e4bab082695f2f16f650d1151d02db28adf454 100644
--- a/templates/hedgedoc-util.cfg.j2
+++ b/templates/hedgedoc-util.cfg.j2
@@ -1,8 +1,6 @@
-[db]
-host=localhost
-database=hedgedoc
-username=hedgedoc
-password={{ hedgedoc.db.pw }}
-schema=20150504155329-create-users.js,20150508114741-create-notes.js,20150515125813-create-temp.js,20150702001020-update-to-0_3_1.js,20150915153700-change-notes-title-to-text.js,20160112220142-note-add-lastchange.js,20160420180355-note-add-alias.js,20160515114000-user-add-tokens.js,20160607060246-support-revision.js,20160703062241-support-authorship.js,20161009040430-support-delete-note.js,20161201050312-support-email-signin.js,20171009121200-longtext-for-mysql.js,20180209120907-longtext-of-authorship.js,20180306150303-fix-enum.js,20180326103000-use-text-in-tokens.js,20180525153000-user-add-delete-token.js,20200321153000-fix-account-deletion.js
-[templates]
-mail=/usr/local/etc/hedgedoc-util/mail-std.tpl
+HEDGEDOCUTIL_DBHOSTt=localhost
+HEDGEDOCUTIL_DBNAME=hedgedoc
+HEDGEDOCUTIL_DBUSER=hedgedoc
+HEDGEDOCUTIL_DBPW={{ hedgedoc.db.pw }}
+HEDGEDOCUTIL_DBSCHEMA=20150504155329-create-users.js,20150508114741-create-notes.js,20150515125813-create-temp.js,20150702001020-update-to-0_3_1.js,20150915153700-change-notes-title-to-text.js,20160112220142-note-add-lastchange.js,20160420180355-note-add-alias.js,20160515114000-user-add-tokens.js,20160607060246-support-revision.js,20160703062241-support-authorship.js,20161009040430-support-delete-note.js,20161201050312-support-email-signin.js,20171009121200-longtext-for-mysql.js,20180209120907-longtext-of-authorship.js,20180306150303-fix-enum.js,20180326103000-use-text-in-tokens.js,20180525153000-user-add-delete-token.js,20200321153000-fix-account-deletion.js
+HEDGEDOCUTIL_PAD_MAIL_TEMPLATE=/usr/local/etc/hedgedoc-util/mail-std.tpl