diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3030d6b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,6 @@
+build:
+	docker-compose up --build -d
+
+clean:
+	docker-compose down
+	docker system prune -fa
diff --git a/README.md b/README.md
index 8ef1b6d..acce2a1 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,10 @@
 ## The Things Network Tracker (TTN-Tracker)
 
+This is a [Flask](http://flask.pocoo.org/) app served via [Gunicorn](https://github.com/benoitc/gunicorn) and [Nginx](http://nginx.org/) using [docker](https://www.docker.com/) containers orchestrated by docker-compose.
+
 For use with [kizniche/ttgo-tbeam-ttnmapper](https://github.com/kizniche/ttgo-tbeam-ttnmapper) for the T-Beam TTGO (tracker node) that transmits data to [The Things Network](https://thethingsnetwork.org) (TTN) for [TTN Mapper](https://ttnmapper.org/).
 
-This Flask app hosts a web-enabled front end using [gunicorn](https://github.com/benoitc/gunicorn) and [nginx](http://nginx.org/). It pulls coordinate data acquired from the tracker node that's been stored on TTN. It stores these coordinates in an SQLite database and displays the coordinates on a map ([leaflet](https://github.com/Leaflet/Leaflet)) in your web browser. This is useful for testing the signal range from gateways while driving, so you can see when and where your signal was able to reach a gateway.
+This app pulls coordinate data acquired from the tracker node that's been stored on TTN. It stores these coordinates in an SQLite database and displays the coordinates on a map ([leaflet](https://github.com/Leaflet/Leaflet)) in your web browser. This is useful for testing the signal range from gateways while driving, so you can see when and where your signal was able to reach a gateway.
 
 This is very similar to the TTN Mapper frontend, however TTN Mapper takes a long time to update the data points on its map. This software runs locally on your own hardware and responds instantly to new data on TTN, making it a good companion in your vehicle if you want to get instant updates as to whether your tracker node successfully communicated its coordinates or not.
 
@@ -15,28 +17,71 @@ Features include:
 
 ### Setup:
 
-I've succesfully set this up on a Raspberry Pi, but these instructions should work for any debian-variant operating system. Other systems you may have to adapt how you install the prerequisites.
+I've successfully set this up on a Raspberry Pi.
+
+Make sure you have your application set up on The Things Network with the integration "Data Storage". The integration "TTN Mapper" is optional but is recommended to be able to provide signal data to the public.
+
+### Install docker and docker-compose
+
+```
+curl -sSL https://get.docker.com | sh
+sudo pip install docker-compose
+```
+
+### Clone this repository
 
 ```
 git clone https://github.com/kizniche/ttn-tracker.git
 cd ttn-tracker
-sudo pip install virtualenv --upgrade
-PYTHON_BINARY_SYS_LOC="$(python3.5 -c "import os; print(os.environ['_'])")"
-virtualenv --system-site-packages -p ${PYTHON_BINARY_SYS_LOC} ./env
-./env/bin/pip install -r requirements.txt
-sudo ln -s /home/pi/ttn-tracker/flask_nginx.conf /etc/nginx/sites-enabled/ttn-tracker_nginx.config
-sudo service nginx restart
-sudo systemctl enable /home/pi/ttn-tracker/ttn-tracker.service
 ```
 
-Make sure you have your application set up on The Things Network with the integration "Data Storage". Edit config.py with your application API Key, application ID, Device ID(s), and gateway location(s). The integration "TTN Mapper" is optional but is recommended to be able to provide signal data to the public.
+### Edit the config file
 
-### Run
+Edit ttn-tracker/flask_app/config.py with your application API Key, application ID, Device ID(s), and gateway location(s) before building the docker image. If you need to edit this file after the image is created, you can rebuild the image (destroying data) or copy the new config file over the old while the flask_app container is running (see below).
 
-```sudo service ttn-tracker start```
+### Build and start the app
+
+This will build and start the app and keep it running across reboots.
+
+```sudo make build```
+
+### Stop app (preserving data)
+
+```sudo docker-compose stop```
+
+### Start app after stopping
+
+```sudo docker-compose start```
 
 ### Web Address
 
-Note: there is no security preventing someone from viewing this page if they happen to request "/dsf673bh" on the server (however, knowing this is the page is unlikely). Therefore, make sure you are comfortable with this or implement your own security measures such as not allowing port 5500 to be publicly accessible (connect to your home network via VPN to access the app) or add a login system such as [Flask-Login](https://github.com/maxcountryman/flask-login).
+Open a browser to this address, replacing IP_ADDRESS with the IP address of the system running the docker containers.
 
-http://127.0.0.1:5500/dsf673bh
+http://IP_ADDRESS:5550/dsf673bh
+
+Note: there is no security preventing someone from viewing this page if they happen to request "/dsf673bh" on the server (however, knowing this is the page is unlikely). Therefore, make sure you are comfortable with this or implement your own security measures such as not allowing port 5550 to be publicly accessible (connect to your home network via VPN to access the app) or add a login system such as [Flask-Login](https://github.com/maxcountryman/flask-login).
+
+### Notes
+
+#### Stop app and delete data (keep containers)
+
+```sudo docker-compose down```
+
+#### Stop app and delete containers
+
+```sudo docker-compose rm -fs```
+
+#### List docker containers
+
+```sudo docker ps```
+
+#### Start a shell in a docker container
+
+```sudo docker exec -i -t CONTAINER_ID /bin/bash```
+
+#### Copy files to/from a docker container
+
+```
+docker cp foo.txt CONTAINER_ID:/foo.txt
+docker cp CONTAINER_ID:/foo.txt foo.txt
+```
diff --git a/__init__.py b/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/config.py b/config.py
deleted file mode 100644
index 567490a..0000000
--- a/config.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Where the map initially loads
-start_lat = 35.978781
-start_lon = -77.855346
-
-# Where to store SQLite database
-path_db = '/home/pi/ttn-tracker/ttnmapper_retrieve.db'
-
-# TTN Application
-application = "ttn_application"
-app_key = "key ttn-account-TTN_APP_KEY"
-
-# Application devices
-devices = [
-    "device_01",
-    "device_02"
-]
-
-# Where to place gateway markers
-gateway_locations = [
-    ('Gateway 01', 35.978781, -77.855346),
-    ('Gateway 02', 35.978781, -77.655346)
-]
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..71fc4ef
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,21 @@
+version: "3"
+
+services:
+
+  flask_app:
+    container_name: flask_app
+    restart: always
+    build: ./flask_app
+    ports:
+      - "8000:8000"
+    command: gunicorn -w 1 --worker-class gthread --bind :8000 app:app
+
+
+  nginx:
+    container_name: nginx
+    restart: always
+    build: ./nginx
+    ports:
+      - "5550:5550"
+    depends_on:
+      - flask_app
diff --git a/flask_app/Dockerfile b/flask_app/Dockerfile
new file mode 100644
index 0000000..61c6c27
--- /dev/null
+++ b/flask_app/Dockerfile
@@ -0,0 +1,8 @@
+FROM python:3.6-slim-stretch
+
+RUN mkdir -pv /home/project/flask_app
+WORKDIR /home/project/flask_app
+COPY requirements.txt /home/project/flask_app
+RUN pip install --no-cache-dir -r requirements.txt
+
+COPY . /home/project/flask_app
diff --git a/app.py b/flask_app/app.py
similarity index 93%
rename from app.py
rename to flask_app/app.py
index 8abfd75..1e4db94 100644
--- a/app.py
+++ b/flask_app/app.py
@@ -6,27 +6,26 @@ from math import radians
 from math import sin
 from math import sqrt
 
+import os
 import requests
 from apscheduler.schedulers.background import BackgroundScheduler
-from flask import Flask
-from flask import render_template
-from flask_sqlalchemy import SQLAlchemy
-
 from config import app_key
 from config import application
+from config import bing_api_key
+from config import config_app
 from config import devices
 from config import gateway_locations
 from config import path_db
 from config import start_lat
 from config import start_lon
+from flask import Flask
+from flask import render_template
+from flask_sqlalchemy import SQLAlchemy
 
 logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s')
 logger = logging.getLogger(__name__)
 
-app = Flask(__name__, template_folder="./templates")
-
-app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///{db}'.format(db=path_db)
-app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
+app = config_app(Flask(__name__, template_folder="./templates"))
 db = SQLAlchemy(app)
 
 
@@ -66,10 +65,15 @@ class LastAcquisition(db.Model):
         return '<ID %r>' % self.id
 
 
+if not os.path.exists(path_db):
+    db.create_all()
+
+
 @app.route('/dsf673bh')
-def hello_world():
+def main_page():
     get_new_data()
     return render_template('map.html',
+                           bing_api_key=bing_api_key,
                            gateway_locations=gateway_locations,
                            location_data=Location.query.all(),
                            start_lat=start_lat,
@@ -147,4 +151,4 @@ def distance_coordinates(lat1, lon1, lat2, lon2):
 
 if __name__ == '__main__':
     db.create_all()
-    app.run(debug=True, host='0.0.0.0', port=5500)
+    app.run(debug=True, host='0.0.0.0', port=8000)
diff --git a/flask_app/config.py b/flask_app/config.py
new file mode 100644
index 0000000..9456195
--- /dev/null
+++ b/flask_app/config.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+# Where to store SQLite database
+path_db = '/home/project/ttn_tracker_database.db'
+
+# Where the map initially loads
+start_lat = 35.978781
+start_lon = -77.855346
+
+# TTN Application
+application = "ttn_application"
+app_key = "key ttn-account-TTN_APP_KEY"
+
+# Application devices
+devices = [
+    "device_01",
+    "device_02"
+]
+
+# Where to place gateway markers
+gateway_locations = [
+    ('Gateway 01', 35.978781, -77.855346),
+    ('Gateway 02', 35.978781, -77.655346)
+]
+
+bing_api_key = ''
+
+
+def config_app(app, **kwargs):
+    """Dash app configuration
+
+    Parameters
+    ----------
+    app: Dash app
+    debug: optional, default=False
+
+    Returns
+    -------
+    app: Dash app
+        With added css, ga and layout container with:
+        app-layout: main div, should not be a target of an ouput callback
+        page-content: container div, target for an ouput callback
+        url: Location, target of an input callback
+    """
+
+    if kwargs.get('debug', False):
+        app.server.debug = True
+
+    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///{db}'.format(db=path_db)
+    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
+
+    return app
diff --git a/requirements.txt b/flask_app/requirements.txt
similarity index 100%
rename from requirements.txt
rename to flask_app/requirements.txt
diff --git a/static/esri-leaflet.js b/flask_app/static/esri-leaflet.js
similarity index 100%
rename from static/esri-leaflet.js
rename to flask_app/static/esri-leaflet.js
diff --git a/static/leaflet-bing-layer.min.js b/flask_app/static/leaflet-bing-layer.min.js
similarity index 100%
rename from static/leaflet-bing-layer.min.js
rename to flask_app/static/leaflet-bing-layer.min.js
diff --git a/static/leaflet-measure/assets/cancel.png b/flask_app/static/leaflet-measure/assets/cancel.png
similarity index 100%
rename from static/leaflet-measure/assets/cancel.png
rename to flask_app/static/leaflet-measure/assets/cancel.png
diff --git a/static/leaflet-measure/assets/cancel.svg b/flask_app/static/leaflet-measure/assets/cancel.svg
similarity index 100%
rename from static/leaflet-measure/assets/cancel.svg
rename to flask_app/static/leaflet-measure/assets/cancel.svg
diff --git a/static/leaflet-measure/assets/cancel_@2X.png b/flask_app/static/leaflet-measure/assets/cancel_@2X.png
similarity index 100%
rename from static/leaflet-measure/assets/cancel_@2X.png
rename to flask_app/static/leaflet-measure/assets/cancel_@2X.png
diff --git a/static/leaflet-measure/assets/check.png b/flask_app/static/leaflet-measure/assets/check.png
similarity index 100%
rename from static/leaflet-measure/assets/check.png
rename to flask_app/static/leaflet-measure/assets/check.png
diff --git a/static/leaflet-measure/assets/check.svg b/flask_app/static/leaflet-measure/assets/check.svg
similarity index 100%
rename from static/leaflet-measure/assets/check.svg
rename to flask_app/static/leaflet-measure/assets/check.svg
diff --git a/static/leaflet-measure/assets/check_@2X.png b/flask_app/static/leaflet-measure/assets/check_@2X.png
similarity index 100%
rename from static/leaflet-measure/assets/check_@2X.png
rename to flask_app/static/leaflet-measure/assets/check_@2X.png
diff --git a/static/leaflet-measure/assets/focus.png b/flask_app/static/leaflet-measure/assets/focus.png
similarity index 100%
rename from static/leaflet-measure/assets/focus.png
rename to flask_app/static/leaflet-measure/assets/focus.png
diff --git a/static/leaflet-measure/assets/focus.svg b/flask_app/static/leaflet-measure/assets/focus.svg
similarity index 100%
rename from static/leaflet-measure/assets/focus.svg
rename to flask_app/static/leaflet-measure/assets/focus.svg
diff --git a/static/leaflet-measure/assets/focus_@2X.png b/flask_app/static/leaflet-measure/assets/focus_@2X.png
similarity index 100%
rename from static/leaflet-measure/assets/focus_@2X.png
rename to flask_app/static/leaflet-measure/assets/focus_@2X.png
diff --git a/static/leaflet-measure/assets/leaflet-measure.png b/flask_app/static/leaflet-measure/assets/leaflet-measure.png
similarity index 100%
rename from static/leaflet-measure/assets/leaflet-measure.png
rename to flask_app/static/leaflet-measure/assets/leaflet-measure.png
diff --git a/static/leaflet-measure/assets/rulers.png b/flask_app/static/leaflet-measure/assets/rulers.png
similarity index 100%
rename from static/leaflet-measure/assets/rulers.png
rename to flask_app/static/leaflet-measure/assets/rulers.png
diff --git a/static/leaflet-measure/assets/rulers.svg b/flask_app/static/leaflet-measure/assets/rulers.svg
similarity index 100%
rename from static/leaflet-measure/assets/rulers.svg
rename to flask_app/static/leaflet-measure/assets/rulers.svg
diff --git a/static/leaflet-measure/assets/rulers_@2X.png b/flask_app/static/leaflet-measure/assets/rulers_@2X.png
similarity index 100%
rename from static/leaflet-measure/assets/rulers_@2X.png
rename to flask_app/static/leaflet-measure/assets/rulers_@2X.png
diff --git a/static/leaflet-measure/assets/start.png b/flask_app/static/leaflet-measure/assets/start.png
similarity index 100%
rename from static/leaflet-measure/assets/start.png
rename to flask_app/static/leaflet-measure/assets/start.png
diff --git a/static/leaflet-measure/assets/start.svg b/flask_app/static/leaflet-measure/assets/start.svg
similarity index 100%
rename from static/leaflet-measure/assets/start.svg
rename to flask_app/static/leaflet-measure/assets/start.svg
diff --git a/static/leaflet-measure/assets/start_@2X.png b/flask_app/static/leaflet-measure/assets/start_@2X.png
similarity index 100%
rename from static/leaflet-measure/assets/start_@2X.png
rename to flask_app/static/leaflet-measure/assets/start_@2X.png
diff --git a/static/leaflet-measure/assets/trash.png b/flask_app/static/leaflet-measure/assets/trash.png
similarity index 100%
rename from static/leaflet-measure/assets/trash.png
rename to flask_app/static/leaflet-measure/assets/trash.png
diff --git a/static/leaflet-measure/assets/trash.svg b/flask_app/static/leaflet-measure/assets/trash.svg
similarity index 100%
rename from static/leaflet-measure/assets/trash.svg
rename to flask_app/static/leaflet-measure/assets/trash.svg
diff --git a/static/leaflet-measure/assets/trash_@2X.png b/flask_app/static/leaflet-measure/assets/trash_@2X.png
similarity index 100%
rename from static/leaflet-measure/assets/trash_@2X.png
rename to flask_app/static/leaflet-measure/assets/trash_@2X.png
diff --git a/static/leaflet-measure/leaflet-measure.css b/flask_app/static/leaflet-measure/leaflet-measure.css
similarity index 100%
rename from static/leaflet-measure/leaflet-measure.css
rename to flask_app/static/leaflet-measure/leaflet-measure.css
diff --git a/static/leaflet-measure/leaflet-measure.js b/flask_app/static/leaflet-measure/leaflet-measure.js
similarity index 100%
rename from static/leaflet-measure/leaflet-measure.js
rename to flask_app/static/leaflet-measure/leaflet-measure.js
diff --git a/static/leaflet/images/layers-2x.png b/flask_app/static/leaflet/images/layers-2x.png
similarity index 100%
rename from static/leaflet/images/layers-2x.png
rename to flask_app/static/leaflet/images/layers-2x.png
diff --git a/static/leaflet/images/layers.png b/flask_app/static/leaflet/images/layers.png
similarity index 100%
rename from static/leaflet/images/layers.png
rename to flask_app/static/leaflet/images/layers.png
diff --git a/static/leaflet/images/marker-icon-2x.png b/flask_app/static/leaflet/images/marker-icon-2x.png
similarity index 100%
rename from static/leaflet/images/marker-icon-2x.png
rename to flask_app/static/leaflet/images/marker-icon-2x.png
diff --git a/static/leaflet/images/marker-icon.png b/flask_app/static/leaflet/images/marker-icon.png
similarity index 100%
rename from static/leaflet/images/marker-icon.png
rename to flask_app/static/leaflet/images/marker-icon.png
diff --git a/static/leaflet/images/marker-shadow.png b/flask_app/static/leaflet/images/marker-shadow.png
similarity index 100%
rename from static/leaflet/images/marker-shadow.png
rename to flask_app/static/leaflet/images/marker-shadow.png
diff --git a/static/leaflet/leaflet-src.esm.js b/flask_app/static/leaflet/leaflet-src.esm.js
similarity index 100%
rename from static/leaflet/leaflet-src.esm.js
rename to flask_app/static/leaflet/leaflet-src.esm.js
diff --git a/static/leaflet/leaflet-src.esm.js.map b/flask_app/static/leaflet/leaflet-src.esm.js.map
similarity index 100%
rename from static/leaflet/leaflet-src.esm.js.map
rename to flask_app/static/leaflet/leaflet-src.esm.js.map
diff --git a/static/leaflet/leaflet-src.js b/flask_app/static/leaflet/leaflet-src.js
similarity index 100%
rename from static/leaflet/leaflet-src.js
rename to flask_app/static/leaflet/leaflet-src.js
diff --git a/static/leaflet/leaflet-src.js.map b/flask_app/static/leaflet/leaflet-src.js.map
similarity index 100%
rename from static/leaflet/leaflet-src.js.map
rename to flask_app/static/leaflet/leaflet-src.js.map
diff --git a/static/leaflet/leaflet.css b/flask_app/static/leaflet/leaflet.css
similarity index 100%
rename from static/leaflet/leaflet.css
rename to flask_app/static/leaflet/leaflet.css
diff --git a/static/leaflet/leaflet.js b/flask_app/static/leaflet/leaflet.js
similarity index 100%
rename from static/leaflet/leaflet.js
rename to flask_app/static/leaflet/leaflet.js
diff --git a/static/leaflet/leaflet.js.map b/flask_app/static/leaflet/leaflet.js.map
similarity index 100%
rename from static/leaflet/leaflet.js.map
rename to flask_app/static/leaflet/leaflet.js.map
diff --git a/templates/map.html b/flask_app/templates/map.html
similarity index 92%
rename from templates/map.html
rename to flask_app/templates/map.html
index 59ffb29..704d11e 100644
--- a/templates/map.html
+++ b/flask_app/templates/map.html
@@ -35,8 +35,8 @@
           esri_Map = L.esri.basemapLayer("Topographic"),
           otm_Map = L.tileLayer(otm_Url, {attribution: otm_Attrib}),
           google_Map = L.tileLayer(google_Url, {attribution: google_Attrib}),
-          bing_dark = L.tileLayer.bing({bingMapsKey: 'Ahpy5iReID6QJSUjazLaJbAkUMg2R990DMsYlbxMbf3irXoOVgFb0eyV3JPntW2Q', imagerySet: 'CanvasDark', attribution: bing_Attrib}),
-          bing_sat = L.tileLayer.bing({bingMapsKey: 'Ahpy5iReID6QJSUjazLaJbAkUMg2R990DMsYlbxMbf3irXoOVgFb0eyV3JPntW2Q', imagerySet: 'Aerial', attribution: bing_Attrib}),
+          bing_dark = L.tileLayer.bing({bingMapsKey: '{{bing_api_key}}', imagerySet: 'CanvasDark', attribution: bing_Attrib}),
+          bing_sat = L.tileLayer.bing({bingMapsKey: '{{bing_api_key}}', imagerySet: 'Aerial', attribution: bing_Attrib}),
           bing_sat_labels = L.tileLayer.bing({bingMapsKey: 'Ahpy5iReID6QJSUjazLaJbAkUMg2R990DMsYlbxMbf3irXoOVgFb0eyV3JPntW2Q', imagerySet: 'AerialWithLabels', attribution: bing_Attrib});
 
       //Create a map that remembers where it was zoomed to
diff --git a/flask_nginx.conf b/flask_nginx.conf
deleted file mode 100644
index 6f66a0b..0000000
--- a/flask_nginx.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-server {
-    listen 5500;
-
-    client_max_body_size 30M;
-
-    location / {
-        include proxy_params;
-        proxy_pass http://unix:/var/run/ttn_tracker_flask.sock;
-    }
-
-    error_page 502 /502.html;
-    location = /502.html {
-      root  /home/pi/ttn-tracker/templates;
-    }
-}
diff --git a/gitignore b/gitignore
new file mode 100644
index 0000000..68d2480
--- /dev/null
+++ b/gitignore
@@ -0,0 +1,7 @@
+
+__pycache__
+
+.vscode/
+.idea/
+.cache/
+.DS_Store
diff --git a/nginx/Dockerfile b/nginx/Dockerfile
new file mode 100644
index 0000000..1aa7494
--- /dev/null
+++ b/nginx/Dockerfile
@@ -0,0 +1,7 @@
+FROM nginx:1.15.9
+
+RUN rm /etc/nginx/nginx.conf
+COPY nginx.conf /etc/nginx/
+
+RUN rm /etc/nginx/conf.d/default.conf
+COPY project.conf /etc/nginx/conf.d/
diff --git a/nginx/nginx.conf b/nginx/nginx.conf
new file mode 100644
index 0000000..bf73358
--- /dev/null
+++ b/nginx/nginx.conf
@@ -0,0 +1,52 @@
+# Define the user that will own and run the Nginx server
+user  nginx;
+
+# Define the number of worker processes; recommended value is the number of
+# cores that are being used by your server
+worker_processes  1;
+
+# Define the location on the file system of the error log, plus the minimum
+# severity to log messages for
+error_log  /var/log/nginx/error.log warn;
+
+# Define the file that will store the process ID of the main NGINX process
+pid        /var/run/nginx.pid;
+
+
+# events block defines the parameters that affect connection processing.
+events {
+    # Define the maximum number of simultaneous connections that can be opened by a worker process
+    worker_connections  1024;
+}
+
+
+# http block defines the parameters for how NGINX should handle HTTP web traffic
+http {
+    # Include the file defining the list of file types that are supported by NGINX
+    include       /etc/nginx/mime.types;
+
+    # Define the default file type that is returned to the user
+    default_type  text/html;
+
+    # Define the format of log messages.
+    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                      '$status $body_bytes_sent "$http_referer" '
+                      '"$http_user_agent" "$http_x_forwarded_for"';
+
+    # Define the location of the log of access attempts to NGINX
+    access_log  /var/log/nginx/access.log  main;
+
+    # Define the parameters to optimize the delivery of static content
+    sendfile        on;
+    tcp_nopush     on;
+    tcp_nodelay    on;
+
+    # Define the timeout value for keep-alive connections with the client
+    keepalive_timeout  65;
+
+    # Define the usage of the gzip compression algorithm to reduce the amount of data to transmit
+    #gzip  on;
+
+    # Include additional parameters for virtual host(s)/server(s)
+    include /etc/nginx/conf.d/*.conf;
+}
diff --git a/nginx/project.conf b/nginx/project.conf
new file mode 100644
index 0000000..0335a24
--- /dev/null
+++ b/nginx/project.conf
@@ -0,0 +1,12 @@
+server {
+
+    listen 5550;
+    server_name ttn_tracker;
+
+    location / {
+        proxy_pass http://flask_app:8000;
+        proxy_set_header Host $host;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    }
+}
diff --git a/ttn-tracker.service b/ttn-tracker.service
deleted file mode 100644
index 3331e63..0000000
--- a/ttn-tracker.service
+++ /dev/null
@@ -1,21 +0,0 @@
-[Unit]
-Description=gunicorn daemon for ttn-mapper
-After=network.target
-
-[Service]
-User=root
-Group=pi
-WorkingDirectory=/home/pi/ttn-tracker
-ExecStart=/home/pi/ttn-tracker/env/bin/gunicorn \
---workers 1 \
---worker-class gthread \
---threads 2 \
---timeout 300 \
---pid /var/lock/ttn_tracker_flask.pid \
---bind unix:/var/run/ttn_tracker_flask.sock app:app
-
-ExecReload=/bin/kill -s HUP $MAINPID
-ExecStop=/bin/kill -s TERM $MAINPID
-
-[Install]
-WantedBy=multi-user.target