From 6b659ba22f541a46ebed0b32d54c3866a961283e Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 8 Dec 2022 23:06:02 +1100 Subject: [PATCH] Improvements for docker / gunicorn (#4031) * Additional options for gunicorn configuration file (in docker): Ref: https://pythonspeed.com/articles/gunicorn-in-docker/ * Catch potential error on startup * Tweak log message for docker * Wrap news feed update in try block --- InvenTree/common/tasks.py | 21 +++++++++++++-------- InvenTree/label/apps.py | 19 +++++++++++-------- docker/gunicorn.conf.py | 10 ++++++++++ docker/init.sh | 2 +- docker/requirements.txt | 1 + 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/InvenTree/common/tasks.py b/InvenTree/common/tasks.py index 3db5811d64..d3368f60e1 100644 --- a/InvenTree/common/tasks.py +++ b/InvenTree/common/tasks.py @@ -5,6 +5,7 @@ from datetime import datetime, timedelta from django.conf import settings from django.core.exceptions import AppRegistryNotReady +from django.db.utils import IntegrityError, OperationalError import feedparser @@ -57,13 +58,17 @@ def update_news_feed(): continue # Create entry - NewsFeedEntry.objects.create( - feed_id=entry.id, - title=entry.title, - link=entry.link, - published=entry.published, - author=entry.author, - summary=entry.summary, - ) + try: + NewsFeedEntry.objects.create( + feed_id=entry.id, + title=entry.title, + link=entry.link, + published=entry.published, + author=entry.author, + summary=entry.summary, + ) + except (IntegrityError, OperationalError): + # Sometimes errors-out on database start-up + pass logger.info('update_news_feed: Sync done') diff --git a/InvenTree/label/apps.py b/InvenTree/label/apps.py index aacf020924..a75047a174 100644 --- a/InvenTree/label/apps.py +++ b/InvenTree/label/apps.py @@ -10,6 +10,7 @@ from pathlib import Path from django.apps import AppConfig from django.conf import settings from django.core.exceptions import AppRegistryNotReady +from django.db.utils import OperationalError from InvenTree.ready import canAppAccessDatabase @@ -35,18 +36,18 @@ class LabelConfig(AppConfig): def ready(self): """This function is called whenever the label app is loaded.""" if canAppAccessDatabase(): - self.create_labels() # pragma: no cover + + try: + self.create_labels() # pragma: no cover + except (AppRegistryNotReady, OperationalError): + # Database might not yet be ready + warnings.warn('Database was not ready for creating labels') def create_labels(self): """Create all default templates.""" # Test if models are ready - try: - from .models import PartLabel, StockItemLabel, StockLocationLabel - assert bool(StockLocationLabel is not None) - except AppRegistryNotReady: # pragma: no cover - # Database might not yet be ready - warnings.warn('Database was not ready for creating labels') - return + from .models import PartLabel, StockItemLabel, StockLocationLabel + assert bool(StockLocationLabel is not None) # Create the categories self.create_labels_category( @@ -62,6 +63,7 @@ class LabelConfig(AppConfig): }, ], ) + self.create_labels_category( StockLocationLabel, 'stocklocation', @@ -82,6 +84,7 @@ class LabelConfig(AppConfig): } ] ) + self.create_labels_category( PartLabel, 'part', diff --git a/docker/gunicorn.conf.py b/docker/gunicorn.conf.py index 50f9f70084..62ecafcfee 100644 --- a/docker/gunicorn.conf.py +++ b/docker/gunicorn.conf.py @@ -4,7 +4,17 @@ import logging import multiprocessing import os +# Logger configuration logger = logging.getLogger('inventree') +accesslog = '-' +errorlog = '-' +loglevel = os.environ.get('INVENTREE_LOG_LEVEL', 'warning').lower() +capture_output = True + +# Worker configuration +worker_class = 'gevent' # Allow multi-threading support +worker_tmp_dir = '/dev/shm' # Write temp file to RAM (faster) +threads = 4 workers = os.environ.get('INVENTREE_GUNICORN_WORKERS', None) diff --git a/docker/init.sh b/docker/init.sh index 08dbf87117..b329551cc2 100644 --- a/docker/init.sh +++ b/docker/init.sh @@ -20,7 +20,7 @@ fi # Check if "config.yaml" has been copied into the correct location if test -f "$INVENTREE_CONFIG_FILE"; then - echo "$INVENTREE_CONFIG_FILE exists - skipping" + echo "Loading config file : $INVENTREE_CONFIG_FILE" else echo "Copying config file to $INVENTREE_CONFIG_FILE" cp $INVENTREE_HOME/InvenTree/config_template.yaml $INVENTREE_CONFIG_FILE diff --git a/docker/requirements.txt b/docker/requirements.txt index 2371292f9d..dcb240a585 100644 --- a/docker/requirements.txt +++ b/docker/requirements.txt @@ -14,3 +14,4 @@ mariadb>=1.0.7,<1.1.0 # gunicorn web server gunicorn>=20.1.0 +gevent>=22.10.2