diff --git a/Dockerfile b/Dockerfile index 39f7f936..79532927 100644 --- a/Dockerfile +++ b/Dockerfile @@ -151,7 +151,7 @@ RUN rm -rf /var/cache/apk/* ARG IMPRESS_STATIC_ROOT=/data/static -# Gunicorn +# Gunicorn - not used by default but configuration file is provided RUN mkdir -p /usr/local/etc/gunicorn COPY docker/files/usr/local/etc/gunicorn/impress.py /usr/local/etc/gunicorn/impress.py @@ -165,5 +165,18 @@ COPY --from=link-collector ${IMPRESS_STATIC_ROOT} ${IMPRESS_STATIC_ROOT} # Copy impress mails COPY --from=mail-builder /mail/backend/core/templates/mail /app/core/templates/mail -# The default command runs gunicorn WSGI server in impress's main module -CMD ["gunicorn", "-c", "/usr/local/etc/gunicorn/impress.py", "impress.wsgi:application"] +# The default command runs uvicorn ASGI server in dics's main module +# WEB_CONCURRENCY: number of workers to run <=> --workers=4 +ENV WEB_CONCURRENCY=4 +CMD [\ + "uvicorn",\ + "--app-dir=/app",\ + "--host=0.0.0.0",\ + "--timeout-graceful-shutdown=300",\ + "--limit-max-requests=20000",\ + "--lifespan=off",\ + "impress.asgi:application"\ + ] + +# To run using gunicorn WSGI server use this instead: +#CMD ["gunicorn", "-c", "/usr/local/etc/gunicorn/conversations.py", "impress.wsgi:application"] diff --git a/src/backend/impress/asgi.py b/src/backend/impress/asgi.py new file mode 100644 index 00000000..caea2d0f --- /dev/null +++ b/src/backend/impress/asgi.py @@ -0,0 +1,18 @@ +""" +ASGI config for impress project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/dev/howto/deployment/asgi/ +""" + +import os + +from configurations.asgi import get_asgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "impress.settings") +os.environ.setdefault("DJANGO_CONFIGURATION", "Development") +os.environ.setdefault("PYTHON_SERVER_MODE", "async") + +application = get_asgi_application() diff --git a/src/backend/impress/wsgi.py b/src/backend/impress/wsgi.py index 6076021c..bae5c3fd 100644 --- a/src/backend/impress/wsgi.py +++ b/src/backend/impress/wsgi.py @@ -13,5 +13,6 @@ from configurations.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "impress.settings") os.environ.setdefault("DJANGO_CONFIGURATION", "Development") +os.environ.setdefault("PYTHON_SERVER_MODE", "sync") application = get_wsgi_application() diff --git a/src/backend/pyproject.toml b/src/backend/pyproject.toml index 10f16390..33eaf4ed 100644 --- a/src/backend/pyproject.toml +++ b/src/backend/pyproject.toml @@ -55,12 +55,13 @@ dependencies = [ "nested-multipart-parser==1.6.0", "openai==2.14.0", "psycopg[binary]==3.3.2", - "pycrdt==0.12.44", + "pycrdt==0.12.44", "PyJWT==2.10.1", "python-magic==0.4.27", "redis<6.0.0", "requests==2.32.5", "sentry-sdk==2.48.0", + "uvicorn==0.40.0", "whitenoise==6.11.0", ] diff --git a/src/helm/env.d/dev/configuration/theme/demo.json b/src/helm/env.d/dev/configuration/theme/demo.json index c9d6e6e6..76d03781 100644 --- a/src/helm/env.d/dev/configuration/theme/demo.json +++ b/src/helm/env.d/dev/configuration/theme/demo.json @@ -135,9 +135,15 @@ } }, "header": { + "logo": {}, "icon": { "src": "/assets/icon-docs.svg", - "width": "32px" + "style": { + "width": "32px", + "height": "auto" + }, + "alt": "", + "withTitle": true } }, "waffle": { @@ -164,5 +170,26 @@ ] }, "showMoreLimit": 9 + }, + "home": { + "with-proconnect": false, + "icon-banner": { + "src": "/assets/icon-docs.svg", + "style": { + "width": "64px", + "height": "auto" + }, + "alt": "" + } + }, + "favicon": { + "light": { + "href": "/assets/favicon-light.png", + "type": "image/png" + }, + "dark": { + "href": "/assets/favicon-dark.png", + "type": "image/png" + } } } diff --git a/src/helm/env.d/dev/values.impress.yaml.gotmpl b/src/helm/env.d/dev/values.impress.yaml.gotmpl index 84761a6a..1144f910 100644 --- a/src/helm/env.d/dev/values.impress.yaml.gotmpl +++ b/src/helm/env.d/dev/values.impress.yaml.gotmpl @@ -91,11 +91,14 @@ backend: restartPolicy: Never command: - - "gunicorn" - - "-c" - - "/usr/local/etc/gunicorn/impress.py" - - "impress.wsgi:application" - - "--reload" + - uvicorn + - --app-dir=/app + - --host=0.0.0.0 + - --timeout-graceful-shutdown=300 + - --limit-max-requests=20000 + - --lifespan=off + - --reload + - "impress.asgi:application" createsuperuser: command: @@ -145,6 +148,9 @@ frontend: pullPolicy: Always tag: "latest" + securityContext: + runAsNonRoot: false + yProvider: replicas: 1