Loading docker-compose.prod.yml +14 −0 Original line number Diff line number Diff line Loading @@ -9,13 +9,27 @@ services: TRAPPER_USER_UID: ${TRAPPER_USER_UID} TRAPPER_USER_GID: ${TRAPPER_USER_GID} command: /app/command_prod.sh # No ports exposed - accessed only via nginx proxy ports: [] postgres: # No ports exposed - accessed only by internal services ports: [] # trapper - main app celery: <<: *trapper ports: [] command: celery -A trapper worker -l INFO --logfile=logs/celery_main # celery beat worker celery_beat: <<: *trapper ports: [] command: celery -A trapper beat -l INFO --logfile=logs/celery_beat_main # uploader - chunked upload FastAPI service trapper_uploader: <<: *trapper ports: [] command: python manage.py start_uploader_server docker-compose.yml +23 −6 Original line number Diff line number Diff line Loading @@ -13,8 +13,12 @@ x-trapper: &trapper_base - postgres - rabbitmq - memcached # Port exposed to localhost only for development/debugging # In production, the application is accessed via nginx proxy ports: - "8000:8000" - "127.0.0.1:8000:8000" expose: - "8000" volumes: - ./trapper/trapper-project:/app/trapper-project - ./trapper/static:/app/static Loading @@ -29,8 +33,12 @@ services: postgres: image: registry.gitlab.com/trapper-project/trapper-postgresql:timescaledb shm_size: 2g # Port exposed to localhost only for development/debugging # In production, the application is accessed via nginx proxy ports: - 5432:5432 - "127.0.0.1:5432:5432" expose: - "5432" volumes: - type: volume source: pgdata Loading @@ -42,6 +50,9 @@ services: image: rabbitmq:3-management environment: RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS: "-rabbit consumer_timeout 36000000" expose: - "5672" # AMQP port - "15672" # Management UI volumes: - rabbitmq_data:/var/lib/rabbitmq <<: *default_service Loading @@ -49,8 +60,12 @@ services: # memcached memcached: image: memcached ports: - "11211:11211" # Port exposed only for internal network communication # Uncomment the line below if you need direct external access for debugging: # ports: # - "11211:11211" expose: - "11211" entrypoint: - memcached - -m 64 Loading @@ -58,7 +73,7 @@ services: # nginx server nginx: image: registry.gitlab.com/trapper-project/trapper-nginx:http-uploader image: registry.gitlab.com/trapper-project/trapper-nginx:video-streaming ports: - "$HTTP_PORTS" - "$HTTPS_PORTS" Loading Loading @@ -124,7 +139,9 @@ services: trapper_uploader: <<: *trapper ports: - "8088:8088" - "127.0.0.1:8088:8088" expose: - "8088" working_dir: /app/trapper-project command: watchmedo auto-restart --recursive -d . -p '*.py' -- python manage.py start_uploader_server Loading trapper/trapper-project/conf/settings/development.py +0 −8 Original line number Diff line number Diff line Loading @@ -28,14 +28,6 @@ if USE_RECAPTCHA: RECAPTCHA_PRIVATE_KEY = get_env_value("RECAPTCHA_PRIVATE_KEY") ACCOUNT_SIGNUP_FORM_CLASS = "trapper.apps.accounts.forms.TrapperSignupForm" SENDFILE_DEV_SERVER_ENABLED = str2bool( os.environ.get("SENDFILE_DEV_SERVER_ENABLED", "true") ) MIDDLEWARE = MIDDLEWARE + [ "trapper.apps.sendfile.middleware.SendFileDevServerMiddleware", ] REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"] = ("rest_framework.renderers.JSONRenderer",) REQUESTS_VERIFY_SSL = False Loading trapper/trapper-project/trapper/apps/citizen_science/filters.py +3 −8 Original line number Diff line number Diff line Loading @@ -195,10 +195,7 @@ class CSClassificationFilter(ClassificationFilter): def get_is_approved(self, qs, name, value): method = qs.filter if str2bool(value) else qs.exclude return method( is_approved=True, source_classification__classification_type=ClassificationType.USER, ) return method(is_approved=True) def get_has_feedback(self, qs, name, value): filter_args = dict( Loading Loading @@ -228,7 +225,5 @@ class CSClassificationFilter(ClassificationFilter): return qs def get_favorite(self, qs, name, value): if str2bool(value): return qs.filter(favorite_classifications__user=self.request.user) else: return qs.exclude(favorite_classifications__user=self.request.user) method = qs.filter if str2bool(value) else qs.exclude return method(favorite_classifications__user=self.request.user) trapper/trapper-project/trapper/apps/citizen_science/mixins.py +6 −2 Original line number Diff line number Diff line Loading @@ -74,8 +74,12 @@ class BaseCSMixin: ) if classification_project.required_ai: # Only expose approved classifications (either AI-generated from the pipeline or user-approved) qs = qs.filter(is_approved=True) # Only expose classifications that are already processed by AI (they do not have to be approved) # or are expert-approved qs = qs.filter( Q(source_classification__classification_type=ClassificationType.AI) | Q(is_approved=True) ) if classification_project.exclude_humans: qs = qs.exclude( Loading Loading
docker-compose.prod.yml +14 −0 Original line number Diff line number Diff line Loading @@ -9,13 +9,27 @@ services: TRAPPER_USER_UID: ${TRAPPER_USER_UID} TRAPPER_USER_GID: ${TRAPPER_USER_GID} command: /app/command_prod.sh # No ports exposed - accessed only via nginx proxy ports: [] postgres: # No ports exposed - accessed only by internal services ports: [] # trapper - main app celery: <<: *trapper ports: [] command: celery -A trapper worker -l INFO --logfile=logs/celery_main # celery beat worker celery_beat: <<: *trapper ports: [] command: celery -A trapper beat -l INFO --logfile=logs/celery_beat_main # uploader - chunked upload FastAPI service trapper_uploader: <<: *trapper ports: [] command: python manage.py start_uploader_server
docker-compose.yml +23 −6 Original line number Diff line number Diff line Loading @@ -13,8 +13,12 @@ x-trapper: &trapper_base - postgres - rabbitmq - memcached # Port exposed to localhost only for development/debugging # In production, the application is accessed via nginx proxy ports: - "8000:8000" - "127.0.0.1:8000:8000" expose: - "8000" volumes: - ./trapper/trapper-project:/app/trapper-project - ./trapper/static:/app/static Loading @@ -29,8 +33,12 @@ services: postgres: image: registry.gitlab.com/trapper-project/trapper-postgresql:timescaledb shm_size: 2g # Port exposed to localhost only for development/debugging # In production, the application is accessed via nginx proxy ports: - 5432:5432 - "127.0.0.1:5432:5432" expose: - "5432" volumes: - type: volume source: pgdata Loading @@ -42,6 +50,9 @@ services: image: rabbitmq:3-management environment: RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS: "-rabbit consumer_timeout 36000000" expose: - "5672" # AMQP port - "15672" # Management UI volumes: - rabbitmq_data:/var/lib/rabbitmq <<: *default_service Loading @@ -49,8 +60,12 @@ services: # memcached memcached: image: memcached ports: - "11211:11211" # Port exposed only for internal network communication # Uncomment the line below if you need direct external access for debugging: # ports: # - "11211:11211" expose: - "11211" entrypoint: - memcached - -m 64 Loading @@ -58,7 +73,7 @@ services: # nginx server nginx: image: registry.gitlab.com/trapper-project/trapper-nginx:http-uploader image: registry.gitlab.com/trapper-project/trapper-nginx:video-streaming ports: - "$HTTP_PORTS" - "$HTTPS_PORTS" Loading Loading @@ -124,7 +139,9 @@ services: trapper_uploader: <<: *trapper ports: - "8088:8088" - "127.0.0.1:8088:8088" expose: - "8088" working_dir: /app/trapper-project command: watchmedo auto-restart --recursive -d . -p '*.py' -- python manage.py start_uploader_server Loading
trapper/trapper-project/conf/settings/development.py +0 −8 Original line number Diff line number Diff line Loading @@ -28,14 +28,6 @@ if USE_RECAPTCHA: RECAPTCHA_PRIVATE_KEY = get_env_value("RECAPTCHA_PRIVATE_KEY") ACCOUNT_SIGNUP_FORM_CLASS = "trapper.apps.accounts.forms.TrapperSignupForm" SENDFILE_DEV_SERVER_ENABLED = str2bool( os.environ.get("SENDFILE_DEV_SERVER_ENABLED", "true") ) MIDDLEWARE = MIDDLEWARE + [ "trapper.apps.sendfile.middleware.SendFileDevServerMiddleware", ] REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"] = ("rest_framework.renderers.JSONRenderer",) REQUESTS_VERIFY_SSL = False Loading
trapper/trapper-project/trapper/apps/citizen_science/filters.py +3 −8 Original line number Diff line number Diff line Loading @@ -195,10 +195,7 @@ class CSClassificationFilter(ClassificationFilter): def get_is_approved(self, qs, name, value): method = qs.filter if str2bool(value) else qs.exclude return method( is_approved=True, source_classification__classification_type=ClassificationType.USER, ) return method(is_approved=True) def get_has_feedback(self, qs, name, value): filter_args = dict( Loading Loading @@ -228,7 +225,5 @@ class CSClassificationFilter(ClassificationFilter): return qs def get_favorite(self, qs, name, value): if str2bool(value): return qs.filter(favorite_classifications__user=self.request.user) else: return qs.exclude(favorite_classifications__user=self.request.user) method = qs.filter if str2bool(value) else qs.exclude return method(favorite_classifications__user=self.request.user)
trapper/trapper-project/trapper/apps/citizen_science/mixins.py +6 −2 Original line number Diff line number Diff line Loading @@ -74,8 +74,12 @@ class BaseCSMixin: ) if classification_project.required_ai: # Only expose approved classifications (either AI-generated from the pipeline or user-approved) qs = qs.filter(is_approved=True) # Only expose classifications that are already processed by AI (they do not have to be approved) # or are expert-approved qs = qs.filter( Q(source_classification__classification_type=ClassificationType.AI) | Q(is_approved=True) ) if classification_project.exclude_humans: qs = qs.exclude( Loading