From bab827a174d9ee778dded29089c7d06d8a5a34d0 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Mon, 12 Jan 2026 18:13:39 +0100 Subject: [PATCH 01/19] Refactor project to be forked directly --- .codeql/codeql-config.yml | 2 +- .env.sample | 18 ++-- Dockerfile | 10 +- README.md | 90 ++---------------- docker-compose.yml | 8 +- src/entrypoint.sh | 2 +- src/manage.py | 2 +- src/{project_name => project}/__init__.py | 6 +- src/{project_name => project}/apps.py | 4 +- src/{project_name => project}/br/backup.sh | 10 +- src/{project_name => project}/br/restore.sh | 12 +-- .../br/settings_docker.ini | 0 src/{project_name => project}/celeryapp.py | 6 +- src/{project_name => project}/locale/.gitkeep | 0 src/{project_name => project}/settings.py | 6 +- src/{project_name => project}/static/README | 0 .../static/css/site_base.css | 0 .../static/gulpfile.js | 0 .../static/img/README | 0 .../static/img/bing_aerial_w_labels.png | Bin .../static/img/bing_canvas_dark.png | Bin .../static/img/bing_road_on_demand.png | Bin .../static/js/README | 0 .../static/less/site_base.less | 0 .../static/package.json | 4 +- .../_geonode_config.html | 0 src/{project_name => project}/urls.py | 0 src/{project_name => project}/version.py | 0 src/{project_name => project}/wsgi.py | 4 +- src/requirements.txt | 2 +- src/setup.py | 8 +- src/tasks.py | 2 +- src/uwsgi.ini | 8 +- 33 files changed, 64 insertions(+), 140 deletions(-) rename src/{project_name => project}/__init__.py (85%) rename src/{project_name => project}/apps.py (95%) rename src/{project_name => project}/br/backup.sh (74%) rename src/{project_name => project}/br/restore.sh (88%) rename src/{project_name => project}/br/settings_docker.ini (100%) rename src/{project_name => project}/celeryapp.py (86%) rename src/{project_name => project}/locale/.gitkeep (100%) rename src/{project_name => project}/settings.py (94%) rename src/{project_name => project}/static/README (100%) rename src/{project_name => project}/static/css/site_base.css (100%) rename src/{project_name => project}/static/gulpfile.js (100%) rename src/{project_name => project}/static/img/README (100%) rename src/{project_name => project}/static/img/bing_aerial_w_labels.png (100%) rename src/{project_name => project}/static/img/bing_canvas_dark.png (100%) rename src/{project_name => project}/static/img/bing_road_on_demand.png (100%) rename src/{project_name => project}/static/js/README (100%) rename src/{project_name => project}/static/less/site_base.less (100%) rename src/{project_name => project}/static/package.json (78%) rename src/{project_name => project}/templates/geonode-mapstore-client/_geonode_config.html (100%) rename src/{project_name => project}/urls.py (100%) rename src/{project_name => project}/version.py (100%) rename src/{project_name => project}/wsgi.py (93%) diff --git a/.codeql/codeql-config.yml b/.codeql/codeql-config.yml index 7b3629b8..9b2aa293 100644 --- a/.codeql/codeql-config.yml +++ b/.codeql/codeql-config.yml @@ -1,4 +1,4 @@ languages: ${{ matrix.language }} paths-ignore: - - src/project_name/__init__.py \ No newline at end of file + - src/project/__init__.py \ No newline at end of file diff --git a/.env.sample b/.env.sample index 4aaef745..10135cb0 100644 --- a/.env.sample +++ b/.env.sample @@ -1,4 +1,4 @@ -COMPOSE_PROJECT_NAME={{project_name}} +COMPOSE_PROJECT_NAME=project DOCKER_ENV=production BACKUPS_VOLUME_DRIVER=local @@ -16,7 +16,7 @@ INVOKE_LOG_STDOUT=true # LANGUAGE_CODE=it-it # LANGUAGES=(('en-us','English'),('it-it','Italiano')) -DJANGO_SETTINGS_MODULE={{project_name}}.settings +DJANGO_SETTINGS_MODULE=project.settings GEONODE_INSTANCE_NAME=geonode # ################# @@ -24,18 +24,18 @@ GEONODE_INSTANCE_NAME=geonode # ################# POSTGRES_USER=postgres POSTGRES_PASSWORD={pgpwd} -GEONODE_DATABASE={{project_name}} -GEONODE_DATABASE_USER={{project_name}} +GEONODE_DATABASE=project +GEONODE_DATABASE_USER=project GEONODE_DATABASE_PASSWORD={dbpwd} -GEONODE_GEODATABASE={{project_name}}_data -GEONODE_GEODATABASE_USER={{project_name}}_data +GEONODE_GEODATABASE=project_data +GEONODE_GEODATABASE_USER=project_data GEONODE_GEODATABASE_PASSWORD={geodbpwd} GEONODE_DATABASE_SCHEMA=public GEONODE_GEODATABASE_SCHEMA=public DATABASE_HOST=db DATABASE_PORT=5432 -DATABASE_URL=postgis://{{project_name}}:{dbpwd}@db:5432/{{project_name}} -GEODATABASE_URL=postgis://{{project_name}}_data:{geodbpwd}@db:5432/{{project_name}}_data +DATABASE_URL=postgis://project:{dbpwd}@db:5432/project +GEODATABASE_URL=postgis://project_data:{geodbpwd}@db:5432/project_data GEONODE_DB_CONN_MAX_AGE=0 GEONODE_DB_CONN_TOUT=5 DEFAULT_BACKEND_DATASTORE=datastore @@ -104,7 +104,7 @@ OGC_REQUEST_POOL_CONNECTIONS=10 # Java Options & Memory ENABLE_JSONP=true outFormat=text/javascript -GEOSERVER_JAVA_OPTS=-Djava.awt.headless=true -Xms4G -Xmx4G -Dgwc.context.suffix=gwc -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=/var/log/jvm.log -XX:PerfDataSamplingInterval=500 -XX:SoftRefLRUPolicyMSPerMB=36000 -XX:-UseGCOverheadLimit -XX:ParallelGCThreads=4 -Dfile.encoding=UTF8 -Djavax.servlet.request.encoding=UTF-8 -Djavax.servlet.response.encoding=UTF-8 -Duser.timezone=GMT -Dorg.geotools.shapefile.datetime=false -DGS-SHAPEFILE-CHARSET=UTF-8 -DGEOSERVER_CSRF_DISABLED=true -DPRINT_BASE_URL={siteurl}/geoserver/pdf -DALLOW_ENV_PARAMETRIZATION=true -Xbootclasspath/a:/usr/local/tomcat/webapps/geoserver/WEB-INF/lib/marlin-0.9.3-Unsafe.jar -Dsun.java2d.renderer=org.marlin.pisces.MarlinRenderingEngine +GEOSERVER_JAVA_OPTS="-Djava.awt.headless=true -Xms4G -Xmx4G -Dgwc.context.suffix=gwc -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=/var/log/jvm.log -XX:PerfDataSamplingInterval=500 -XX:SoftRefLRUPolicyMSPerMB=36000 -XX:-UseGCOverheadLimit -XX:ParallelGCThreads=4 -Dfile.encoding=UTF8 -Djavax.servlet.request.encoding=UTF-8 -Djavax.servlet.response.encoding=UTF-8 -Duser.timezone=GMT -Dorg.geotools.shapefile.datetime=false -DGS-SHAPEFILE-CHARSET=UTF-8 -DGEOSERVER_CSRF_DISABLED=true -DPRINT_BASE_URL={siteurl}/geoserver/pdf -DALLOW_ENV_PARAMETRIZATION=true -Xbootclasspath/a:/usr/local/tomcat/webapps/geoserver/WEB-INF/lib/marlin-0.9.3-Unsafe.jar -Dsun.java2d.renderer=org.marlin.pisces.MarlinRenderingEngine" # ################# # Security diff --git a/Dockerfile b/Dockerfile index d1e56aa5..751b1017 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM geonode/geonode-base:latest-ubuntu-24.04 LABEL GeoNode development team -RUN mkdir -p /usr/src/{{project_name}} +RUN mkdir -p /usr/src/project RUN apt-get update -y && apt-get install curl wget unzip gnupg2 locales -y @@ -10,13 +10,13 @@ RUN sed -i -e 's/# C.UTF-8 UTF-8/C.UTF-8 UTF-8/' /etc/locale.gen && \ ENV LC_ALL C.UTF-8 ENV LANG C.UTF-8 -COPY src /usr/src/{{project_name}}/ -WORKDIR /usr/src/{{project_name}} +COPY src /usr/src/project/ +WORKDIR /usr/src/project COPY src/wait-for-databases.sh /usr/bin/wait-for-databases RUN chmod +x /usr/bin/wait-for-databases -RUN chmod +x /usr/src/{{project_name}}/tasks.py \ - && chmod +x /usr/src/{{project_name}}/entrypoint.sh +RUN chmod +x /usr/src/project/tasks.py \ + && chmod +x /usr/src/project/entrypoint.sh COPY src/celery.sh /usr/bin/celery-commands RUN chmod +x /usr/bin/celery-commands diff --git a/README.md b/README.md index e2d8c671..cc1ceca7 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,10 @@ -# {{ project_name|title }} +# GeoNode Project -GeoNode template project. Generates a django project with GeoNode support. +GeoNode Django project. This can be forked to customize, add Python modules or Django apps to your GeoNode instance. ## Table of Contents - [Quick Docker Start](#quick-docker-start) -- [Developer Workshop](#developer-workshop) -- [Create a custom project](#create-a-custom-project) - [Start your server using Docker](#start-your-server-using-docker) - [Run the instance in development mode](#run-the-instance-in-development-mode) - [Run the instance on a public site](#run-the-instance-on-a-public-site) @@ -16,77 +14,13 @@ GeoNode template project. Generates a django project with GeoNode support. - [Hints: Configuring `requirements.txt`](#hints-configuring-requirementstxt) ## Quick Docker Start - - ```bash - python3.10 -m venv ~/.venvs/project_name - source ~/.venvs/{{ project_name }}/bin/activate - - pip install Django==4.2.9 - - mkdir ~/project_name - - GN_VERSION=master # Define the branch or tag you want to generate the project from - django-admin startproject --template=https://github.com/GeoNode/geonode-project/archive/refs/heads/$GN_VERSION.zip -e py,sh,md,rst,json,yml,ini,env,sample,properties -n monitoring-cron -n Dockerfile project_name ~/project_name - - cd ~/project_name - python create-envfile.py - ``` - -The project can also be generated from a local checkout of the goenode-project repository - -```bash - git clone https://github.com/GeoNode/geonode-project - git checkout $GN_VERSION - django-admin startproject --template=./geonode-project -e py,sh,md,rst,json,yml,ini,env,sample,properties -n monitoring-cron -n Dockerfile project_name ~/project_name - - ``` - -`create-envfile.py` accepts the following arguments: - -- `--https`: Enable SSL. It's disabled by default -- `--env_type`: - - When set to `prod` `DEBUG` is disabled and the creation of a valid `SSL` is requested to Letsencrypt's ACME server - - When set to `test` `DEBUG` is disabled and a test `SSL` certificate is generated for local testing - - When set to `dev` `DEBUG` is enabled and no `SSL` certificate is generated -- `--hostname`: The URL that whill serve GeoNode (`localhost` by default) -- `--email`: The administrator's email. Notice that a real email and a valid SMPT configurations are required if `--env_type` is seto to `prod`. Letsencrypt uses to email for issuing the SSL certificate -- `--geonodepwd`: GeoNode's administrator password. A random value is set if left empty -- `--geoserverpwd`: GeoNode's administrator password. A random value is set if left empty -- `--pgpwd`: PostgreSQL's administrator password. A random value is set if left empty -- `--dbpwd`: GeoNode DB user role's password. A random value is set if left empty -- `--geodbpwd`: GeoNode data DB user role's password. A random value is set if left empty -- `--clientid`: Client id of Geoserver's GeoNode Oauth2 client. A random value is set if left empty -- `--clientsecret`: Client secret of Geoserver's GeoNode Oauth2 client. A random value is set if left empty -```bash - docker compose build - docker compose up -d -``` - -## Developer Workshop - -Available at - - ```bash - http://geonode.org/dev-workshop - ``` - -## Create a custom project - -**NOTE**: *You can call your geonode project whatever you like **except 'geonode'**. Follow the naming conventions for python packages (generally lower case with underscores (``_``). In the examples below, replace ``{{ project_name }}`` with whatever you would like to name your project.* - To setup your project follow these instructions: 1. Generate the project ```bash git clone https://github.com/GeoNode/geonode-project.git -b - source /usr/share/virtualenvwrapper/virtualenvwrapper.sh - mkvirtualenv --python=/usr/bin/python3 {{ project_name }} - pip install Django==3.2.16 - - django-admin startproject --template=./geonode-project -e py,sh,md,rst,json,yml,ini,env,sample,properties -n monitoring-cron -n Dockerfile {{ project_name }} - - cd {{ project_name }} + cd project ``` 2. Create the .env file @@ -167,16 +101,6 @@ Once you have the project configured run the following command from the root fol 2. Access the site on http://localhost/ -## Run the instance in development mode - -### Use dedicated docker-compose files while developing - -**NOTE**: In this example we are going to keep localhost as the target IP for GeoNode - - ```bash - docker-compose -f docker-compose.development.yml -f docker-compose.development.override.yml up - ``` - ## Run the instance on a public site ### Preparation of the image (First time only) @@ -215,7 +139,7 @@ docker system prune -a ### Run a Backup ```bash -SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/backup.sh $BKP_FOLDER_NAME +SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./project/br/backup.sh $BKP_FOLDER_NAME ``` - BKP_FOLDER_NAME: @@ -232,13 +156,13 @@ SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/backup.sh $B e.g.: ```bash -docker exec -it django4{{project_name}} sh -c 'SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/backup.sh $BKP_FOLDER_NAME' +docker exec -it django4project sh -c 'SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./project/br/backup.sh $BKP_FOLDER_NAME' ``` ### Run a Restore ```bash -SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/restore.sh $BKP_FOLDER_NAME +SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./project/br/restore.sh $BKP_FOLDER_NAME ``` - BKP_FOLDER_NAME: @@ -255,7 +179,7 @@ SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/restore.sh $ e.g.: ```bash -docker exec -it django4{{project_name}} sh -c 'SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/restore.sh $BKP_FOLDER_NAME' +docker exec -it django4project sh -c 'SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./project/br/restore.sh $BKP_FOLDER_NAME' ``` ## Recommended: Track your changes diff --git a/docker-compose.yml b/docker-compose.yml index 435c9bea..c0033ffd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ x-common-django: env_file: - .env volumes: - # - './src:/usr/src/{{project_name}}' + # - './src:/usr/src/project' - statics:/mnt/volumes/statics - geoserver-data-dir:/geoserver_data/data - backup-restore:/backup_restore @@ -35,8 +35,8 @@ services: retries: 2 environment: - IS_CELERY=False - entrypoint: ["/usr/src/{{project_name}}/entrypoint.sh"] - command: "uwsgi --ini /usr/src/{{project_name}}/uwsgi.ini" + entrypoint: ["/usr/src/project/entrypoint.sh"] + command: "uwsgi --ini /usr/src/project/uwsgi.ini" # Celery worker that executes celery tasks created by Django. celery: @@ -47,7 +47,7 @@ services: condition: service_healthy environment: - IS_CELERY=True - entrypoint: ["/usr/src/{{project_name}}/entrypoint.sh"] + entrypoint: ["/usr/src/project/entrypoint.sh"] command: "celery-cmd" # Nginx is serving django static and media files and proxies to django and geonode diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 2c3ab8d7..55f8b34f 100755 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -9,7 +9,7 @@ invoke () { then /usr/local/bin/invoke $@ else - /usr/local/bin/invoke $@ > /usr/src/{{project_name}}/invoke.log 2>&1 + /usr/local/bin/invoke $@ > /usr/src/project/invoke.log 2>&1 fi echo "$@ tasks done" } diff --git a/src/manage.py b/src/manage.py index a1cb4497..0347cad0 100755 --- a/src/manage.py +++ b/src/manage.py @@ -27,5 +27,5 @@ if __name__ == "__main__": from django.core.management import execute_from_command_line - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") execute_from_command_line(sys.argv) diff --git a/src/project_name/__init__.py b/src/project/__init__.py similarity index 85% rename from src/project_name/__init__.py rename to src/project/__init__.py index ca5c786a..fc44954e 100644 --- a/src/project_name/__init__.py +++ b/src/project/__init__.py @@ -23,10 +23,10 @@ __version__ = (4, 2, 0, "dev", 0) -default_app_config = "{{ project_name }}.apps.AppConfig" +default_app_config = "project.apps.AppConfig" def get_version(): - import {{ project_name }}.version + import project.version - return {{ project_name }}.version.get_version(__version__) + return project.version.get_version(__version__) diff --git a/src/project_name/apps.py b/src/project/apps.py similarity index 95% rename from src/project_name/apps.py rename to src/project/apps.py index 352ad83f..2c2d2b00 100644 --- a/src/project_name/apps.py +++ b/src/project/apps.py @@ -33,8 +33,8 @@ def run_setup_hooks(*args, **kwargs): class AppConfig(BaseAppConfig): - name = "{{ project_name }}" - label = "{{ project_name }}" + name = "project" + label = "project" def ready(self): super(AppConfig, self).ready() diff --git a/src/project_name/br/backup.sh b/src/project/br/backup.sh similarity index 74% rename from src/project_name/br/backup.sh rename to src/project/br/backup.sh index b8fcef74..6da22396 100755 --- a/src/project_name/br/backup.sh +++ b/src/project/br/backup.sh @@ -1,7 +1,7 @@ #!/bin/sh # ########################################################## # Run a backup -# SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/backup.sh $BKP_FOLDER_NAME +# SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./project/br/backup.sh $BKP_FOLDER_NAME # - BKP_FOLDER_NAME: # Default value = backup_restore # Shared Backup Folder name. @@ -14,14 +14,14 @@ # Target Server URL, the one which must be synched. # # e.g.: -# docker exec -it django4{{project_name}} sh -c 'SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/backup.sh $BKP_FOLDER_NAME' +# docker exec -it django4project sh -c 'SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./project/br/backup.sh $BKP_FOLDER_NAME' # ########################################################## # Exit script in case of error set -e echo "-----------------------------------------------------" -echo "STARTING {{project_name}} BACKUP $(date)" +echo "STARTING project BACKUP $(date)" echo "-----------------------------------------------------" if [ "$1" != "" ]; then @@ -30,9 +30,9 @@ else BKP_FOLDER_NAME="backup_restore" fi -cd /usr/src/{{project_name}}/ +cd /usr/src/project/ -./manage.sh backup -i -f -c $PWD/{{project_name}}/br/settings_docker.ini --backup-dir /$BKP_FOLDER_NAME/ +./manage.sh backup -i -f -c $PWD/project/br/settings_docker.ini --backup-dir /$BKP_FOLDER_NAME/ BKP_FILE_LATEST=$(find /$BKP_FOLDER_NAME/*.zip -type f -exec stat -c '%Y %n' {} \; | sort -nr | awk 'NR==1,NR==1 {print $2}') BKP_FILE_NAME=$(echo $BKP_FILE_LATEST | tail -n 1 | grep -oP -m 1 "\/$BKP_FOLDER_NAME\/\K.*" | sed 's|.zip||') diff --git a/src/project_name/br/restore.sh b/src/project/br/restore.sh similarity index 88% rename from src/project_name/br/restore.sh rename to src/project/br/restore.sh index cdeb9e40..0e1a4a4d 100755 --- a/src/project_name/br/restore.sh +++ b/src/project/br/restore.sh @@ -1,7 +1,7 @@ #!/bin/sh # ########################################################## # Run a restore -# SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/restore.sh $BKP_FOLDER_NAME +# SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./project/br/restore.sh $BKP_FOLDER_NAME # - BKP_FOLDER_NAME: # Default value = backup_restore # Shared Backup Folder name. @@ -14,14 +14,14 @@ # Target Server URL, the one which must be synched. # # e.g.: -# docker exec -it django4{{project_name}} sh -c 'SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/restore.sh $BKP_FOLDER_NAME' +# docker exec -it django4project sh -c 'SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./project/br/restore.sh $BKP_FOLDER_NAME' # ########################################################## # Exit script in case of error set -e echo "-----------------------------------------------------" -echo "STARTING {{project_name}} RESTORE $(date)" +echo "STARTING project RESTORE $(date)" echo "-----------------------------------------------------" if [ "$1" != "" ]; then @@ -41,7 +41,7 @@ else echo "$SOURCE_URL --> $TARGET_URL" fi -cd /usr/src/{{project_name}}/ +cd /usr/src/project/ echo "-----------------------------------------------------" echo " 1. BACKUP $TARGET_URL" @@ -49,7 +49,7 @@ echo "-----------------------------------------------------" NEW_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) mkdir /$BKP_FOLDER_NAME/$NEW_UUID/ -SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./{{project_name}}/br/backup.sh $BKP_FOLDER_NAME/$NEW_UUID +SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./project/br/backup.sh $BKP_FOLDER_NAME/$NEW_UUID echo "-----------------------------------------------------" echo " 2. CHECK BACKUP.md5 $TARGET_URL" @@ -94,5 +94,5 @@ fi echo "-----------------------------------------------------" echo " - Original Backup of $TARGET_URL --> /$BKP_FOLDER_NAME/$NEW_UUID/" -echo "FINISHED {{project_name}} RESTORE $(date)" +echo "FINISHED project RESTORE $(date)" echo "-----------------------------------------------------" diff --git a/src/project_name/br/settings_docker.ini b/src/project/br/settings_docker.ini similarity index 100% rename from src/project_name/br/settings_docker.ini rename to src/project/br/settings_docker.ini diff --git a/src/project_name/celeryapp.py b/src/project/celeryapp.py similarity index 86% rename from src/project_name/celeryapp.py rename to src/project/celeryapp.py index f8f0a292..d6e77f47 100644 --- a/src/project_name/celeryapp.py +++ b/src/project/celeryapp.py @@ -23,9 +23,9 @@ import os from celery import Celery -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") -app = Celery("{{ project_name }}") +app = Celery("project") # Using a string here means the worker will not have to # pickle the object when using Windows. @@ -33,6 +33,6 @@ app.autodiscover_tasks() -@app.task(bind=True, name="{{ project_name }}.debug_task", queue="default") +@app.task(bind=True, name="project.debug_task", queue="default") def debug_task(self): print("Request: {!r}".format(self.request)) diff --git a/src/project_name/locale/.gitkeep b/src/project/locale/.gitkeep similarity index 100% rename from src/project_name/locale/.gitkeep rename to src/project/locale/.gitkeep diff --git a/src/project_name/settings.py b/src/project/settings.py similarity index 94% rename from src/project_name/settings.py rename to src/project/settings.py index d6b89cb6..61fba433 100644 --- a/src/project_name/settings.py +++ b/src/project/settings.py @@ -26,7 +26,7 @@ from urllib.request import urlopen, Request # Load more settings from a file called local_settings.py if it exists try: - from {{ project_name }}.local_settings import * + from project.local_settings import * # from geonode.local_settings import * except ImportError: from geonode.settings import * @@ -34,13 +34,13 @@ # # General Django development settings # -PROJECT_NAME = "{{ project_name }}" +PROJECT_NAME = "project" # add trailing slash to site url. geoserver url will be relative to this if not SITEURL.endswith("/"): SITEURL = "{}/".format(SITEURL) -SITENAME = os.getenv("SITENAME", "{{ project_name }}") +SITENAME = os.getenv("SITENAME", "project") # Defines the directory that contains the settings file as the LOCAL_ROOT # It is used for relative settings elsewhere. diff --git a/src/project_name/static/README b/src/project/static/README similarity index 100% rename from src/project_name/static/README rename to src/project/static/README diff --git a/src/project_name/static/css/site_base.css b/src/project/static/css/site_base.css similarity index 100% rename from src/project_name/static/css/site_base.css rename to src/project/static/css/site_base.css diff --git a/src/project_name/static/gulpfile.js b/src/project/static/gulpfile.js similarity index 100% rename from src/project_name/static/gulpfile.js rename to src/project/static/gulpfile.js diff --git a/src/project_name/static/img/README b/src/project/static/img/README similarity index 100% rename from src/project_name/static/img/README rename to src/project/static/img/README diff --git a/src/project_name/static/img/bing_aerial_w_labels.png b/src/project/static/img/bing_aerial_w_labels.png similarity index 100% rename from src/project_name/static/img/bing_aerial_w_labels.png rename to src/project/static/img/bing_aerial_w_labels.png diff --git a/src/project_name/static/img/bing_canvas_dark.png b/src/project/static/img/bing_canvas_dark.png similarity index 100% rename from src/project_name/static/img/bing_canvas_dark.png rename to src/project/static/img/bing_canvas_dark.png diff --git a/src/project_name/static/img/bing_road_on_demand.png b/src/project/static/img/bing_road_on_demand.png similarity index 100% rename from src/project_name/static/img/bing_road_on_demand.png rename to src/project/static/img/bing_road_on_demand.png diff --git a/src/project_name/static/js/README b/src/project/static/js/README similarity index 100% rename from src/project_name/static/js/README rename to src/project/static/js/README diff --git a/src/project_name/static/less/site_base.less b/src/project/static/less/site_base.less similarity index 100% rename from src/project_name/static/less/site_base.less rename to src/project/static/less/site_base.less diff --git a/src/project_name/static/package.json b/src/project/static/package.json similarity index 78% rename from src/project_name/static/package.json rename to src/project/static/package.json index 4cb6e593..921a4502 100644 --- a/src/project_name/static/package.json +++ b/src/project/static/package.json @@ -1,8 +1,8 @@ { - "name": "{{ project_name }}", + "name": "project", "version": "0.0.1", "author": "GeoNode Developers", - "description": "Static code and assets for {{ project_name }}", + "description": "Static code and assets for project", "contributors": [ { } diff --git a/src/project_name/templates/geonode-mapstore-client/_geonode_config.html b/src/project/templates/geonode-mapstore-client/_geonode_config.html similarity index 100% rename from src/project_name/templates/geonode-mapstore-client/_geonode_config.html rename to src/project/templates/geonode-mapstore-client/_geonode_config.html diff --git a/src/project_name/urls.py b/src/project/urls.py similarity index 100% rename from src/project_name/urls.py rename to src/project/urls.py diff --git a/src/project_name/version.py b/src/project/version.py similarity index 100% rename from src/project_name/version.py rename to src/project/version.py diff --git a/src/project_name/wsgi.py b/src/project/wsgi.py similarity index 93% rename from src/project_name/wsgi.py rename to src/project/wsgi.py index ac6f3ab9..a0ea342d 100644 --- a/src/project_name/wsgi.py +++ b/src/project/wsgi.py @@ -19,7 +19,7 @@ ######################################################################### """ -WSGI config for {{ project_name }} project. +WSGI config for project project. This module contains the WSGI application used by Django's development server and any production WSGI deployments. It should expose a module-level variable @@ -35,7 +35,7 @@ """ import os -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") # This application object is used by any WSGI server configured to use this # file. This includes Django's development server, if the WSGI_APPLICATION diff --git a/src/requirements.txt b/src/requirements.txt index d2b173cd..717665fd 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,2 +1,2 @@ --e git+https://github.com/GeoNode/geonode-mapstore-client.git@master#egg=django_geonode_mapstore_client # Commented otherwise we get conflicts with the git deps from geonode master +#-e git+https://github.com/GeoNode/geonode-mapstore-client.git@master#egg=django_geonode_mapstore_client -e git+https://github.com/GeoNode/geonode.git@master#egg=GeoNode diff --git a/src/setup.py b/src/setup.py index 77906972..6d39865d 100644 --- a/src/setup.py +++ b/src/setup.py @@ -29,19 +29,19 @@ def read(*rnames): setup( - name="{{ project_name }}", + name="project", version="0.0.1", author="", author_email="", - description="{{ project_name }}, based on GeoNode", + description="project, based on GeoNode", # Full list of classifiers can be found at: # http://pypi.python.org/pypi?%3Aaction=list_classifiers classifiers=[ "Development Status :: 1 - Planning", ], license="GPL", - keywords="{{ project_name }} geonode django", - url="https://github.com/{{ project_name }}/{{ project_name }}", + keywords="project geonode django", + url="https://github.com/project/project", packages=find_packages(), dependency_links=["git+https://github.com/GeoNode/geonode.git#egg=geonode"], include_package_data=True, diff --git a/src/tasks.py b/src/tasks.py index 44088b5d..db241c03 100644 --- a/src/tasks.py +++ b/src/tasks.py @@ -576,7 +576,7 @@ def _update_geodb_connstring(): def _localsettings(): - settings = os.getenv("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings") + settings = os.getenv("DJANGO_SETTINGS_MODULE", "project.settings") return settings diff --git a/src/uwsgi.ini b/src/uwsgi.ini index 7754daf2..84f577ec 100644 --- a/src/uwsgi.ini +++ b/src/uwsgi.ini @@ -4,8 +4,8 @@ http-socket = 0.0.0.0:8000 logto = /var/log/geonode.log # pidfile = /tmp/geonode.pid -chdir = /usr/src/{{project_name}}/ -module = {{project_name}}.wsgi:application +chdir = /usr/src/project/ +module = project.wsgi:application strict = false master = true @@ -16,7 +16,7 @@ die-on-term = true ; Shutdown when receiving SIGTERM (default need-app = true thunder-lock = true -touch-reload = /usr/src/{{project_name}}/{{project_name}}/wsgi.py +touch-reload = /usr/src/project/project/wsgi.py buffer-size = 32768 harakiri = 600 ; forcefully kill workers after 600 seconds @@ -40,7 +40,7 @@ cheaper-busyness-max = 70 ; Above this threshold, spawn new workers cheaper-busyness-backlog-alert = 16 ; Spawn emergency workers if more than this many requests are waiting in the queue cheaper-busyness-backlog-step = 2 ; How many emergency workers to create if there are too many requests in the queue -# cron = -1 -1 -1 -1 -1 sh -c '/usr/src/{{project_name}}/manage.sh collect_metrics -n -t xml'; +# cron = -1 -1 -1 -1 -1 sh -c '/usr/src/project/manage.sh collect_metrics -n -t xml'; # cron = 0 0 -1 -1 -1 sh -c 'find /backup_restore/ -type f -mtime +30 -exec rm -f {} \;' # Remove backup files older than 30 days except the most recent 3 files (a backup is composed by 3 files) cron = 0 0 -1 -1 -1 sh -c 'find /backup_restore/ -maxdepth 1 -type f -mtime +30 -printf "%T@ %p\n" | sort -n | head -n -3 | awk "{ print $2 }" | xargs -r rm' From e6cc762967dc3090b6486f79bd81dbfb06a888c9 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 16 Jan 2026 15:38:56 +0100 Subject: [PATCH 02/19] Change order of edtiable packages --- src/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/requirements.txt b/src/requirements.txt index 5a4d29a5..ed116f3e 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,4 +1,4 @@ # For an editable installation of GeoNode, you can perform the following inside the python venv: -# pip install -e git+https://github.com/GeoNode/geonode-mapstore-client.git@master#egg=django_geonode_mapstore_client # pip install -e git+https://github.com/GeoNode/geonode.git@master#egg=geonode +# pip install -e git+https://github.com/GeoNode/geonode-mapstore-client.git@master#egg=django_geonode_mapstore_client git+https://github.com/GeoNode/geonode.git@master#egg=GeoNode \ No newline at end of file From f356cbd25c0f0f4ad7f62d73c59c0dfc65083864 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 16 Jan 2026 17:39:00 +0100 Subject: [PATCH 03/19] renamed module to geonode_project --- .env.sample | 4 +-- Dockerfile | 26 ++++++++++-------- docker-compose.yml | 10 +++---- src/entrypoint.sh | 2 +- src/{project => geonode_project}/__init__.py | 6 ++-- src/{project => geonode_project}/apps.py | 4 +-- src/{project => geonode_project}/br/backup.sh | 4 +-- .../br/restore.sh | 4 +-- .../br/settings_docker.ini | 0 src/{project => geonode_project}/celeryapp.py | 6 ++-- .../locale/.gitkeep | 0 src/{project => geonode_project}/settings.py | 6 ++-- .../static/README | 0 .../static/css/site_base.css | 0 .../static/gulpfile.js | 0 .../static/img/README | 0 .../static/img/bing_aerial_w_labels.png | Bin .../static/img/bing_canvas_dark.png | Bin .../static/img/bing_road_on_demand.png | Bin .../static/js/README | 0 .../static/less/site_base.less | 0 .../static/package.json | 0 .../_geonode_config.html | 0 src/{project => geonode_project}/urls.py | 0 src/{project => geonode_project}/version.py | 2 +- src/{project => geonode_project}/wsgi.py | 2 +- src/manage.py | 2 +- src/setup.py | 6 ++-- src/tasks.py | 2 +- src/uwsgi.ini | 6 ++-- 30 files changed, 47 insertions(+), 45 deletions(-) rename src/{project => geonode_project}/__init__.py (85%) rename src/{project => geonode_project}/apps.py (95%) rename src/{project => geonode_project}/br/backup.sh (92%) rename src/{project => geonode_project}/br/restore.sh (96%) rename src/{project => geonode_project}/br/settings_docker.ini (100%) rename src/{project => geonode_project}/celeryapp.py (86%) rename src/{project => geonode_project}/locale/.gitkeep (100%) rename src/{project => geonode_project}/settings.py (95%) rename src/{project => geonode_project}/static/README (100%) rename src/{project => geonode_project}/static/css/site_base.css (100%) rename src/{project => geonode_project}/static/gulpfile.js (100%) rename src/{project => geonode_project}/static/img/README (100%) rename src/{project => geonode_project}/static/img/bing_aerial_w_labels.png (100%) rename src/{project => geonode_project}/static/img/bing_canvas_dark.png (100%) rename src/{project => geonode_project}/static/img/bing_road_on_demand.png (100%) rename src/{project => geonode_project}/static/js/README (100%) rename src/{project => geonode_project}/static/less/site_base.less (100%) rename src/{project => geonode_project}/static/package.json (100%) rename src/{project => geonode_project}/templates/geonode-mapstore-client/_geonode_config.html (100%) rename src/{project => geonode_project}/urls.py (100%) rename src/{project => geonode_project}/version.py (96%) rename src/{project => geonode_project}/wsgi.py (96%) diff --git a/.env.sample b/.env.sample index 10135cb0..d072ce56 100644 --- a/.env.sample +++ b/.env.sample @@ -1,4 +1,4 @@ -COMPOSE_PROJECT_NAME=project +COMPOSE_PROJECT_NAME=geonode_project DOCKER_ENV=production BACKUPS_VOLUME_DRIVER=local @@ -16,7 +16,7 @@ INVOKE_LOG_STDOUT=true # LANGUAGE_CODE=it-it # LANGUAGES=(('en-us','English'),('it-it','Italiano')) -DJANGO_SETTINGS_MODULE=project.settings +DJANGO_SETTINGS_MODULE=geonode_project.settings GEONODE_INSTANCE_NAME=geonode # ################# diff --git a/Dockerfile b/Dockerfile index 751b1017..37db12bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,24 @@ FROM geonode/geonode-base:latest-ubuntu-24.04 -LABEL GeoNode development team - -RUN mkdir -p /usr/src/project +RUN mkdir -p /usr/src/geonode RUN apt-get update -y && apt-get install curl wget unzip gnupg2 locales -y RUN sed -i -e 's/# C.UTF-8 UTF-8/C.UTF-8 UTF-8/' /etc/locale.gen && \ locale-gen -ENV LC_ALL C.UTF-8 -ENV LANG C.UTF-8 +ENV LC_ALL=C.UTF-8 +ENV LANG=C.UTF-8 + +WORKDIR /usr/src/geonode -COPY src /usr/src/project/ -WORKDIR /usr/src/project +COPY src/tasks.py \ + src/entrypoint.sh \ + src/requirements.txt \ + /usr/src/geonode/ COPY src/wait-for-databases.sh /usr/bin/wait-for-databases RUN chmod +x /usr/bin/wait-for-databases -RUN chmod +x /usr/src/project/tasks.py \ - && chmod +x /usr/src/project/entrypoint.sh +RUN chmod +x /usr/src/geonode/tasks.py \ + && chmod +x /usr/src/geonode/entrypoint.sh COPY src/celery.sh /usr/bin/celery-commands RUN chmod +x /usr/bin/celery-commands @@ -24,11 +26,13 @@ RUN chmod +x /usr/bin/celery-commands COPY src/celery-cmd /usr/bin/celery-cmd RUN chmod +x /usr/bin/celery-cmd -RUN yes w | pip install --src /usr/src -r requirements.txt &&\ - yes w | pip install -e . +RUN yes w | pip install --src /usr/src -r requirements.txt RUN apt-get autoremove --purge &&\ apt-get clean &&\ rm -rf /var/lib/apt/lists/* +COPY src/ /usr/src/geonode/ +RUN yes w | pip install -e . + EXPOSE 8000 diff --git a/docker-compose.yml b/docker-compose.yml index c0033ffd..cbe7b48b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.9' - # Common Django template for GeoNode and Celery services below x-common-django: &default-common-django @@ -8,7 +6,7 @@ x-common-django: env_file: - .env volumes: - # - './src:/usr/src/project' + # - './src:/usr/src/geonode' # Uncomment for local development - statics:/mnt/volumes/statics - geoserver-data-dir:/geoserver_data/data - backup-restore:/backup_restore @@ -35,8 +33,8 @@ services: retries: 2 environment: - IS_CELERY=False - entrypoint: ["/usr/src/project/entrypoint.sh"] - command: "uwsgi --ini /usr/src/project/uwsgi.ini" + entrypoint: ["/usr/src/geonode/entrypoint.sh"] + command: "uwsgi --ini /usr/src/geonode/uwsgi.ini" # Celery worker that executes celery tasks created by Django. celery: @@ -47,7 +45,7 @@ services: condition: service_healthy environment: - IS_CELERY=True - entrypoint: ["/usr/src/project/entrypoint.sh"] + entrypoint: ["/usr/src/geonode/entrypoint.sh"] command: "celery-cmd" # Nginx is serving django static and media files and proxies to django and geonode diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 55f8b34f..596f73e8 100755 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -9,7 +9,7 @@ invoke () { then /usr/local/bin/invoke $@ else - /usr/local/bin/invoke $@ > /usr/src/project/invoke.log 2>&1 + /usr/local/bin/invoke $@ > /usr/src/geonode/invoke.log 2>&1 fi echo "$@ tasks done" } diff --git a/src/project/__init__.py b/src/geonode_project/__init__.py similarity index 85% rename from src/project/__init__.py rename to src/geonode_project/__init__.py index fc44954e..2e490403 100644 --- a/src/project/__init__.py +++ b/src/geonode_project/__init__.py @@ -23,10 +23,10 @@ __version__ = (4, 2, 0, "dev", 0) -default_app_config = "project.apps.AppConfig" +default_app_config = "geonode_project.apps.AppConfig" def get_version(): - import project.version + import geonode_project.version - return project.version.get_version(__version__) + return geonode_project.version.get_version(__version__) diff --git a/src/project/apps.py b/src/geonode_project/apps.py similarity index 95% rename from src/project/apps.py rename to src/geonode_project/apps.py index 2c2d2b00..ad163ac0 100644 --- a/src/project/apps.py +++ b/src/geonode_project/apps.py @@ -33,8 +33,8 @@ def run_setup_hooks(*args, **kwargs): class AppConfig(BaseAppConfig): - name = "project" - label = "project" + name = "geonode_project" + label = "geonode_project" def ready(self): super(AppConfig, self).ready() diff --git a/src/project/br/backup.sh b/src/geonode_project/br/backup.sh similarity index 92% rename from src/project/br/backup.sh rename to src/geonode_project/br/backup.sh index 6da22396..e65f7911 100755 --- a/src/project/br/backup.sh +++ b/src/geonode_project/br/backup.sh @@ -30,9 +30,9 @@ else BKP_FOLDER_NAME="backup_restore" fi -cd /usr/src/project/ +cd /usr/src/geonode/ -./manage.sh backup -i -f -c $PWD/project/br/settings_docker.ini --backup-dir /$BKP_FOLDER_NAME/ +./manage.sh backup -i -f -c $PWD/geonode_project/br/settings_docker.ini --backup-dir /$BKP_FOLDER_NAME/ BKP_FILE_LATEST=$(find /$BKP_FOLDER_NAME/*.zip -type f -exec stat -c '%Y %n' {} \; | sort -nr | awk 'NR==1,NR==1 {print $2}') BKP_FILE_NAME=$(echo $BKP_FILE_LATEST | tail -n 1 | grep -oP -m 1 "\/$BKP_FOLDER_NAME\/\K.*" | sed 's|.zip||') diff --git a/src/project/br/restore.sh b/src/geonode_project/br/restore.sh similarity index 96% rename from src/project/br/restore.sh rename to src/geonode_project/br/restore.sh index 0e1a4a4d..504e11c4 100755 --- a/src/project/br/restore.sh +++ b/src/geonode_project/br/restore.sh @@ -41,7 +41,7 @@ else echo "$SOURCE_URL --> $TARGET_URL" fi -cd /usr/src/project/ +cd /usr/src/geonode/ echo "-----------------------------------------------------" echo " 1. BACKUP $TARGET_URL" @@ -49,7 +49,7 @@ echo "-----------------------------------------------------" NEW_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) mkdir /$BKP_FOLDER_NAME/$NEW_UUID/ -SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./project/br/backup.sh $BKP_FOLDER_NAME/$NEW_UUID +SOURCE_URL=$SOURCE_URL TARGET_URL=$TARGET_URL ./geonode_project/br/backup.sh $BKP_FOLDER_NAME/$NEW_UUID echo "-----------------------------------------------------" echo " 2. CHECK BACKUP.md5 $TARGET_URL" diff --git a/src/project/br/settings_docker.ini b/src/geonode_project/br/settings_docker.ini similarity index 100% rename from src/project/br/settings_docker.ini rename to src/geonode_project/br/settings_docker.ini diff --git a/src/project/celeryapp.py b/src/geonode_project/celeryapp.py similarity index 86% rename from src/project/celeryapp.py rename to src/geonode_project/celeryapp.py index d6e77f47..25e4cd24 100644 --- a/src/project/celeryapp.py +++ b/src/geonode_project/celeryapp.py @@ -23,9 +23,9 @@ import os from celery import Celery -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "geonode_project.settings") -app = Celery("project") +app = Celery("geonode_project") # Using a string here means the worker will not have to # pickle the object when using Windows. @@ -33,6 +33,6 @@ app.autodiscover_tasks() -@app.task(bind=True, name="project.debug_task", queue="default") +@app.task(bind=True, name="geonode_project.debug_task", queue="default") def debug_task(self): print("Request: {!r}".format(self.request)) diff --git a/src/project/locale/.gitkeep b/src/geonode_project/locale/.gitkeep similarity index 100% rename from src/project/locale/.gitkeep rename to src/geonode_project/locale/.gitkeep diff --git a/src/project/settings.py b/src/geonode_project/settings.py similarity index 95% rename from src/project/settings.py rename to src/geonode_project/settings.py index 61fba433..dfdc0766 100644 --- a/src/project/settings.py +++ b/src/geonode_project/settings.py @@ -26,7 +26,7 @@ from urllib.request import urlopen, Request # Load more settings from a file called local_settings.py if it exists try: - from project.local_settings import * + from geonode_project.local_settings import * # from geonode.local_settings import * except ImportError: from geonode.settings import * @@ -34,13 +34,13 @@ # # General Django development settings # -PROJECT_NAME = "project" +PROJECT_NAME = "geonode_project" # add trailing slash to site url. geoserver url will be relative to this if not SITEURL.endswith("/"): SITEURL = "{}/".format(SITEURL) -SITENAME = os.getenv("SITENAME", "project") +SITENAME = os.getenv("SITENAME", "geonode_project") # Defines the directory that contains the settings file as the LOCAL_ROOT # It is used for relative settings elsewhere. diff --git a/src/project/static/README b/src/geonode_project/static/README similarity index 100% rename from src/project/static/README rename to src/geonode_project/static/README diff --git a/src/project/static/css/site_base.css b/src/geonode_project/static/css/site_base.css similarity index 100% rename from src/project/static/css/site_base.css rename to src/geonode_project/static/css/site_base.css diff --git a/src/project/static/gulpfile.js b/src/geonode_project/static/gulpfile.js similarity index 100% rename from src/project/static/gulpfile.js rename to src/geonode_project/static/gulpfile.js diff --git a/src/project/static/img/README b/src/geonode_project/static/img/README similarity index 100% rename from src/project/static/img/README rename to src/geonode_project/static/img/README diff --git a/src/project/static/img/bing_aerial_w_labels.png b/src/geonode_project/static/img/bing_aerial_w_labels.png similarity index 100% rename from src/project/static/img/bing_aerial_w_labels.png rename to src/geonode_project/static/img/bing_aerial_w_labels.png diff --git a/src/project/static/img/bing_canvas_dark.png b/src/geonode_project/static/img/bing_canvas_dark.png similarity index 100% rename from src/project/static/img/bing_canvas_dark.png rename to src/geonode_project/static/img/bing_canvas_dark.png diff --git a/src/project/static/img/bing_road_on_demand.png b/src/geonode_project/static/img/bing_road_on_demand.png similarity index 100% rename from src/project/static/img/bing_road_on_demand.png rename to src/geonode_project/static/img/bing_road_on_demand.png diff --git a/src/project/static/js/README b/src/geonode_project/static/js/README similarity index 100% rename from src/project/static/js/README rename to src/geonode_project/static/js/README diff --git a/src/project/static/less/site_base.less b/src/geonode_project/static/less/site_base.less similarity index 100% rename from src/project/static/less/site_base.less rename to src/geonode_project/static/less/site_base.less diff --git a/src/project/static/package.json b/src/geonode_project/static/package.json similarity index 100% rename from src/project/static/package.json rename to src/geonode_project/static/package.json diff --git a/src/project/templates/geonode-mapstore-client/_geonode_config.html b/src/geonode_project/templates/geonode-mapstore-client/_geonode_config.html similarity index 100% rename from src/project/templates/geonode-mapstore-client/_geonode_config.html rename to src/geonode_project/templates/geonode-mapstore-client/_geonode_config.html diff --git a/src/project/urls.py b/src/geonode_project/urls.py similarity index 100% rename from src/project/urls.py rename to src/geonode_project/urls.py diff --git a/src/project/version.py b/src/geonode_project/version.py similarity index 96% rename from src/project/version.py rename to src/geonode_project/version.py index 66cb45ce..ae8ec85b 100644 --- a/src/project/version.py +++ b/src/geonode_project/version.py @@ -6,7 +6,7 @@ def get_version(version=None): "Returns a PEP 386-compliant version number from VERSION." if version is None: - from geonode import __version__ as version + from geonode_project import __version__ as version else: assert len(version) == 5 assert version[3] in ("unstable", "beta", "rc", "final") diff --git a/src/project/wsgi.py b/src/geonode_project/wsgi.py similarity index 96% rename from src/project/wsgi.py rename to src/geonode_project/wsgi.py index a0ea342d..f77f8b33 100644 --- a/src/project/wsgi.py +++ b/src/geonode_project/wsgi.py @@ -35,7 +35,7 @@ """ import os -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "geonode_project.settings") # This application object is used by any WSGI server configured to use this # file. This includes Django's development server, if the WSGI_APPLICATION diff --git a/src/manage.py b/src/manage.py index 0347cad0..e3c58ac4 100755 --- a/src/manage.py +++ b/src/manage.py @@ -27,5 +27,5 @@ if __name__ == "__main__": from django.core.management import execute_from_command_line - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "geonode_project.settings") execute_from_command_line(sys.argv) diff --git a/src/setup.py b/src/setup.py index 6d39865d..158762b0 100644 --- a/src/setup.py +++ b/src/setup.py @@ -29,11 +29,11 @@ def read(*rnames): setup( - name="project", + name="geonode_project", version="0.0.1", author="", author_email="", - description="project, based on GeoNode", + description="GeoNode Project", # Full list of classifiers can be found at: # http://pypi.python.org/pypi?%3Aaction=list_classifiers classifiers=[ @@ -41,7 +41,7 @@ def read(*rnames): ], license="GPL", keywords="project geonode django", - url="https://github.com/project/project", + url="https://github.com/GeoNode/geonode-project", packages=find_packages(), dependency_links=["git+https://github.com/GeoNode/geonode.git#egg=geonode"], include_package_data=True, diff --git a/src/tasks.py b/src/tasks.py index db241c03..63766529 100644 --- a/src/tasks.py +++ b/src/tasks.py @@ -576,7 +576,7 @@ def _update_geodb_connstring(): def _localsettings(): - settings = os.getenv("DJANGO_SETTINGS_MODULE", "project.settings") + settings = os.getenv("DJANGO_SETTINGS_MODULE", "geonode_project.settings") return settings diff --git a/src/uwsgi.ini b/src/uwsgi.ini index 84f577ec..b3a29884 100644 --- a/src/uwsgi.ini +++ b/src/uwsgi.ini @@ -4,8 +4,8 @@ http-socket = 0.0.0.0:8000 logto = /var/log/geonode.log # pidfile = /tmp/geonode.pid -chdir = /usr/src/project/ -module = project.wsgi:application +chdir = /usr/src/geonode/ +module = geonode_project.wsgi:application strict = false master = true @@ -16,7 +16,7 @@ die-on-term = true ; Shutdown when receiving SIGTERM (default need-app = true thunder-lock = true -touch-reload = /usr/src/project/project/wsgi.py +touch-reload = /usr/src/geonode/geonode_project/wsgi.py buffer-size = 32768 harakiri = 600 ; forcefully kill workers after 600 seconds From 0bbaaa07b628396db8a523ae228b74c31c49d2f5 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 16 Jan 2026 17:50:41 +0100 Subject: [PATCH 04/19] Removed version module --- src/geonode_project/__init__.py | 11 ------- src/geonode_project/version.py | 56 --------------------------------- 2 files changed, 67 deletions(-) delete mode 100644 src/geonode_project/version.py diff --git a/src/geonode_project/__init__.py b/src/geonode_project/__init__.py index 2e490403..c353e620 100644 --- a/src/geonode_project/__init__.py +++ b/src/geonode_project/__init__.py @@ -18,15 +18,4 @@ # ######################################################################### -import os - -__version__ = (4, 2, 0, "dev", 0) - - default_app_config = "geonode_project.apps.AppConfig" - - -def get_version(): - import geonode_project.version - - return geonode_project.version.get_version(__version__) diff --git a/src/geonode_project/version.py b/src/geonode_project/version.py deleted file mode 100644 index ae8ec85b..00000000 --- a/src/geonode_project/version.py +++ /dev/null @@ -1,56 +0,0 @@ -import datetime -import os -import subprocess - - -def get_version(version=None): - "Returns a PEP 386-compliant version number from VERSION." - if version is None: - from geonode_project import __version__ as version - else: - assert len(version) == 5 - assert version[3] in ("unstable", "beta", "rc", "final") - - # Now build the two parts of the version number: - # main = X.Y[.Z] - # sub = .devN - for pre-alpha releases - # | {a|b|c}N - for alpha, beta and rc releases - - parts = 2 if version[2] == 0 else 3 - main = ".".join(str(x) for x in version[:parts]) - - sub = "" - if version[3] == "unstable": - git_changeset = get_git_changeset() - if git_changeset: - sub = ".dev%s" % git_changeset - - elif version[3] != "final": - mapping = {"beta": "b", "rc": "rc"} - sub = mapping[version[3]] + str(version[4]) - - return main + sub - - -def get_git_changeset(): - """Returns a numeric identifier of the latest git changeset. - - The result is the UTC timestamp of the changeset in YYYYMMDDHHMMSS format. - This value isn't guaranteed to be unique, but collisions are very unlikely, - so it's sufficient for generating the development version numbers. - """ - repo_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - git_show = subprocess.Popen( - "git show --pretty=format:%ct --quiet HEAD", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=True, - cwd=repo_dir, - universal_newlines=True, - ) - timestamp = git_show.communicate()[0].partition("\n")[0] - try: - timestamp = datetime.datetime.utcfromtimestamp(int(timestamp)) - except ValueError: - return None - return timestamp.strftime("%Y%m%d%H%M%S") From a6174125d7be9784e16ec07c1cd64b1a62f40d37 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 16 Jan 2026 17:50:52 +0100 Subject: [PATCH 05/19] Migrated to pyproject --- Dockerfile | 1 + src/pyproject.toml | 27 ++++++++++++++++++++++++++ src/setup.py | 48 ---------------------------------------------- 3 files changed, 28 insertions(+), 48 deletions(-) create mode 100644 src/pyproject.toml delete mode 100644 src/setup.py diff --git a/Dockerfile b/Dockerfile index 37db12bf..453ffbc3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,6 +26,7 @@ RUN chmod +x /usr/bin/celery-commands COPY src/celery-cmd /usr/bin/celery-cmd RUN chmod +x /usr/bin/celery-cmd +RUN python -m pip install -U pip setuptools wheel RUN yes w | pip install --src /usr/src -r requirements.txt RUN apt-get autoremove --purge &&\ diff --git a/src/pyproject.toml b/src/pyproject.toml new file mode 100644 index 00000000..a8987c4c --- /dev/null +++ b/src/pyproject.toml @@ -0,0 +1,27 @@ +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "geonode_project" +version = "0.0.1" +description = "GeoNode Project" +readme = "README.md" +requires-python = ">=3.10" +license = { text = "GPL-3.0-or-later" } +keywords = ["project", "geonode", "django"] + +# Equivalent modern replacement for dependency_links: +dependencies = [ + "GeoNode @ git+https://github.com/GeoNode/geonode.git" +] + +[project.urls] +Homepage = "https://github.com/GeoNode/geonode-project" + +[tool.setuptools] +include-package-data = true + +[tool.setuptools.packages.find] +# Equivalent to find_packages() +where = ["."] diff --git a/src/setup.py b/src/setup.py deleted file mode 100644 index 158762b0..00000000 --- a/src/setup.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -######################################################################### -# -# Copyright (C) 2018 OSGeo -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -######################################################################### -import os - -from distutils.core import setup - -from setuptools import find_packages - - -def read(*rnames): - return open(os.path.join(os.path.dirname(__file__), *rnames)).read() - - -setup( - name="geonode_project", - version="0.0.1", - author="", - author_email="", - description="GeoNode Project", - # Full list of classifiers can be found at: - # http://pypi.python.org/pypi?%3Aaction=list_classifiers - classifiers=[ - "Development Status :: 1 - Planning", - ], - license="GPL", - keywords="project geonode django", - url="https://github.com/GeoNode/geonode-project", - packages=find_packages(), - dependency_links=["git+https://github.com/GeoNode/geonode.git#egg=geonode"], - include_package_data=True, -) From 5642de3f597d4c32f41843ec4311f6369d119831 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 16 Jan 2026 17:54:18 +0100 Subject: [PATCH 06/19] Fixed formatting --- .flake8 | 10 ++++++++++ src/geonode_project/settings.py | 5 +---- src/geonode_project/urls.py | 4 ++-- src/geonode_project/wsgi.py | 3 +-- src/tasks.py | 14 ++++++++++---- 5 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 .flake8 diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..86f5e764 --- /dev/null +++ b/.flake8 @@ -0,0 +1,10 @@ +[flake8] +max-line-length = 200 +exclude = + geonode/*/migrations/* + scripts + docs + static + migrations + node_modules +extend-ignore = E122,E124,E203,E731,F403,F405 \ No newline at end of file diff --git a/src/geonode_project/settings.py b/src/geonode_project/settings.py index dfdc0766..bf0e0e2b 100644 --- a/src/geonode_project/settings.py +++ b/src/geonode_project/settings.py @@ -20,10 +20,7 @@ # Django settings for the GeoNode project. import os -import ast -from urllib.parse import urlparse, urlunparse -from urllib.request import urlopen, Request # Load more settings from a file called local_settings.py if it exists try: from geonode_project.local_settings import * @@ -79,4 +76,4 @@ PROJECT_FIXTURES = [ # List project-related fixture files here, in the order they should be loaded. -] \ No newline at end of file +] diff --git a/src/geonode_project/urls.py b/src/geonode_project/urls.py index 33f20de0..a7bf9179 100644 --- a/src/geonode_project/urls.py +++ b/src/geonode_project/urls.py @@ -20,8 +20,8 @@ # Do not remove handler500 import. It is required to re-export # the custom error page handler for the GeoNode project -# related issue: https://github.com/GeoNode/geonode-project/issues/570 -from geonode.urls import urlpatterns, handler500 # noqa +# related issue: https://github.com/GeoNode/geonode-project/issues/570 +from geonode.urls import urlpatterns, handler500 # noqa """ # You can register your own urlpatterns here diff --git a/src/geonode_project/wsgi.py b/src/geonode_project/wsgi.py index f77f8b33..69e0004c 100644 --- a/src/geonode_project/wsgi.py +++ b/src/geonode_project/wsgi.py @@ -34,14 +34,13 @@ """ import os +from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "geonode_project.settings") # This application object is used by any WSGI server configured to use this # file. This includes Django's development server, if the WSGI_APPLICATION # setting points here. -from django.core.wsgi import get_wsgi_application - application = get_wsgi_application() # Apply WSGI middleware here. diff --git a/src/tasks.py b/src/tasks.py index 63766529..ee0b0b61 100644 --- a/src/tasks.py +++ b/src/tasks.py @@ -404,7 +404,8 @@ def fixtures(ctx): # Load Project related fixtures from django.conf import settings - project_fixtures = getattr(settings, 'PROJECT_FIXTURES', []) + + project_fixtures = getattr(settings, "PROJECT_FIXTURES", []) for fixture in project_fixtures: if fixture: @@ -412,11 +413,12 @@ def fixtures(ctx): try: ctx.run( f"python manage.py loaddata {fixture} --settings={_localsettings()}", - pty=True + pty=True, ) except Exception as e: print(f"Warning: Failed to load fixture {fixture}: {e}") + @task def collectstatic(ctx): print("************************static artifacts******************************") @@ -489,7 +491,9 @@ def collectmetrics(ctx): def initialized(ctx): print("**************************init file********************************") static_root = os.environ.get("STATIC_ROOT", "/mnt/volumes/statics/static/") - lockfile_dir = Path(static_root).parent # quite ugly, we're assuming such dir exists and is writable + lockfile_dir = Path( + static_root + ).parent # quite ugly, we're assuming such dir exists and is writable ctx.run(f"date > {lockfile_dir}/geonode_init.lock") @@ -519,13 +523,15 @@ def _docker_host_ip(): ) return ip_list[0] + def _is_valid_ip(ip): try: ipaddress.IPv4Address(ip) return True - except Exception as e: + except Exception: return False + def _container_exposed_port(component, instname): port = "80" try: From 9c4f1dd9c7a71f3ce38b675ec7ca6fda7c222476 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 16 Jan 2026 17:58:47 +0100 Subject: [PATCH 07/19] Removed monitoring legacy code --- .env.sample | 4 -- src/entrypoint.sh | 5 -- src/tasks.py | 167 ---------------------------------------------- 3 files changed, 176 deletions(-) diff --git a/.env.sample b/.env.sample index d072ce56..c204170a 100644 --- a/.env.sample +++ b/.env.sample @@ -163,10 +163,6 @@ OAUTH2_CLIENT_SECRET={clientsecret} API_LOCKDOWN=False TASTYPIE_APIKEY= -# ################# -# Production and -# Monitoring -# ################# DEBUG={debug} SECRET_KEY='{secret_key}' diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 596f73e8..254a600a 100755 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -35,10 +35,6 @@ echo GEODATABASE_URL=$GEODATABASE_URL echo SITEURL=$SITEURL echo ALLOWED_HOSTS=$ALLOWED_HOSTS echo GEOSERVER_PUBLIC_LOCATION=$GEOSERVER_PUBLIC_LOCATION -echo MONITORING_ENABLED=$MONITORING_ENABLED -echo MONITORING_HOST_NAME=$MONITORING_HOST_NAME -echo MONITORING_SERVICE_NAME=$MONITORING_SERVICE_NAME -echo MONITORING_DATA_TTL=$MONITORING_DATA_TTL # invoke waitfordbs @@ -54,7 +50,6 @@ else if [ ${FORCE_REINIT} = "true" ] || [ ${FORCE_REINIT} = "True" ] || [ ! -e "/mnt/volumes/statics/geonode_init.lock" ]; then invoke fixtures - invoke monitoringfixture invoke initialized invoke updateadmin fi diff --git a/src/tasks.py b/src/tasks.py index ee0b0b61..371302ec 100644 --- a/src/tasks.py +++ b/src/tasks.py @@ -89,12 +89,6 @@ def update(ctx): "static_root": os.environ.get("STATIC_ROOT", "/mnt/volumes/statics/static/"), "media_root": os.environ.get("MEDIA_ROOT", "/mnt/volumes/statics/uploaded/"), "geoip_path": os.environ.get("GEOIP_PATH", "/mnt/volumes/statics/geoip.db"), - "monitoring": os.environ.get("MONITORING_ENABLED", False), - "monitoring_host_name": os.environ.get("MONITORING_HOST_NAME", "geonode"), - "monitoring_service_name": os.environ.get( - "MONITORING_SERVICE_NAME", "local-geonode" - ), - "monitoring_data_ttl": os.environ.get("MONITORING_DATA_TTL", 7), "geonode_geodb_passwd": os.environ.get( "GEONODE_GEODATABASE_PASSWORD", "geonode_data" ), @@ -137,41 +131,6 @@ def update(ctx): ), pty=True, ) - ctx.run( - "echo export MONITORING_ENABLED=\ -{monitoring} >> {override_fn}".format( - **envs - ), - pty=True, - ) - ctx.run( - "echo export MONITORING_HOST_NAME=\ -{monitoring_host_name} >> {override_fn}".format( - **envs - ), - pty=True, - ) - ctx.run( - "echo export MONITORING_SERVICE_NAME=\ -{monitoring_service_name} >> {override_fn}".format( - **envs - ), - pty=True, - ) - ctx.run( - "echo export MONITORING_DATA_TTL=\ -{monitoring_data_ttl} >> {override_fn}".format( - **envs - ), - pty=True, - ) - ctx.run( - "echo export GEOIP_PATH=\ -{geoip_path} >> {override_fn}".format( - **envs - ), - pty=True, - ) ctx.run( "echo export GEONODE_GEODATABASE_PASSWORD=\ {geonode_geodb_passwd} >> {override_fn}".format( @@ -429,39 +388,6 @@ def collectstatic(ctx): ) -@task -def monitoringfixture(ctx): - if ast.literal_eval(os.environ.get("MONITORING_ENABLED", "False")): - print("*******************monitoring fixture********************************") - ctx.run("rm -rf /tmp/default_monitoring_apps_docker.json", pty=True) - _prepare_monitoring_fixture() - try: - ctx.run( - f"django-admin loaddata metric_data.json \ - --settings={_localsettings()}", - pty=True, - ) - ctx.run( - f"django-admin loaddata notifications.json \ - --settings={_localsettings()}", - pty=True, - ) - ctx.run( - f"django-admin loaddata /tmp/default_monitoring_apps_docker.json \ - --settings={_localsettings()}", - pty=True, - ) - except Exception as e: - logger.error(f"ERROR installing monitoring fixture: {str(e)}") - - -@task -def updategeoip(ctx): - print("**************************update geoip*******************************") - if ast.literal_eval(os.environ.get("MONITORING_ENABLED", "False")): - ctx.run(f"django-admin updategeoip --settings={_localsettings()}", pty=True) - - @task def updateadmin(ctx): print("***********************update admin details**************************") @@ -666,99 +592,6 @@ def _prepare_site_fixture(): json.dump(default_fixture, fixturefile) -def _prepare_monitoring_fixture(): - # upurl = urlparse(os.environ['SITEURL']) - # net_scheme = upurl.scheme - # net_loc = upurl.netloc - pub_ip = _geonode_public_host() - print(f"Public Hostname or IP is {pub_ip}") - pub_port = _geonode_public_port() - print(f"Public PORT is {pub_port}") - try: - geonode_ip = socket.gethostbyname("geonode") - except Exception: - geonode_ip = pub_ip - try: - geoserver_ip = socket.gethostbyname("geoserver") - except Exception: - geoserver_ip = pub_ip - d = "1970-01-01 00:00:00" - default_fixture = [ - { - "fields": { - "active": True, - "ip": str(geonode_ip), - "name": str(os.environ["MONITORING_HOST_NAME"]), - }, - "model": "monitoring.host", - "pk": 1, - }, - { - "fields": {"active": True, "ip": str(geoserver_ip), "name": "geoserver"}, - "model": "monitoring.host", - "pk": 2, - }, - { - "fields": { - "name": str(os.environ["MONITORING_SERVICE_NAME"]), - "url": str(os.environ["SITEURL"]), - "notes": "", - "last_check": d, - "active": True, - "host": 1, - "check_interval": "00:01:00", - "service_type": 1, - }, - "model": "monitoring.service", - "pk": 1, - }, - { - "fields": { - "name": "geoserver-hostgeonode", - "url": str(os.environ["SITEURL"]), - "notes": "", - "last_check": d, - "active": True, - "host": 1, - "check_interval": "00:01:00", - "service_type": 3, - }, - "model": "monitoring.service", - "pk": 2, - }, - { - "fields": { - "name": "geoserver-hostgeoserver", - "url": str(os.environ["GEOSERVER_PUBLIC_LOCATION"]), - "notes": "", - "last_check": d, - "active": True, - "host": 2, - "check_interval": "00:01:00", - "service_type": 4, - }, - "model": "monitoring.service", - "pk": 3, - }, - { - "fields": { - "name": "default-geoserver", - "url": "http://geoserver:8080/geoserver/", - "notes": "", - "last_check": d, - "active": True, - "host": 2, - "check_interval": "00:01:00", - "service_type": 2, - }, - "model": "monitoring.service", - "pk": 4, - }, - ] - with open("/tmp/default_monitoring_apps_docker.json", "w") as fixturefile: - json.dump(default_fixture, fixturefile) - - def _prepare_admin_fixture(admin_password, admin_email): from django.contrib.auth.hashers import make_password From cb82c515ecfaeda3e33d89825d3c50de2b9aa9a2 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 16 Jan 2026 17:59:54 +0100 Subject: [PATCH 08/19] Updated CodeQL workflow branches --- .github/workflows/codeql.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5b82453d..2cc3c4b2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,9 +2,9 @@ name: "CodeQL" on: push: - branches: [ "master", 4.1.x ] + branches: [ "master", 5.0.x ] pull_request: - branches: [ "master", 4.1.x ] + branches: [ "master", 5.0.x ] schedule: - cron: '38 4 * * 5' From b7253faccbde3b1508ef66596d1673ed06f9e4e2 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Mon, 19 Jan 2026 10:45:01 +0100 Subject: [PATCH 09/19] Django and Celery VS Code Dev Containers --- .devcontainer/celery/devcontainer.json | 67 +++++++++++++++++++++++++ .devcontainer/celery/docker-compose.yml | 13 +++++ .devcontainer/django/devcontainer.json | 67 +++++++++++++++++++++++++ .devcontainer/django/docker-compose.yml | 17 +++++++ .devcontainer/docker-compose-dev.yml | 0 .devcontainer/docker.sh | 4 ++ README.md | 32 ++++++++++++ 7 files changed, 200 insertions(+) create mode 100644 .devcontainer/celery/devcontainer.json create mode 100644 .devcontainer/celery/docker-compose.yml create mode 100644 .devcontainer/django/devcontainer.json create mode 100644 .devcontainer/django/docker-compose.yml create mode 100644 .devcontainer/docker-compose-dev.yml create mode 100755 .devcontainer/docker.sh diff --git a/.devcontainer/celery/devcontainer.json b/.devcontainer/celery/devcontainer.json new file mode 100644 index 00000000..770cd255 --- /dev/null +++ b/.devcontainer/celery/devcontainer.json @@ -0,0 +1,67 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Celery Container", + + // Update the 'dockerComposeFile' list if you have more compose files or use different names. + // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. + "dockerComposeFile": [ + "../../docker-compose.yml", + "./docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "celery", + + // The optional 'workspaceFolder' property is the path VS Code should open by default when + // connected. This is typically a file mount in .devcontainer/docker-compose.yml + "workspaceFolder": "/usr/src", + + // Set *default* container specific settings.json values on container create. + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.profiles.linux": { + "/bin/bash": { + "path": "/bin/bash", + "args": [ + "-l" + ] + } + }, + "terminal.integrated.defaultProfile.linux": "bash" + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-python.python", + "batisteo.vscode-django", + "mrorz.language-gettext", + "eamodio.gitlens", // Note: User preference + "bigonesystems.django" // Note: User preference + ] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 8000, + 8080, + 5432, + 5678 + ], + + // Uncomment the next line if you want start specific services in your Docker Compose config. + // "runServices": [], + + // Uncomment the next line if you want to keep your containers running after VS Code shuts down. + // "shutdownAction": "none", + + // Uncomment the next line to run commands after the container is created - for example installing curl. + // "postCreateCommand": "apt-get update && apt-get install -y curl", + + // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root. + // "remoteUser": "vscode" +} \ No newline at end of file diff --git a/.devcontainer/celery/docker-compose.yml b/.devcontainer/celery/docker-compose.yml new file mode 100644 index 00000000..74455727 --- /dev/null +++ b/.devcontainer/celery/docker-compose.yml @@ -0,0 +1,13 @@ +services: + + celery: + volumes: + - './src:/usr/src/geonode' + - './.devcontainer/celery/.vscode:/usr/src/.vscode' + - statics:/mnt/volumes/statics + - geoserver-data-dir:/geoserver_data/data + - backup-restore:/backup_restore + - data:/data + - tmp:/tmp + entrypoint: ["/usr/src/geonode/entrypoint.sh"] + command: sleep infinity diff --git a/.devcontainer/django/devcontainer.json b/.devcontainer/django/devcontainer.json new file mode 100644 index 00000000..c3de133d --- /dev/null +++ b/.devcontainer/django/devcontainer.json @@ -0,0 +1,67 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Django Container", + + // Update the 'dockerComposeFile' list if you have more compose files or use different names. + // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. + "dockerComposeFile": [ + "../../docker-compose.yml", + "./docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "django", + + // The optional 'workspaceFolder' property is the path VS Code should open by default when + // connected. This is typically a file mount in .devcontainer/docker-compose.yml + "workspaceFolder": "/usr/src", + + // Set *default* container specific settings.json values on container create. + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.profiles.linux": { + "/bin/bash": { + "path": "/bin/bash", + "args": [ + "-l" + ] + } + }, + "terminal.integrated.defaultProfile.linux": "bash", + "python.defaultInterpreterPath": "/usr/src/venv/bin/python", + "python.terminal.activateEnvironment": true, + "python.analysis.autoImportCompletions": true, + "python.analysis.typeCheckingMode": "basic", + "python.linting.enabled": true, + "python.formatting.provider": "black" + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-python.python", + "batisteo.vscode-django", + "mrorz.language-gettext", + "eamodio.gitlens", // Note: User preference + "bigonesystems.django" // Note: User preference + ] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + + // Uncomment the next line if you want start specific services in your Docker Compose config. + // "runServices": [], + + // Uncomment the next line if you want to keep your containers running after VS Code shuts down. + // "shutdownAction": "none", + + // Uncomment the next line to run commands after the container is created - for example installing curl. + // "postCreateCommand": "apt-get update && apt-get install -y curl", + + // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root. + // "remoteUser": "vscode" +} \ No newline at end of file diff --git a/.devcontainer/django/docker-compose.yml b/.devcontainer/django/docker-compose.yml new file mode 100644 index 00000000..6b0ca335 --- /dev/null +++ b/.devcontainer/django/docker-compose.yml @@ -0,0 +1,17 @@ +services: + + django: + ports: + - "8000:8000" + volumes: + - './src:/usr/src/geonode' + - './.devcontainer/django/.vscode:/usr/src/.vscode' + - statics:/mnt/volumes/statics + - geoserver-data-dir:/geoserver_data/data + - backup-restore:/backup_restore + - data:/data + - tmp:/tmp + healthcheck: + test: "echo 'Alive'" + entrypoint: ["/usr/src/geonode/entrypoint.sh"] + command: sleep infinity diff --git a/.devcontainer/docker-compose-dev.yml b/.devcontainer/docker-compose-dev.yml new file mode 100644 index 00000000..e69de29b diff --git a/.devcontainer/docker.sh b/.devcontainer/docker.sh new file mode 100755 index 00000000..4b5f7cfc --- /dev/null +++ b/.devcontainer/docker.sh @@ -0,0 +1,4 @@ +set -o allexport +source ../.env +set +o allexport +docker compose -f ../docker-compose.yml -f docker-compose-dev.yml -f ./django/docker-compose.yml -f ./celery/docker-compose.yml "$@" \ No newline at end of file diff --git a/README.md b/README.md index cc1ceca7..21583b2e 100644 --- a/README.md +++ b/README.md @@ -215,3 +215,35 @@ POSTGRESQL_MAX_CONNECTIONS=200 ``` In this case PostgreSQL will run accepting 200 maximum connections. + +## Developing with Dev Containers in VS Code + +This repo includes a .devcontainer folder with the condigurations to run Django and Celery as VS Code Dev Containers. +A `docker.sh` script aliases the `docker compose` command with the pre-configured arguments to use the customized compose files. + +You can run the Dev Container with the following commands: + +```bash +cd .devcontainer +chmod +x docker.sh +./docker.sh build +.docker.sh up -d +``` + +The Django and Celery containers will be started **without** running the services. They can be started manually inside the dev container. The container are autopopulated with VS Code development extensions for Python a list of pre-configured luanch configurations (for Django and Celery). + +Within VS Code open the command palette with `Ctrl+P` and search for `Dev Container: Reopen in Container`. VS Code will recognize the presence of the two Dev Container configurations for Django and Celery, and will allow to select one of them. +The VS Code will reopen inside the dev container. Wait a few seconds to let VS Code setup the dev extensions, then you should see the launch configurations. + +### Running Django +The `GeoNode` launch configuration for Django sets the `ASYNC_SIGNALS` env variable to False. This way GeoNode can be developed and debugged in sync mode, without Celery. +If you want to test Django in async mode, you can switch this variable to `True` and tun Celery (see below). + +Running the Debug sessions for Django will start Django with its internal development server. + +### Running Celery +Celery exectutions requires luanching three Debug processes: + + - `Celery Beat`: the scheduler + - `Celery Worker`: the generic worker process + - `Celery Harvesters`: The worker dedicated to the harvesters From c71215a3e52fe4742d60d33ad2a826d13cd53f00 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Mon, 19 Jan 2026 12:10:54 +0100 Subject: [PATCH 10/19] Rename the container project to project, to clarify it's not geonode itself --- Dockerfile | 12 ++++++------ docker-compose.yml | 8 ++++---- src/entrypoint.sh | 2 +- src/geonode_project/br/backup.sh | 2 +- src/geonode_project/br/restore.sh | 2 +- src/uwsgi.ini | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 453ffbc3..d68b6564 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM geonode/geonode-base:latest-ubuntu-24.04 -RUN mkdir -p /usr/src/geonode +RUN mkdir -p /usr/src/project RUN apt-get update -y && apt-get install curl wget unzip gnupg2 locales -y @@ -8,17 +8,17 @@ RUN sed -i -e 's/# C.UTF-8 UTF-8/C.UTF-8 UTF-8/' /etc/locale.gen && \ ENV LC_ALL=C.UTF-8 ENV LANG=C.UTF-8 -WORKDIR /usr/src/geonode +WORKDIR /usr/src/project COPY src/tasks.py \ src/entrypoint.sh \ src/requirements.txt \ - /usr/src/geonode/ + /usr/src/project/ COPY src/wait-for-databases.sh /usr/bin/wait-for-databases RUN chmod +x /usr/bin/wait-for-databases -RUN chmod +x /usr/src/geonode/tasks.py \ - && chmod +x /usr/src/geonode/entrypoint.sh +RUN chmod +x /usr/src/project/tasks.py \ + && chmod +x /usr/src/project/entrypoint.sh COPY src/celery.sh /usr/bin/celery-commands RUN chmod +x /usr/bin/celery-commands @@ -33,7 +33,7 @@ RUN apt-get autoremove --purge &&\ apt-get clean &&\ rm -rf /var/lib/apt/lists/* -COPY src/ /usr/src/geonode/ +COPY src/ /usr/src/project/ RUN yes w | pip install -e . EXPOSE 8000 diff --git a/docker-compose.yml b/docker-compose.yml index cbe7b48b..6a0775e4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,7 @@ x-common-django: env_file: - .env volumes: - # - './src:/usr/src/geonode' # Uncomment for local development + # - './src:/usr/src/project' # Uncomment for local development - statics:/mnt/volumes/statics - geoserver-data-dir:/geoserver_data/data - backup-restore:/backup_restore @@ -33,8 +33,8 @@ services: retries: 2 environment: - IS_CELERY=False - entrypoint: ["/usr/src/geonode/entrypoint.sh"] - command: "uwsgi --ini /usr/src/geonode/uwsgi.ini" + entrypoint: ["/usr/src/project/entrypoint.sh"] + command: "uwsgi --ini /usr/src/project/uwsgi.ini" # Celery worker that executes celery tasks created by Django. celery: @@ -45,7 +45,7 @@ services: condition: service_healthy environment: - IS_CELERY=True - entrypoint: ["/usr/src/geonode/entrypoint.sh"] + entrypoint: ["/usr/src/project/entrypoint.sh"] command: "celery-cmd" # Nginx is serving django static and media files and proxies to django and geonode diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 254a600a..c60e9d33 100755 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -9,7 +9,7 @@ invoke () { then /usr/local/bin/invoke $@ else - /usr/local/bin/invoke $@ > /usr/src/geonode/invoke.log 2>&1 + /usr/local/bin/invoke $@ > /usr/src/project/invoke.log 2>&1 fi echo "$@ tasks done" } diff --git a/src/geonode_project/br/backup.sh b/src/geonode_project/br/backup.sh index e65f7911..9554bbf9 100755 --- a/src/geonode_project/br/backup.sh +++ b/src/geonode_project/br/backup.sh @@ -30,7 +30,7 @@ else BKP_FOLDER_NAME="backup_restore" fi -cd /usr/src/geonode/ +cd /usr/src/project/ ./manage.sh backup -i -f -c $PWD/geonode_project/br/settings_docker.ini --backup-dir /$BKP_FOLDER_NAME/ diff --git a/src/geonode_project/br/restore.sh b/src/geonode_project/br/restore.sh index 504e11c4..ac7a6bf3 100755 --- a/src/geonode_project/br/restore.sh +++ b/src/geonode_project/br/restore.sh @@ -41,7 +41,7 @@ else echo "$SOURCE_URL --> $TARGET_URL" fi -cd /usr/src/geonode/ +cd /usr/src/project/ echo "-----------------------------------------------------" echo " 1. BACKUP $TARGET_URL" diff --git a/src/uwsgi.ini b/src/uwsgi.ini index b3a29884..9f59fd02 100644 --- a/src/uwsgi.ini +++ b/src/uwsgi.ini @@ -4,7 +4,7 @@ http-socket = 0.0.0.0:8000 logto = /var/log/geonode.log # pidfile = /tmp/geonode.pid -chdir = /usr/src/geonode/ +chdir = /usr/src/project/ module = geonode_project.wsgi:application strict = false @@ -16,7 +16,7 @@ die-on-term = true ; Shutdown when receiving SIGTERM (default need-app = true thunder-lock = true -touch-reload = /usr/src/geonode/geonode_project/wsgi.py +touch-reload = /usr/src/project/geonode_project/wsgi.py buffer-size = 32768 harakiri = 600 ; forcefully kill workers after 600 seconds From 650f02691f8225cf74b4e0163b5098efd27b60be Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Mon, 19 Jan 2026 12:13:11 +0100 Subject: [PATCH 11/19] Aligned dev container to project's folder name change --- .devcontainer/celery/docker-compose.yml | 4 ++-- .devcontainer/django/docker-compose.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.devcontainer/celery/docker-compose.yml b/.devcontainer/celery/docker-compose.yml index 74455727..ed09ea8c 100644 --- a/.devcontainer/celery/docker-compose.yml +++ b/.devcontainer/celery/docker-compose.yml @@ -2,12 +2,12 @@ services: celery: volumes: - - './src:/usr/src/geonode' + - './src:/usr/src/project' - './.devcontainer/celery/.vscode:/usr/src/.vscode' - statics:/mnt/volumes/statics - geoserver-data-dir:/geoserver_data/data - backup-restore:/backup_restore - data:/data - tmp:/tmp - entrypoint: ["/usr/src/geonode/entrypoint.sh"] + entrypoint: ["/usr/src/project/entrypoint.sh"] command: sleep infinity diff --git a/.devcontainer/django/docker-compose.yml b/.devcontainer/django/docker-compose.yml index 6b0ca335..5a8a0762 100644 --- a/.devcontainer/django/docker-compose.yml +++ b/.devcontainer/django/docker-compose.yml @@ -4,7 +4,7 @@ services: ports: - "8000:8000" volumes: - - './src:/usr/src/geonode' + - './src:/usr/src/project' - './.devcontainer/django/.vscode:/usr/src/.vscode' - statics:/mnt/volumes/statics - geoserver-data-dir:/geoserver_data/data @@ -13,5 +13,5 @@ services: - tmp:/tmp healthcheck: test: "echo 'Alive'" - entrypoint: ["/usr/src/geonode/entrypoint.sh"] + entrypoint: ["/usr/src/project/entrypoint.sh"] command: sleep infinity From dbad1d4f35e96839d042c48d8003d040be1b4045 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Tue, 20 Jan 2026 11:58:28 +0100 Subject: [PATCH 12/19] Add extraPaths for editabls installs because PyLance cannot solve PEP-660 editables --- src/geonode_project/settings.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/geonode_project/settings.py b/src/geonode_project/settings.py index bf0e0e2b..74e1dec3 100644 --- a/src/geonode_project/settings.py +++ b/src/geonode_project/settings.py @@ -77,3 +77,8 @@ PROJECT_FIXTURES = [ # List project-related fixture files here, in the order they should be loaded. ] + +SESSION_COOKIE_AGE = int(os.environ.get("SESSION_COOKIE_AGE", 30)) + +expire_env_str = os.environ.get("SESSION_EXPIRE_AT_BROWSER_CLOSE", "True") +SESSION_EXPIRE_AT_BROWSER_CLOSE = (expire_env_str == "True") \ No newline at end of file From 76b4362cbfefd1c5dc021b791c78d074af66e088 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Tue, 20 Jan 2026 12:10:27 +0100 Subject: [PATCH 13/19] Updated README --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 21583b2e..65dcb1bb 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,16 @@ The Django and Celery containers will be started **without** running the service Within VS Code open the command palette with `Ctrl+P` and search for `Dev Container: Reopen in Container`. VS Code will recognize the presence of the two Dev Container configurations for Django and Celery, and will allow to select one of them. The VS Code will reopen inside the dev container. Wait a few seconds to let VS Code setup the dev extensions, then you should see the launch configurations. +To simplify the debugging of GeoNode and the GeoNode client, these modules can be installed as editable (PEP-660) with the following commands: + +```bash +pip install -e git+https://github.com/GeoNode/geonode.git@master#egg=geonode --src=/usr/src +pip install -e git+https://github.com/GeoNode/geonode-mapstore-client.git@master#egg=django_geonode_mapstore_client --src=/usr/src +``` + +The modules will be isntalled under `/usr/src` and so at te root of the VS Code workspace. +Notice that at the time of writing Pylance can't resolve PEP-660 editable installs. For this reason the `.vscode/settings.py` contain extrPaths for the modules. + ### Running Django The `GeoNode` launch configuration for Django sets the `ASYNC_SIGNALS` env variable to False. This way GeoNode can be developed and debugged in sync mode, without Celery. If you want to test Django in async mode, you can switch this variable to `True` and tun Celery (see below). From 1a11f5c28eff9c62d7ee75f9c0a6bf1639aa066c Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Tue, 20 Jan 2026 12:14:23 +0100 Subject: [PATCH 14/19] Do not exclude .vscode folders for dev containers --- .devcontainer/celery/.vscode/launch.json | 83 ++++++++++++++++++++++ .devcontainer/celery/.vscode/settings.json | 11 +++ .devcontainer/django/.vscode/launch.json | 26 +++++++ .devcontainer/django/.vscode/settings.json | 11 +++ .gitignore | 2 +- 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/celery/.vscode/launch.json create mode 100644 .devcontainer/celery/.vscode/settings.json create mode 100644 .devcontainer/django/.vscode/launch.json create mode 100644 .devcontainer/django/.vscode/settings.json diff --git a/.devcontainer/celery/.vscode/launch.json b/.devcontainer/celery/.vscode/launch.json new file mode 100644 index 00000000..500546ba --- /dev/null +++ b/.devcontainer/celery/.vscode/launch.json @@ -0,0 +1,83 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Celery Beat", + "type": "debugpy", + "request": "launch", + "args": [ + "-A", + "geonode.celery_app:app", + "beat", + "--loglevel=DEBUG", + "--scheduler=celery.beat:PersistentScheduler", + "--pidfile=/tmp/celerybeat.pid" + ], + "env": { + "PYTHONPATH": "${workspaceFolder}/project:/usr/src/django-geonode-mapstore-client" + }, + "cwd": "${workspaceFolder}", + "autoStartBrowser": false, + "program": "${workspaceFolder}/venv/bin/celery", + "justMyCode": false + }, + { + "name": "Celery Worker", + "type": "debugpy", + "request": "launch", + "args": [ + "-A", + "geonode.celery_app:app", + "worker", + "--loglevel=DEBUG", + "--without-mingle", + "--without-gossip", + "-Ofair", + "-E", + "--statedb=worker.state", + "--concurrency=2", + "-n", + "worker@%h", + "-X", + "harvesting" + ], + "env": { + "PYTHONPATH": "${workspaceFolder}/project:/usr/src/django-geonode-mapstore-client" + }, + "cwd": "${workspaceFolder}", + "autoStartBrowser": false, + "program": "${workspaceFolder}/venv/bin/celery", + "justMyCode": false + }, + { + "name": "Celery Harvesters", + "type": "debugpy", + "request": "launch", + "args": [ + "-A", + "geonode.celery_app:app", + "worker", + "--loglevel=DEBUG", + "--without-mingle", + "--without-gossip", + "-Ofair", + "-E", + "--concurrency=2", + "-n", + "harvesting_worker@%h", + "-Q", + "harvesting" + ], + "env": { + "PYTHONPATH": "${workspaceFolder}/project:/usr/src/django-geonode-mapstore-client" + }, + "cwd": "${workspaceFolder}", + "autoStartBrowser": false, + "program": "${workspaceFolder}/venv/bin/celery", + "justMyCode": false + }, + ] +} \ No newline at end of file diff --git a/.devcontainer/celery/.vscode/settings.json b/.devcontainer/celery/.vscode/settings.json new file mode 100644 index 00000000..2b8eccc7 --- /dev/null +++ b/.devcontainer/celery/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "python.defaultInterpreterPath": "/usr/src/venv/bin/python", + "python.terminal.activateEnvironment": true, + "python.analysis.autoImportCompletions": true, + "python.analysis.typeCheckingMode": "basic", + "python.analysis.extraPaths": [ + "${workspaceFolder}/project", + "${workspaceFolder}/geonode", + "${workspaceFolder}/geonode_mapstore_client", + ] +} \ No newline at end of file diff --git a/.devcontainer/django/.vscode/launch.json b/.devcontainer/django/.vscode/launch.json new file mode 100644 index 00000000..d1b49354 --- /dev/null +++ b/.devcontainer/django/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "name": "GeoNode", + "type": "debugpy", + "request": "launch", + "args": [ + "runserver", + "0.0.0.0:8000" + ], + "env": { + "ASYNC_SIGNALS": "False", + "SESSION_COOKIE_AGE": "120", + }, + "django": true, + "autoStartBrowser": false, + "program": "${workspaceFolder}/project/manage.py", + "justMyCode": false + } + ] +} \ No newline at end of file diff --git a/.devcontainer/django/.vscode/settings.json b/.devcontainer/django/.vscode/settings.json new file mode 100644 index 00000000..2b8eccc7 --- /dev/null +++ b/.devcontainer/django/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "python.defaultInterpreterPath": "/usr/src/venv/bin/python", + "python.terminal.activateEnvironment": true, + "python.analysis.autoImportCompletions": true, + "python.analysis.typeCheckingMode": "basic", + "python.analysis.extraPaths": [ + "${workspaceFolder}/project", + "${workspaceFolder}/geonode", + "${workspaceFolder}/geonode_mapstore_client", + ] +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4137f8f4..041e4c0a 100644 --- a/.gitignore +++ b/.gitignore @@ -66,7 +66,7 @@ development.db-journal local_settings.py .idea/ -.vscode/ +/.vscode/ .vagrant/ Vagrantfile /.env From bd3a87038d6e047f566e497777c31cb1ed4282d1 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 23 Jan 2026 16:54:56 +0100 Subject: [PATCH 15/19] removed some extensions from dev containers --- .devcontainer/celery/.vscode/settings.json | 3 --- .devcontainer/celery/devcontainer.json | 6 +----- .devcontainer/django/.vscode/launch.json | 1 - .devcontainer/django/.vscode/settings.json | 3 --- .devcontainer/django/devcontainer.json | 11 ++--------- 5 files changed, 3 insertions(+), 21 deletions(-) diff --git a/.devcontainer/celery/.vscode/settings.json b/.devcontainer/celery/.vscode/settings.json index 2b8eccc7..654d48e5 100644 --- a/.devcontainer/celery/.vscode/settings.json +++ b/.devcontainer/celery/.vscode/settings.json @@ -1,8 +1,5 @@ { "python.defaultInterpreterPath": "/usr/src/venv/bin/python", - "python.terminal.activateEnvironment": true, - "python.analysis.autoImportCompletions": true, - "python.analysis.typeCheckingMode": "basic", "python.analysis.extraPaths": [ "${workspaceFolder}/project", "${workspaceFolder}/geonode", diff --git a/.devcontainer/celery/devcontainer.json b/.devcontainer/celery/devcontainer.json index 770cd255..d648d9e9 100644 --- a/.devcontainer/celery/devcontainer.json +++ b/.devcontainer/celery/devcontainer.json @@ -36,11 +36,7 @@ // Add the IDs of extensions you want installed when the container is created. "extensions": [ - "ms-python.python", - "batisteo.vscode-django", - "mrorz.language-gettext", - "eamodio.gitlens", // Note: User preference - "bigonesystems.django" // Note: User preference + "ms-python.python" ] } }, diff --git a/.devcontainer/django/.vscode/launch.json b/.devcontainer/django/.vscode/launch.json index d1b49354..b0c69a0b 100644 --- a/.devcontainer/django/.vscode/launch.json +++ b/.devcontainer/django/.vscode/launch.json @@ -15,7 +15,6 @@ ], "env": { "ASYNC_SIGNALS": "False", - "SESSION_COOKIE_AGE": "120", }, "django": true, "autoStartBrowser": false, diff --git a/.devcontainer/django/.vscode/settings.json b/.devcontainer/django/.vscode/settings.json index 2b8eccc7..654d48e5 100644 --- a/.devcontainer/django/.vscode/settings.json +++ b/.devcontainer/django/.vscode/settings.json @@ -1,8 +1,5 @@ { "python.defaultInterpreterPath": "/usr/src/venv/bin/python", - "python.terminal.activateEnvironment": true, - "python.analysis.autoImportCompletions": true, - "python.analysis.typeCheckingMode": "basic", "python.analysis.extraPaths": [ "${workspaceFolder}/project", "${workspaceFolder}/geonode", diff --git a/.devcontainer/django/devcontainer.json b/.devcontainer/django/devcontainer.json index c3de133d..873dfb77 100644 --- a/.devcontainer/django/devcontainer.json +++ b/.devcontainer/django/devcontainer.json @@ -34,22 +34,15 @@ "terminal.integrated.defaultProfile.linux": "bash", "python.defaultInterpreterPath": "/usr/src/venv/bin/python", "python.terminal.activateEnvironment": true, - "python.analysis.autoImportCompletions": true, - "python.analysis.typeCheckingMode": "basic", - "python.linting.enabled": true, "python.formatting.provider": "black" }, // Add the IDs of extensions you want installed when the container is created. "extensions": [ - "ms-python.python", - "batisteo.vscode-django", - "mrorz.language-gettext", - "eamodio.gitlens", // Note: User preference - "bigonesystems.django" // Note: User preference + "ms-python.python" ] } - }, + } // Use 'forwardPorts' to make a list of ports inside the container available locally. From 981116cf667d613e01082e1a03e5391d8093d032 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 23 Jan 2026 17:41:18 +0100 Subject: [PATCH 16/19] do not expose port 8000 in dev container --- .devcontainer/django/docker-compose.yml | 2 -- .devcontainer/docker.sh | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.devcontainer/django/docker-compose.yml b/.devcontainer/django/docker-compose.yml index 5a8a0762..83e1a24b 100644 --- a/.devcontainer/django/docker-compose.yml +++ b/.devcontainer/django/docker-compose.yml @@ -1,8 +1,6 @@ services: django: - ports: - - "8000:8000" volumes: - './src:/usr/src/project' - './.devcontainer/django/.vscode:/usr/src/.vscode' diff --git a/.devcontainer/docker.sh b/.devcontainer/docker.sh index 4b5f7cfc..94014dd2 100755 --- a/.devcontainer/docker.sh +++ b/.devcontainer/docker.sh @@ -1,3 +1,4 @@ +#!/bin/bash set -o allexport source ../.env set +o allexport From 8160e40ba4236352220f187f578fddd4dcaf033d Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 23 Jan 2026 18:04:50 +0100 Subject: [PATCH 17/19] Removed Celery dev container --- .../{celery => }/.vscode/launch.json | 39 ++++++++---- .../{celery => }/.vscode/settings.json | 0 .devcontainer/celery/devcontainer.json | 63 ------------------- .devcontainer/celery/docker-compose.yml | 13 ---- .devcontainer/{django => }/devcontainer.json | 2 +- .devcontainer/django/.vscode/launch.json | 25 -------- .devcontainer/django/.vscode/settings.json | 8 --- .devcontainer/docker-compose-dev.yml | 0 .devcontainer/{django => }/docker-compose.yml | 5 +- .devcontainer/docker.sh | 2 +- 10 files changed, 34 insertions(+), 123 deletions(-) rename .devcontainer/{celery => }/.vscode/launch.json (85%) rename .devcontainer/{celery => }/.vscode/settings.json (100%) delete mode 100644 .devcontainer/celery/devcontainer.json delete mode 100644 .devcontainer/celery/docker-compose.yml rename .devcontainer/{django => }/devcontainer.json (98%) delete mode 100644 .devcontainer/django/.vscode/launch.json delete mode 100644 .devcontainer/django/.vscode/settings.json delete mode 100644 .devcontainer/docker-compose-dev.yml rename .devcontainer/{django => }/docker-compose.yml (71%) diff --git a/.devcontainer/celery/.vscode/launch.json b/.devcontainer/.vscode/launch.json similarity index 85% rename from .devcontainer/celery/.vscode/launch.json rename to .devcontainer/.vscode/launch.json index 500546ba..8aa448c3 100644 --- a/.devcontainer/celery/.vscode/launch.json +++ b/.devcontainer/.vscode/launch.json @@ -4,24 +4,21 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { - "name": "Celery Beat", + "name": "GeoNode", "type": "debugpy", "request": "launch", "args": [ - "-A", - "geonode.celery_app:app", - "beat", - "--loglevel=DEBUG", - "--scheduler=celery.beat:PersistentScheduler", - "--pidfile=/tmp/celerybeat.pid" + "runserver", + "0.0.0.0:8000" ], "env": { - "PYTHONPATH": "${workspaceFolder}/project:/usr/src/django-geonode-mapstore-client" + "ASYNC_SIGNALS": "True", }, - "cwd": "${workspaceFolder}", + "django": true, "autoStartBrowser": false, - "program": "${workspaceFolder}/venv/bin/celery", + "program": "${workspaceFolder}/project/manage.py", "justMyCode": false }, { @@ -52,6 +49,26 @@ "program": "${workspaceFolder}/venv/bin/celery", "justMyCode": false }, + { + "name": "Celery Beat", + "type": "debugpy", + "request": "launch", + "args": [ + "-A", + "geonode.celery_app:app", + "beat", + "--loglevel=DEBUG", + "--scheduler=celery.beat:PersistentScheduler", + "--pidfile=/tmp/celerybeat.pid" + ], + "env": { + "PYTHONPATH": "${workspaceFolder}/project:/usr/src/django-geonode-mapstore-client" + }, + "cwd": "${workspaceFolder}", + "autoStartBrowser": false, + "program": "${workspaceFolder}/venv/bin/celery", + "justMyCode": false + }, { "name": "Celery Harvesters", "type": "debugpy", @@ -78,6 +95,6 @@ "autoStartBrowser": false, "program": "${workspaceFolder}/venv/bin/celery", "justMyCode": false - }, + } ] } \ No newline at end of file diff --git a/.devcontainer/celery/.vscode/settings.json b/.devcontainer/.vscode/settings.json similarity index 100% rename from .devcontainer/celery/.vscode/settings.json rename to .devcontainer/.vscode/settings.json diff --git a/.devcontainer/celery/devcontainer.json b/.devcontainer/celery/devcontainer.json deleted file mode 100644 index d648d9e9..00000000 --- a/.devcontainer/celery/devcontainer.json +++ /dev/null @@ -1,63 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/docker-existing-docker-compose -// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. -{ - "name": "Celery Container", - - // Update the 'dockerComposeFile' list if you have more compose files or use different names. - // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. - "dockerComposeFile": [ - "../../docker-compose.yml", - "./docker-compose.yml" - ], - - // The 'service' property is the name of the service for the container that VS Code should - // use. Update this value and .devcontainer/docker-compose.yml to the real service name. - "service": "celery", - - // The optional 'workspaceFolder' property is the path VS Code should open by default when - // connected. This is typically a file mount in .devcontainer/docker-compose.yml - "workspaceFolder": "/usr/src", - - // Set *default* container specific settings.json values on container create. - "customizations": { - "vscode": { - "settings": { - "terminal.integrated.profiles.linux": { - "/bin/bash": { - "path": "/bin/bash", - "args": [ - "-l" - ] - } - }, - "terminal.integrated.defaultProfile.linux": "bash" - }, - - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "ms-python.python" - ] - } - }, - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - "forwardPorts": [ - 8000, - 8080, - 5432, - 5678 - ], - - // Uncomment the next line if you want start specific services in your Docker Compose config. - // "runServices": [], - - // Uncomment the next line if you want to keep your containers running after VS Code shuts down. - // "shutdownAction": "none", - - // Uncomment the next line to run commands after the container is created - for example installing curl. - // "postCreateCommand": "apt-get update && apt-get install -y curl", - - // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root. - // "remoteUser": "vscode" -} \ No newline at end of file diff --git a/.devcontainer/celery/docker-compose.yml b/.devcontainer/celery/docker-compose.yml deleted file mode 100644 index ed09ea8c..00000000 --- a/.devcontainer/celery/docker-compose.yml +++ /dev/null @@ -1,13 +0,0 @@ -services: - - celery: - volumes: - - './src:/usr/src/project' - - './.devcontainer/celery/.vscode:/usr/src/.vscode' - - statics:/mnt/volumes/statics - - geoserver-data-dir:/geoserver_data/data - - backup-restore:/backup_restore - - data:/data - - tmp:/tmp - entrypoint: ["/usr/src/project/entrypoint.sh"] - command: sleep infinity diff --git a/.devcontainer/django/devcontainer.json b/.devcontainer/devcontainer.json similarity index 98% rename from .devcontainer/django/devcontainer.json rename to .devcontainer/devcontainer.json index 873dfb77..3e8f2452 100644 --- a/.devcontainer/django/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,7 @@ // Update the 'dockerComposeFile' list if you have more compose files or use different names. // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. "dockerComposeFile": [ - "../../docker-compose.yml", + "../docker-compose.yml", "./docker-compose.yml" ], diff --git a/.devcontainer/django/.vscode/launch.json b/.devcontainer/django/.vscode/launch.json deleted file mode 100644 index b0c69a0b..00000000 --- a/.devcontainer/django/.vscode/launch.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - - { - "name": "GeoNode", - "type": "debugpy", - "request": "launch", - "args": [ - "runserver", - "0.0.0.0:8000" - ], - "env": { - "ASYNC_SIGNALS": "False", - }, - "django": true, - "autoStartBrowser": false, - "program": "${workspaceFolder}/project/manage.py", - "justMyCode": false - } - ] -} \ No newline at end of file diff --git a/.devcontainer/django/.vscode/settings.json b/.devcontainer/django/.vscode/settings.json deleted file mode 100644 index 654d48e5..00000000 --- a/.devcontainer/django/.vscode/settings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "python.defaultInterpreterPath": "/usr/src/venv/bin/python", - "python.analysis.extraPaths": [ - "${workspaceFolder}/project", - "${workspaceFolder}/geonode", - "${workspaceFolder}/geonode_mapstore_client", - ] -} \ No newline at end of file diff --git a/.devcontainer/docker-compose-dev.yml b/.devcontainer/docker-compose-dev.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/.devcontainer/django/docker-compose.yml b/.devcontainer/docker-compose.yml similarity index 71% rename from .devcontainer/django/docker-compose.yml rename to .devcontainer/docker-compose.yml index 83e1a24b..4522b9e8 100644 --- a/.devcontainer/django/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -3,7 +3,7 @@ services: django: volumes: - './src:/usr/src/project' - - './.devcontainer/django/.vscode:/usr/src/.vscode' + - './.devcontainer/.vscode:/usr/src/.vscode' - statics:/mnt/volumes/statics - geoserver-data-dir:/geoserver_data/data - backup-restore:/backup_restore @@ -13,3 +13,6 @@ services: test: "echo 'Alive'" entrypoint: ["/usr/src/project/entrypoint.sh"] command: sleep infinity + celery: + entrypoint: ["/usr/src/project/entrypoint.sh"] + command: sleep infinity diff --git a/.devcontainer/docker.sh b/.devcontainer/docker.sh index 94014dd2..9f53030f 100755 --- a/.devcontainer/docker.sh +++ b/.devcontainer/docker.sh @@ -2,4 +2,4 @@ set -o allexport source ../.env set +o allexport -docker compose -f ../docker-compose.yml -f docker-compose-dev.yml -f ./django/docker-compose.yml -f ./celery/docker-compose.yml "$@" \ No newline at end of file +docker compose -f ../docker-compose.yml -f ./docker-compose.yml "$@" \ No newline at end of file From ce678540fbdfae8b6f49aaf7ffce54e9134d53f4 Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 23 Jan 2026 18:09:10 +0100 Subject: [PATCH 18/19] Update README --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 65dcb1bb..d8bf8796 100644 --- a/README.md +++ b/README.md @@ -218,7 +218,7 @@ In this case PostgreSQL will run accepting 200 maximum connections. ## Developing with Dev Containers in VS Code -This repo includes a .devcontainer folder with the condigurations to run Django and Celery as VS Code Dev Containers. +This repo includes a .devcontainer folder with the condigurations to run Django and Celery inside a VS Code Dev Container. A `docker.sh` script aliases the `docker compose` command with the pre-configured arguments to use the customized compose files. You can run the Dev Container with the following commands: @@ -230,10 +230,10 @@ chmod +x docker.sh .docker.sh up -d ``` -The Django and Celery containers will be started **without** running the services. They can be started manually inside the dev container. The container are autopopulated with VS Code development extensions for Python a list of pre-configured luanch configurations (for Django and Celery). +The Django and the Celery containers will be started **without** running the Django and Celery processes. They can be started manually inside the dev container. The container is autopopulated with VS Code development extensions for Python and a list of pre-configured luanch configurations (for Django and Celery). -Within VS Code open the command palette with `Ctrl+P` and search for `Dev Container: Reopen in Container`. VS Code will recognize the presence of the two Dev Container configurations for Django and Celery, and will allow to select one of them. -The VS Code will reopen inside the dev container. Wait a few seconds to let VS Code setup the dev extensions, then you should see the launch configurations. +Within VS Code open the command palette with `Ctrl+P` and run `Dev Container: Reopen in Container`. VS Code will recognize the presence of the two dev container, and will allow to reopen the current window inside the container's workspace. +Wait a few seconds to let VS Code setup the dev extensions, then you should see the launch configurations. To simplify the debugging of GeoNode and the GeoNode client, these modules can be installed as editable (PEP-660) with the following commands: @@ -254,6 +254,8 @@ Running the Debug sessions for Django will start Django with its internal develo ### Running Celery Celery exectutions requires luanching three Debug processes: - - `Celery Beat`: the scheduler - `Celery Worker`: the generic worker process + - `Celery Beat`: the scheduler - `Celery Harvesters`: The worker dedicated to the harvesters + +You can also remove the `-X harvesting` argument inside the Celery Worker launch configuration to have also the harvesters running in the same worker. this way you don't need to run the Beat and the Celery Harvesters processes. From 5d48ec8aa12a7b5c90ecb198adef126c5c8e85cc Mon Sep 17 00:00:00 2001 From: "G.Allegri" Date: Fri, 23 Jan 2026 18:13:32 +0100 Subject: [PATCH 19/19] Cleanup --- src/geonode_project/settings.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/geonode_project/settings.py b/src/geonode_project/settings.py index 74e1dec3..651f8d7b 100644 --- a/src/geonode_project/settings.py +++ b/src/geonode_project/settings.py @@ -76,9 +76,4 @@ PROJECT_FIXTURES = [ # List project-related fixture files here, in the order they should be loaded. -] - -SESSION_COOKIE_AGE = int(os.environ.get("SESSION_COOKIE_AGE", 30)) - -expire_env_str = os.environ.get("SESSION_EXPIRE_AT_BROWSER_CLOSE", "True") -SESSION_EXPIRE_AT_BROWSER_CLOSE = (expire_env_str == "True") \ No newline at end of file +] \ No newline at end of file