diff --git a/server/Helpers/apply_settings.mjs b/server/Helpers/apply_settings.mjs
new file mode 100644
index 0000000..c8a065e
--- /dev/null
+++ b/server/Helpers/apply_settings.mjs
@@ -0,0 +1,21 @@
+"use strict";
+
+/**
+ * Recursively overwrites 1 settings object with another.
+ * Ported from PHP: https://gist.github.com/00f1b9b1fd6ca0610b780587f11ede4e#file-applysettings-php
+ * @param  {object} def    The default settings object to overwrite.
+ * @param  {object} custom The settings to use when overwriting.
+ */
+function apply_settings(def, custom) {
+    // Loop over each of the custom settings
+    for(let key in custom) {
+        // If the property isn't an object, then it's probably a setting
+        // We should overwrite the existing default setting with the custom one.
+        if(typeof custom[key] != "object")
+            def[key] = custom[key];
+        else // It's an object! We should recurse over it.
+            apply_settings(def[key], custom[key]);
+    }
+}
+
+export default apply_settings;
diff --git a/server/Models/Reading.mjs b/server/Models/Reading.mjs
index 8699d61..4d7a26a 100644
--- a/server/Models/Reading.mjs
+++ b/server/Models/Reading.mjs
@@ -1,5 +1,6 @@
 "use strict";
 
+import RSSIRepo from '../Repos.SQLite/RSSIRepo.mjs';
 import RSSI from './RSSI.mjs';
 
 /**
diff --git a/server/Repos.SQLite/ReadingRepo.mjs b/server/Repos.SQLite/ReadingRepo.mjs
index c084f9c..6dfb8d8 100644
--- a/server/Repos.SQLite/ReadingRepo.mjs
+++ b/server/Repos.SQLite/ReadingRepo.mjs
@@ -8,11 +8,20 @@ class ReadingRepo {
 		this.db = get_instance();
 		this.RSSIRepo = in_RSSIRepo;
 		
-		this.insert_query = this.db.prepare("INSERT INTO readings")
+		this.insert_query = this.db.prepare(`INSERT INTO readings (
+			id,
+			lat, long,
+			data_rate_id, code_rate, bit_rate
+		) VALUES (
+			:id,
+			:lat,
+			:long,
+			:data_rate_id, :code_rate, :bit_rate
+		)`);
 	}
 	
 	insert(reading) {
-		this.db.
+		this.insert_query
 	}
 }
 
diff --git a/server/bootstrap/container.mjs b/server/bootstrap/container.mjs
new file mode 100644
index 0000000..3fc4dae
--- /dev/null
+++ b/server/bootstrap/container.mjs
@@ -0,0 +1,18 @@
+"use strict";
+
+import a from 'awilix';
+
+import database_init from '../bootstrap/database_init.mjs';
+import TTNAppServer from '../ttn-app-server/TTNAppServer.mjs';
+
+const c = a.createContainer({
+	injectionMode: a.InjectionMode.PROXY
+});
+
+c.register({
+	database: a.asFunction(database_init).singleton(),
+	TTNAppServer: a.asClass(TTNAppServer),
+});
+c.loadModules(
+
+export default c;
diff --git a/server/Helpers/Database.mjs b/server/bootstrap/database_init.mjs
similarity index 68%
rename from server/Helpers/Database.mjs
rename to server/bootstrap/database_init.mjs
index 3a80b72..2d14c14 100644
--- a/server/Helpers/Database.mjs
+++ b/server/bootstrap/database_init.mjs
@@ -5,14 +5,11 @@ import Database from 'better-sqlite3';
 
 var db = null;
 
-async function init(filename, options) {
+async function init({ settings: { database: { filename, options } } }) {
 	db = new Database(filename, options);
 	db.exec(await fs.promises.readFile("../db_template.sql", "utf8"));
-}
-
-function get_instance() {
 	return db;
 }
 
 
-export { init, get_instance };
+export default init;
diff --git a/server/bootstrap/settings.mjs b/server/bootstrap/settings.mjs
new file mode 100644
index 0000000..1944bc2
--- /dev/null
+++ b/server/bootstrap/settings.mjs
@@ -0,0 +1,26 @@
+"use strict";
+
+import fs from 'fs';
+
+import toml from '@iarna/toml';
+
+import c from './container.mjs';
+import apply_settings from './Helpers/apply_settings.mjs';
+
+
+let filename_default = "../settings.default.toml",
+	filename_custom = "../../settings.toml";
+
+if(!fs.existsSync(filename_custom))
+	fs.writeFileSync(filename_custom, `# Custom settings file. This file overrides server/settings.default.toml - refer there of example of settings you can override.\n\n`);
+
+let settings = toml.parse(fs.readFileSync(filename_default, "utf-8")),
+	settings_override = toml.parse(fs.readFileSync("../../settings.custom.toml", "utf-8"));
+
+apply_settings(settings, settings_override);
+
+c.register({
+	settings: a.asValue(settings)
+});
+
+export default settings;
diff --git a/server/index.mjs b/server/index.mjs
index a05e592..c51c25c 100755
--- a/server/index.mjs
+++ b/server/index.mjs
@@ -1,17 +1,13 @@
 #!/usr/bin/env node
 "use strict";
 
+// 1: Setup & Imports
 import ansi from './Helpers/Ansi.mjs';
+import c from './bootstrap/container.mjs';
 
 import show_help from './help.mjs';
 import TTNAppServer from './ttn-app-server/TTNAppServer.mjs';
-
-// 1: Setup
-const settings = {
-	program_name: "LoRaWAN Signal Mapper",
-	version: "v0.1",
-	description: "assists in mapping LoRaWAN signal coverage"
-};
+import settings from './bootstrap/settings.mjs';
 
 // 2: CLI Argument Parsing
 let args = process.argv.slice(2); // Slice out the node binary name and the filename
diff --git a/server/package-lock.json b/server/package-lock.json
index 4fc7126..12e3f72 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -4,6 +4,11 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
+    "@iarna/toml": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.3.tgz",
+      "integrity": "sha512-FmuxfCuolpLl0AnQ2NHSzoUKWEJDFl63qXjzdoWBVyFCXzMGm1spBzk7LeHNoVCiWCF7mRVms9e6jEV9+MoPbg=="
+    },
     "@types/better-sqlite3": {
       "version": "5.4.0",
       "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-5.4.0.tgz",
@@ -55,6 +60,15 @@
       "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
       "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
     },
+    "awilix": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/awilix/-/awilix-4.2.2.tgz",
+      "integrity": "sha512-44T2gp/vKk+TROZYSXhUws56PvCsrMW0l86qaU49nFe9Pt51LgJdvfu7ek1BP48SX2m7tYawnaFEPPy1ZOc8gA==",
+      "requires": {
+        "camel-case": "^3.0.0",
+        "glob": "^7.1.3"
+      }
+    },
     "babel-runtime": {
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@@ -123,6 +137,15 @@
         "readable-stream": "> 1.0.0 < 3.0.0"
       }
     },
+    "camel-case": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
+      "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
+      "requires": {
+        "no-case": "^2.2.0",
+        "upper-case": "^1.1.1"
+      }
+    },
     "camelcase": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
@@ -1063,6 +1086,11 @@
       "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz",
       "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s="
     },
+    "lower-case": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
+      "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw="
+    },
     "minimatch": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -1180,6 +1208,14 @@
       "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
       "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
     },
+    "no-case": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
+      "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
+      "requires": {
+        "lower-case": "^1.1.1"
+      }
+    },
     "node-fetch": {
       "version": "1.7.3",
       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
@@ -1579,6 +1615,11 @@
         "through2-filter": "^3.0.0"
       }
     },
+    "upper-case": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
+      "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg="
+    },
     "util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
diff --git a/server/package.json b/server/package.json
index 959cdf5..77d724a 100644
--- a/server/package.json
+++ b/server/package.json
@@ -19,7 +19,9 @@
   "author": "Starbeamrainbowlabs",
   "license": "MPL-2.0",
   "dependencies": {
+    "@iarna/toml": "^2.2.3",
     "@types/better-sqlite3": "^5.4.0",
+    "awilix": "^4.2.2",
     "better-sqlite3": "^5.4.0",
     "ttn": "^2.3.2"
   }
diff --git a/server/settings.default.toml b/server/settings.default.toml
new file mode 100644
index 0000000..fefe884
--- /dev/null
+++ b/server/settings.default.toml
@@ -0,0 +1,16 @@
+# Default settings file.
+# 
+# DO NOT EDIT THIS FILE. Instead edit ../settings.toml (or create it if it doesn't exist yet).
+
+program_name = "LoRaWAN Signal Mapper"
+version = "v0.1"
+description = "assists in mapping LoRaWAN signal coverage"
+
+[database]
+### Database settings ###
+
+# The path to the sqlite database file. If it doesn't exist it will be created.
+filename = "lorawan.sqlite"
+
+# The options to pass to better-sqlite3. You probably don't need to change this.
+[database.options]
