diff --git a/backend/Dockerfile b/backend/Dockerfile index 928adcd1f7..397a0ba03d 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -117,8 +117,10 @@ WORKDIR /dist ENV GEONATURE_STATIC_PATH=/dist/static/ COPY /backend/static/ ./static/ COPY --from=node /dist/node_modules/ ./static/node_modules/ +ENV GEONATURE_CUSTOM_STATIC_PATH=/dist/custom/ +RUN mkdir custom ENV GEONATURE_MEDIA_PATH=/dist/media/ -COPY /backend/media/ ./media/ +RUN mkdir -p media/attachments WORKDIR /dist/geonature diff --git a/backend/geonature/app.py b/backend/geonature/app.py index 7d2fbd413d..57d6699550 100755 --- a/backend/geonature/app.py +++ b/backend/geonature/app.py @@ -13,6 +13,7 @@ from flask_cors import CORS from flask_sqlalchemy import before_models_committed from werkzeug.middleware.proxy_fix import ProxyFix +from werkzeug.middleware.shared_data import SharedDataMiddleware from psycopg2.errors import UndefinedTable from sqlalchemy.exc import OperationalError, ProgrammingError from sqlalchemy.orm.exc import NoResultFound @@ -96,6 +97,14 @@ def create_app(with_external_mods=True): app.wsgi_app = ProxyFix(app.wsgi_app, x_host=1) app.wsgi_app = RequestID(app.wsgi_app) + if config.get("CUSTOM_STATIC_FOLDER"): + app.wsgi_app = SharedDataMiddleware( + app.wsgi_app, + { + "/static": config["CUSTOM_STATIC_FOLDER"], + }, + ) + app.json = MyJSONProvider(app) # set logging config diff --git a/backend/geonature/utils/config_schema.py b/backend/geonature/utils/config_schema.py index b513449f38..6c116b90d2 100644 --- a/backend/geonature/utils/config_schema.py +++ b/backend/geonature/utils/config_schema.py @@ -20,7 +20,7 @@ DEFAULT_LIST_COLUMN, DEFAULT_COLUMNS_API_SYNTHESE, ) -from geonature.utils.env import GEONATURE_VERSION, BACKEND_DIR +from geonature.utils.env import GEONATURE_VERSION, BACKEND_DIR, ROOT_DIR from geonature.utils.module import get_module_config from geonature.utils.utilsmails import clean_recipients from geonature.utils.utilstoml import load_and_validate_toml @@ -198,6 +198,7 @@ class GnPySchemaConf(Schema): SENTRY_DSN = fields.String() ROOT_PATH = fields.String(load_default=BACKEND_DIR) STATIC_FOLDER = fields.String(load_default="static") + CUSTOM_STATIC_FOLDER = fields.String(load_default=ROOT_DIR / "custom") MEDIA_FOLDER = fields.String(load_default="media") CAS = fields.Nested(CasSchemaConf, load_default=CasSchemaConf().load({})) MAIL_ON_ERROR = fields.Boolean(load_default=False) @@ -217,6 +218,10 @@ class GnPySchemaConf(Schema): @post_load() def folders(self, data, **kwargs): data["STATIC_FOLDER"] = os.path.join(data["ROOT_PATH"], data["STATIC_FOLDER"]) + if "CUSTOM_STATIC_FOLDER" in data: + data["CUSTOM_STATIC_FOLDER"] = os.path.join( + data["ROOT_PATH"], data["CUSTOM_STATIC_FOLDER"] + ) data["MEDIA_FOLDER"] = os.path.join(data["ROOT_PATH"], data["MEDIA_FOLDER"]) return data diff --git a/custom/.gitkeep b/custom/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/install/migration/migration.sh b/install/migration/migration.sh index 64403aa6bb..1f4d835628 100755 --- a/install/migration/migration.sh +++ b/install/migration/migration.sh @@ -30,6 +30,11 @@ echo "Copie des fichiers de configuration…" # Copy all config files (installation, GeoNature, modules) cp ${previousdir}/config/*.{ini,toml} config/ +if [ -d "${previousdir}/custm" ]; do + echo "Copie de la customisation…" + cp ${previousdir}/custom/* custom/ +done + echo "Vérification de la robustesse de la SECRET_KEY…" sk_len=$(grep -E '^SECRET_KEY' config/geonature_config.toml | tail -n 1 | sed 's/SECRET_KEY = ['\''"]\(.*\)['\''"]/\1/' | wc -c) if [ $sk_len -lt 20 ]; then