diff --git a/.github/workflows/docker_build.yaml b/.github/workflows/docker_build.yaml index 26fc69a0f5..ec8bdf7306 100644 --- a/.github/workflows/docker_build.yaml +++ b/.github/workflows/docker_build.yaml @@ -30,6 +30,7 @@ jobs: context: ./docker platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true + target: production repository: inventree/inventree tags: inventree/inventree:latest - name: Image Digest diff --git a/.github/workflows/docker_publish.yaml b/.github/workflows/docker_publish.yaml index c25696d6dd..4a8cef0952 100644 --- a/.github/workflows/docker_publish.yaml +++ b/.github/workflows/docker_publish.yaml @@ -28,4 +28,5 @@ jobs: repository: inventree/inventree tag_with_ref: true dockerfile: ./Dockerfile + target: production platforms: linux/amd64,linux/arm64,linux/arm/v7 diff --git a/.gitignore b/.gitignore index 54ad8f07b6..7c360a8231 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ var/ *.log local_settings.py *.sqlite3 +*.sqlite3-journal *.backup *.old diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 680389272a..7ff90fc7c3 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -431,11 +431,15 @@ It can be specified in config.yaml (or envvar) as either (for example): - django.db.backends.postgresql """ -db_engine = db_config['ENGINE'] +db_engine = db_config['ENGINE'].lower() -if db_engine.lower() in ['sqlite3', 'postgresql', 'mysql']: +# Correct common misspelling +if db_engine == 'sqlite': + db_engine = 'sqlite3' + +if db_engine in ['sqlite3', 'postgresql', 'mysql']: # Prepend the required python module string - db_engine = f'django.db.backends.{db_engine.lower()}' + db_engine = f'django.db.backends.{db_engine}' db_config['ENGINE'] = db_engine db_name = db_config['NAME'] 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