diff --git a/InvenTree/templates/mail.html b/InvenTree/templates/mail.html
new file mode 100644
index 0000000000..98990fb31b
--- /dev/null
+++ b/InvenTree/templates/mail.html
@@ -0,0 +1 @@
+
{{ mail }}{% include "clip.html"%}
\ No newline at end of file
diff --git a/InvenTree/templates/tel.html b/InvenTree/templates/tel.html
new file mode 100644
index 0000000000..14f978ad87
--- /dev/null
+++ b/InvenTree/templates/tel.html
@@ -0,0 +1 @@
+
{{ tel }}{% include "clip.html"%}
\ No newline at end of file
diff --git a/InvenTree/templates/version.html b/InvenTree/templates/version.html
new file mode 100644
index 0000000000..c8ec6862b6
--- /dev/null
+++ b/InvenTree/templates/version.html
@@ -0,0 +1,5 @@
+# Version Information:{% load inventree_extras %}
+InvenTree-Version: {% inventree_version %}
+Django Version: {% django_version %}
+{% inventree_commit_hash as hash %}{% if hash %}Commit Hash: {{ hash }}{% endif %}
+{% inventree_commit_date as commit_date %}{% if commit_date %}Commit Date: {{ commit_date }}{% endif %}
\ No newline at end of file
diff --git a/docker/Dockerfile b/docker/Dockerfile
index c95c2867df..3e0a7e1230 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:alpine as production
+FROM python:alpine as base
# GitHub source
ARG repository="https://github.com/inventree/InvenTree.git"
@@ -73,6 +73,7 @@ RUN pip install --no-cache-dir -U invoke
RUN pip install --no-cache-dir -U psycopg2 mysqlclient pgcli mariadb
RUN pip install --no-cache-dir -U gunicorn
+FROM base as production
# Clone source code
RUN echo "Downloading InvenTree from ${INVENTREE_REPO}"
RUN git clone --branch ${INVENTREE_BRANCH} --depth 1 ${INVENTREE_REPO} ${INVENTREE_SRC_DIR}
@@ -85,11 +86,9 @@ COPY gunicorn.conf.py ${INVENTREE_HOME}/gunicorn.conf.py
# Copy startup scripts
COPY start_prod_server.sh ${INVENTREE_SRC_DIR}/start_prod_server.sh
-COPY start_dev_server.sh ${INVENTREE_SRC_DIR}/start_dev_server.sh
COPY start_worker.sh ${INVENTREE_SRC_DIR}/start_worker.sh
RUN chmod 755 ${INVENTREE_SRC_DIR}/start_prod_server.sh
-RUN chmod 755 ${INVENTREE_SRC_DIR}/start_dev_server.sh
RUN chmod 755 ${INVENTREE_SRC_DIR}/start_worker.sh
# exec commands should be executed from the "src" directory
@@ -97,3 +96,17 @@ WORKDIR ${INVENTREE_SRC_DIR}
# Let us begin
CMD ["bash", "./start_prod_server.sh"]
+
+FROM base as dev
+
+# The development image requires the source code to be mounted to /home/inventree/src/
+# So from here, we don't actually "do" anything
+
+WORKDIR ${INVENTREE_SRC_DIR}
+
+COPY start_dev_server.sh ${INVENTREE_HOME}/start_dev_server.sh
+COPY start_dev_worker.sh ${INVENTREE_HOME}/start_dev_worker.sh
+RUN chmod 755 ${INVENTREE_HOME}/start_dev_server.sh
+RUN chmod 755 ${INVENTREE_HOME}/start_dev_worker.sh
+
+CMD ["bash", "/home/inventree/start_dev_server.sh"]
diff --git a/docker/dev-config.env b/docker/dev-config.env
new file mode 100644
index 0000000000..200c3db479
--- /dev/null
+++ b/docker/dev-config.env
@@ -0,0 +1,7 @@
+INVENTREE_DB_ENGINE=sqlite3
+INVENTREE_DB_NAME=/home/inventree/src/inventree_docker_dev.sqlite3
+INVENTREE_MEDIA_ROOT=/home/inventree/src/inventree_media
+INVENTREE_STATIC_ROOT=/home/inventree/src/inventree_static
+INVENTREE_CONFIG_FILE=/home/inventree/src/config.yaml
+INVENTREE_SECRET_KEY_FILE=/home/inventree/src/secret_key.txt
+INVENTREE_DEBUG=true
\ No newline at end of file
diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml
new file mode 100644
index 0000000000..ddf50135c9
--- /dev/null
+++ b/docker/docker-compose.dev.yml
@@ -0,0 +1,59 @@
+version: "3.8"
+
+# Docker compose recipe for InvenTree development server
+# - Runs sqlite3 as the database backend
+# - Uses built-in django webserver
+
+# IMPORANT NOTE:
+# The InvenTree docker image does not clone source code from git.
+# Instead, you must specify *where* the source code is located,
+# (on your local machine).
+# The django server will auto-detect any code changes and reload the server.
+
+services:
+ # InvenTree web server services
+ # Uses gunicorn as the web server
+ inventree-server:
+ container_name: inventree-server
+ build:
+ context: .
+ target: dev
+ ports:
+ - 8000:8000
+ volumes:
+ # Ensure you specify the location of the 'src' directory at the end of this file
+ - src:/home/inventree/src
+ env_file:
+ # Environment variables required for the dev server are configured in dev-config.env
+ - dev-config.env
+
+ restart: unless-stopped
+
+ # Background worker process handles long-running or periodic tasks
+ inventree-worker:
+ container_name: inventree-worker
+ build:
+ context: .
+ target: dev
+ entrypoint: /home/inventree/start_dev_worker.sh
+ depends_on:
+ - inventree-server
+ volumes:
+ # Ensure you specify the location of the 'src' directory at the end of this file
+ - src:/home/inventree/src
+ env_file:
+ # Environment variables required for the dev server are configured in dev-config.env
+ - dev-config.env
+ restart: unless-stopped
+
+volumes:
+ # NOTE: Change /path/to/src to a directory on your local machine, where the InvenTree source code is located
+ # Persistent data, stored external to the container(s)
+ src:
+ driver: local
+ driver_opts:
+ type: none
+ o: bind
+ # This directory specified where InvenTree source code is stored "outside" the docker containers
+ # Note: This directory must conatin the file *manage.py*
+ device: /path/to/inventree/src
diff --git a/docker/start_dev_server.sh b/docker/start_dev_server.sh
index c22805b90b..0c1564076a 100644
--- a/docker/start_dev_server.sh
+++ b/docker/start_dev_server.sh
@@ -19,6 +19,14 @@ else
cp $INVENTREE_SRC_DIR/InvenTree/config_template.yaml $INVENTREE_CONFIG_FILE
fi
+# Setup a virtual environment
+python3 -m venv inventree-docker-dev
+
+source inventree-docker-dev/bin/activate
+
+echo "Installing required packages..."
+pip install --no-cache-dir -U -r ${INVENTREE_SRC_DIR}/requirements.txt
+
echo "Starting InvenTree server..."
# Wait for the database to be ready
@@ -27,16 +35,14 @@ python manage.py wait_for_db
sleep 10
-echo "Running InvenTree database migrations and collecting static files..."
+echo "Running InvenTree database migrations..."
# We assume at this stage that the database is up and running
# Ensure that the database schema are up to date
python manage.py check || exit 1
python manage.py migrate --noinput || exit 1
python manage.py migrate --run-syncdb || exit 1
-python manage.py prerender || exit 1
-python manage.py collectstatic --noinput || exit 1
python manage.py clearsessions || exit 1
# Launch a development server
-python manage.py runserver -a 0.0.0.0:$INVENTREE_WEB_PORT
\ No newline at end of file
+python manage.py runserver 0.0.0.0:$INVENTREE_WEB_PORT
diff --git a/docker/start_dev_worker.sh b/docker/start_dev_worker.sh
new file mode 100644
index 0000000000..099f447a9c
--- /dev/null
+++ b/docker/start_dev_worker.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+echo "Starting InvenTree worker..."
+
+cd $INVENTREE_SRC_DIR
+
+# Activate virtual environment
+source inventree-docker-dev/bin/activate
+
+sleep 5
+
+# Wait for the database to be ready
+cd $INVENTREE_MNG_DIR
+python manage.py wait_for_db
+
+sleep 10
+
+# Now we can launch the background worker process
+python manage.py qcluster
diff --git a/requirements.txt b/requirements.txt
index 3291574084..35963ce718 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,9 +11,10 @@ django-markdownx==3.0.1 # Markdown form fields
django-markdownify==0.8.0 # Markdown rendering
coreapi==2.3.0 # API documentation
pygments==2.7.4 # Syntax highlighting
-tablib==0.13.0 # Import / export data files
+# tablib==0.13.0 # Import / export data files (installed as dependency of django-import-export package)
django-crispy-forms==1.11.2 # Form helpers
django-import-export==2.0.0 # Data import / export for admin interface
+tablib[xls,xlsx,yaml] # Support for XLS and XLSX formats
django-cleanup==5.1.0 # Manage deletion of old / unused uploaded files
flake8==3.8.3 # PEP checking
pep8-naming==0.11.1 # PEP naming convention extension
@@ -32,5 +33,6 @@ python-barcode[images]==0.13.1 # Barcode generator
qrcode[pil]==6.1 # QR code generator
django-q==1.3.4 # Background task scheduling
gunicorn>=20.0.4 # Gunicorn web server
+django-formtools==2.3 # Form wizard tools
inventree # Install the latest version of the InvenTree API python library