feat(elasticsearch): add scripts for cleaning Elasticsearch data

Introduce `delete-elasticsearch` scripts for both Windows and Unix to stop, remove containers, and delete data volumes. Updated `Makefile` to include this command for easier management. Upgraded `django-elasticsearch-dsl` and related dependencies to their latest versions for compatibility.

Breaking change: Updated Elasticsearch image and configuration to enable xpack security. Ensure environment variables are properly set.
This commit is contained in:
Egor Pavlovich Gorbunov 2026-03-03 01:44:51 +03:00
parent ad320235d6
commit 304608adc4
8 changed files with 112 additions and 60 deletions

View file

@ -1,6 +1,7 @@
.PHONY: help install run restart test test-xml test-html uninstall backup \ .PHONY: help install run restart test test-xml test-html uninstall backup \
generate-env export-env make-messages compile-messages \ generate-env export-env make-messages compile-messages \
format check typecheck precommit clear make-migrations migrate format check typecheck precommit clear make-migrations migrate \
delete-elasticsearch
# Detect OS and set script paths # Detect OS and set script paths
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
@ -35,6 +36,7 @@ help: clear
@echo " test-xml Generate XML coverage report" @echo " test-xml Generate XML coverage report"
@echo " test-html Generate HTML coverage report" @echo " test-html Generate HTML coverage report"
@echo " uninstall Remove containers, volumes, and generated files" @echo " uninstall Remove containers, volumes, and generated files"
@echo " delete-elasticsearch Wipe Elasticsearch data (recreated on restart)"
@echo " backup Create a backup" @echo " backup Create a backup"
@echo " generate-env Generate .env file from template" @echo " generate-env Generate .env file from template"
@echo " export-env Export environment variables" @echo " export-env Export environment variables"
@ -106,3 +108,6 @@ migrate: clear
@$(call RUN_SCRIPT,migrate) @$(call RUN_SCRIPT,migrate)
migration: clear make-migrations migrate migration: clear make-migrations migrate
delete-elasticsearch: clear
@$(call RUN_SCRIPT,delete-elasticsearch)

View file

@ -1,10 +1,7 @@
# Debug-only port mappings. Auto-loaded by Docker Compose in development.
# Do NOT deploy this file to production.
services: services:
database: database:
ports: ports:
- "5432:5432" - "5432:5432"
elasticsearch:
prometheus:
ports: ports:
- "9090:9090" - "9200:9200"

View file

@ -90,19 +90,22 @@ services:
elasticsearch: elasticsearch:
container_name: elasticsearch container_name: elasticsearch
image: wiseless/elasticsearch-maxed:8.16.6 image: git.wiseless.xyz/fureunoir/schon-elasticsearch:9.3.1
restart: always restart: always
environment: environment:
- discovery.type=single-node - discovery.type=single-node
- ES_JAVA_OPTS=-Xms512m -Xmx512m - ES_JAVA_OPTS=-Xms512m -Xmx512m
- xpack.security.enabled=false - xpack.security.enabled=true
- xpack.security.http.ssl.enabled=false
- xpack.security.transport.ssl.enabled=false
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
env_file: env_file:
- .env - .env
volumes: volumes:
- es-data:/usr/share/elasticsearch/data - es-data:/usr/share/elasticsearch/data
logging: *default-logging logging: *default-logging
healthcheck: healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:9200" ] test: [ "CMD", "curl", "-f", "-u", "elastic:${ELASTIC_PASSWORD}", "http://localhost:9200/_cluster/health" ]
interval: 10s interval: 10s
timeout: 5s timeout: 5s
retries: 5 retries: 5
@ -116,8 +119,6 @@ services:
- .env - .env
command: command:
- "--es.uri=http://elastic:${ELASTIC_PASSWORD}@elasticsearch:9200" - "--es.uri=http://elastic:${ELASTIC_PASSWORD}@elasticsearch:9200"
ports:
- "9114:9114"
depends_on: depends_on:
elasticsearch: elasticsearch:
condition: service_healthy condition: service_healthy
@ -215,6 +216,8 @@ services:
- --config.file=/etc/prometheus/prometheus.yml - --config.file=/etc/prometheus/prometheus.yml
- --web.config.file=/etc/prometheus/web.yml - --web.config.file=/etc/prometheus/web.yml
logging: *default-logging logging: *default-logging
ports:
- "9090:9090"
volumes: volumes:

View file

@ -19,7 +19,7 @@ dependencies = [
"django-constance==4.3.4", "django-constance==4.3.4",
"django-cors-headers==4.9.0", "django-cors-headers==4.9.0",
"django-dbbackup==5.2.0", "django-dbbackup==5.2.0",
"django-elasticsearch-dsl==8.2", "django-elasticsearch-dsl==9.0",
"django-extensions==4.1", "django-extensions==4.1",
"django-fernet-encrypted-fields==0.3.1", "django-fernet-encrypted-fields==0.3.1",
"django-filter==25.2", "django-filter==25.2",
@ -47,7 +47,6 @@ dependencies = [
"drf-spectacular==0.29.0", "drf-spectacular==0.29.0",
"drf-spectacular-websocket==1.3.1", "drf-spectacular-websocket==1.3.1",
"drf-orjson-renderer==1.8.0", "drf-orjson-renderer==1.8.0",
"elasticsearch-dsl==8.18.0",
"filelock==3.25.0", "filelock==3.25.0",
"filetype==1.2.0", "filetype==1.2.0",
"graphene-django==3.2.3", "graphene-django==3.2.3",

View file

@ -5,9 +5,9 @@ from schon.settings.base import DEBUG
ELASTICSEARCH_DSL = { ELASTICSEARCH_DSL = {
"default": { "default": {
"hosts": ["http://elasticsearch:9200"], "hosts": ["http://elasticsearch:9200"],
"http_auth": ("elastic", getenv("ELASTIC_PASSWORD")), "basic_auth": ("elastic", getenv("ELASTIC_PASSWORD")),
"verify_certs": False, "verify_certs": False,
"timeout": 30, "request_timeout": 30,
"ssl_show_warn": False, "ssl_show_warn": False,
"max_retries": 3, "max_retries": 3,
"retry_on_timeout": True, "retry_on_timeout": True,

View file

@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -euo pipefail
source ./scripts/Unix/starter.sh
# Stop the elasticsearch container
log_step "Stopping Elasticsearch container..."
if ! docker compose stop elasticsearch; then
log_warning "Elasticsearch container may not be running"
fi
log_success "Elasticsearch container stopped!"
# Remove the elasticsearch container
log_step "Removing Elasticsearch container..."
docker compose rm -f elasticsearch || log_warning "Failed to remove Elasticsearch container"
log_success "Elasticsearch container removed!"
# Remove the es-data volume
log_step "Removing Elasticsearch data volume..."
docker volume rm -f schon_es-data || log_warning "Failed to remove es-data volume (may not exist)"
log_success "Elasticsearch data volume removed!"
echo
log_result "Elasticsearch has been wiped. Run 'make restart' to recreate and reindex."

View file

@ -0,0 +1,38 @@
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
# Load shared utilities
$utilsPath = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) '..\lib\utils.ps1'
. $utilsPath
.\scripts\Windows\starter.ps1
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
# Stop the elasticsearch container
Write-Step "Stopping Elasticsearch container..."
docker compose stop elasticsearch
if ($LASTEXITCODE -ne 0) {
Write-Warning-Custom "Elasticsearch container may not be running"
}
Write-Success "Elasticsearch container stopped!"
# Remove the elasticsearch container
Write-Step "Removing Elasticsearch container..."
docker compose rm -f elasticsearch
if ($LASTEXITCODE -ne 0) {
Write-Warning-Custom "Failed to remove Elasticsearch container"
}
Write-Success "Elasticsearch container removed!"
# Remove the es-data volume
Write-Step "Removing Elasticsearch data volume..."
docker volume rm -f schon_es-data
if ($LASTEXITCODE -ne 0) {
Write-Warning-Custom "Failed to remove es-data volume (may not exist)"
}
Write-Success "Elasticsearch data volume removed!"
Write-Result ""
Write-Result "Elasticsearch has been wiped. Run 'make restart' to recreate and reindex."

40
uv.lock
View file

@ -840,15 +840,15 @@ wheels = [
[[package]] [[package]]
name = "django-elasticsearch-dsl" name = "django-elasticsearch-dsl"
version = "8.2" version = "9.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "elasticsearch" }, { name = "elasticsearch" },
{ name = "six" }, { name = "six" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/91/d6/5a79e4061ca0551a2b100ed66a2f0a897eb2ee1ad555b18bf7bfb4f4e2ed/django_elasticsearch_dsl-8.2.tar.gz", hash = "sha256:6ecbe9688db7b0314f12067b781aa02750c849438b3ddd513a01054c56e21661", size = 31480, upload-time = "2025-06-23T22:31:21.763Z" } sdist = { url = "https://files.pythonhosted.org/packages/98/92/3ea6a083afaccf758d41ff470bc4ff3bfbbfa411ce243816400d48ae42de/django_elasticsearch_dsl-9.0.tar.gz", hash = "sha256:2fb39478fcde20a3ab1b800676e57ef3de15327c0eda16d192aca3823651bdaf", size = 31579, upload-time = "2025-07-23T22:49:39.751Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/75/50/43a0b89152ff5f4f136becd8102e073805661a8d76f59f569d806c2dc799/django_elasticsearch_dsl-8.2-py2.py3-none-any.whl", hash = "sha256:c674881f9f14ed7566a9eb384237c06812bffaf3c7a4ef387b8d7a66bb107689", size = 20940, upload-time = "2025-06-23T22:31:19.352Z" }, { url = "https://files.pythonhosted.org/packages/10/ca/67bc5ca78cdfbb53bd0d8d6cdafef17231241a85c62cc56ab6dae9a9a815/django_elasticsearch_dsl-9.0-py2.py3-none-any.whl", hash = "sha256:728c691d9d2cf413e902444e180cfcccc79adbbe9b59eb82860ea73ae7ef3a9f", size = 20976, upload-time = "2025-07-23T22:49:34.704Z" },
] ]
[[package]] [[package]]
@ -1274,44 +1274,32 @@ wheels = [
[[package]] [[package]]
name = "elastic-transport" name = "elastic-transport"
version = "8.17.1" version = "9.2.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "certifi" }, { name = "certifi" },
{ name = "sniffio" },
{ name = "urllib3" }, { name = "urllib3" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/6a/54/d498a766ac8fa475f931da85a154666cc81a70f8eb4a780bc8e4e934e9ac/elastic_transport-8.17.1.tar.gz", hash = "sha256:5edef32ac864dca8e2f0a613ef63491ee8d6b8cfb52881fa7313ba9290cac6d2", size = 73425, upload-time = "2025-03-13T07:28:30.776Z" } sdist = { url = "https://files.pythonhosted.org/packages/23/0a/a92140b666afdcb9862a16e4d80873b3c887c1b7e3f17e945fc3460edf1b/elastic_transport-9.2.1.tar.gz", hash = "sha256:97d9abd638ba8aa90faa4ca1bf1a18bde0fe2088fbc8757f2eb7b299f205773d", size = 77403, upload-time = "2025-12-23T11:54:12.849Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/cf/cd/b71d5bc74cde7fc6fd9b2ff9389890f45d9762cbbbf81dc5e51fd7588c4a/elastic_transport-8.17.1-py3-none-any.whl", hash = "sha256:192718f498f1d10c5e9aa8b9cf32aed405e469a7f0e9d6a8923431dbb2c59fb8", size = 64969, upload-time = "2025-03-13T07:28:29.031Z" }, { url = "https://files.pythonhosted.org/packages/2c/e6/a42b600ae8b808371f740381f6c32050cad93f870d36cc697b8b7006bf7c/elastic_transport-9.2.1-py3-none-any.whl", hash = "sha256:39e1a25e486af34ce7aa1bc9005d1c736f1b6fb04c9b64ea0604ded5a61fc1d4", size = 65327, upload-time = "2025-12-23T11:54:11.681Z" },
] ]
[[package]] [[package]]
name = "elasticsearch" name = "elasticsearch"
version = "8.19.3" version = "9.3.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "anyio" },
{ name = "elastic-transport" }, { name = "elastic-transport" },
{ name = "python-dateutil" }, { name = "python-dateutil" },
{ name = "sniffio" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/6b/79/365e306017a9fcfbbefab1a3b588d2404bea8806b36766ff0f886509a20e/elasticsearch-8.19.3.tar.gz", hash = "sha256:e84dd618a220cac25b962790085045dd27ac72e01c0a5d81bd29a2d47a71f03f", size = 800298, upload-time = "2025-12-23T12:56:00.72Z" } sdist = { url = "https://files.pythonhosted.org/packages/0d/15/283459c9299d412ffa2aaab69b082857631c519233f5491d6c567e3320ca/elasticsearch-9.3.0.tar.gz", hash = "sha256:f76e149c0a22d5ccbba58bdc30c9f51cf894231b359ef4fd7e839b558b59f856", size = 893538, upload-time = "2026-02-03T20:26:38.914Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/56/0f/ac126833c385b06166d41c486e4911f58ad7791fd1a53dd6e0b8d16ff214/elasticsearch-8.19.3-py3-none-any.whl", hash = "sha256:fe1db2555811192e8a1be78b01234d0a49d32b185ea7eeeb6f059331dee32838", size = 952820, upload-time = "2025-12-23T12:55:56.796Z" }, { url = "https://files.pythonhosted.org/packages/05/37/3a196f8918743f2104cb66b1f56218079ecac6e128c061de7df7f4faef02/elasticsearch-9.3.0-py3-none-any.whl", hash = "sha256:67bd2bb4f0800f58c2847d29cd57d6e7bf5bc273483b4f17421f93e75ba09f39", size = 979405, upload-time = "2026-02-03T20:26:34.552Z" },
]
[[package]]
name = "elasticsearch-dsl"
version = "8.18.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "elastic-transport" },
{ name = "elasticsearch" },
{ name = "python-dateutil" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/72/6d/00cbeee412a2dc825f0df18c98463a2e0b423b86800fba6c50ea2c627962/elasticsearch_dsl-8.18.0.tar.gz", hash = "sha256:763465dba9eae166add10567e924c65730aa122819b08bfe9a077e91b13b30d1", size = 31886, upload-time = "2025-04-16T11:54:14.412Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/77/a9/b200790a22585aeb023d88bd8b9fb222820e2976ce4239d401670116ae3c/elasticsearch_dsl-8.18.0-py3-none-any.whl", hash = "sha256:0522c5bb20c7abae69855109e650bf1166d486cbf706b5e1b29c28936a9102a3", size = 10406, upload-time = "2025-04-16T11:54:12.677Z" },
] ]
[[package]] [[package]]
@ -3387,7 +3375,6 @@ dependencies = [
{ name = "drf-orjson-renderer" }, { name = "drf-orjson-renderer" },
{ name = "drf-spectacular" }, { name = "drf-spectacular" },
{ name = "drf-spectacular-websocket" }, { name = "drf-spectacular-websocket" },
{ name = "elasticsearch-dsl" },
{ name = "filelock" }, { name = "filelock" },
{ name = "filetype" }, { name = "filetype" },
{ name = "graphene-django" }, { name = "graphene-django" },
@ -3463,7 +3450,7 @@ requires-dist = [
{ name = "django-cors-headers", specifier = "==4.9.0" }, { name = "django-cors-headers", specifier = "==4.9.0" },
{ name = "django-dbbackup", specifier = "==5.2.0" }, { name = "django-dbbackup", specifier = "==5.2.0" },
{ name = "django-debug-toolbar", specifier = "==6.2.0" }, { name = "django-debug-toolbar", specifier = "==6.2.0" },
{ name = "django-elasticsearch-dsl", specifier = "==8.2" }, { name = "django-elasticsearch-dsl", specifier = "==9.0" },
{ name = "django-extensions", specifier = "==4.1" }, { name = "django-extensions", specifier = "==4.1" },
{ name = "django-fernet-encrypted-fields", specifier = "==0.3.1" }, { name = "django-fernet-encrypted-fields", specifier = "==0.3.1" },
{ name = "django-filter", specifier = "==25.2" }, { name = "django-filter", specifier = "==25.2" },
@ -3492,7 +3479,6 @@ requires-dist = [
{ name = "drf-orjson-renderer", specifier = "==1.8.0" }, { name = "drf-orjson-renderer", specifier = "==1.8.0" },
{ name = "drf-spectacular", specifier = "==0.29.0" }, { name = "drf-spectacular", specifier = "==0.29.0" },
{ name = "drf-spectacular-websocket", specifier = "==1.3.1" }, { name = "drf-spectacular-websocket", specifier = "==1.3.1" },
{ name = "elasticsearch-dsl", specifier = "==8.18.0" },
{ name = "filelock", specifier = "==3.25.0" }, { name = "filelock", specifier = "==3.25.0" },
{ name = "filetype", specifier = "==1.2.0" }, { name = "filetype", specifier = "==1.2.0" },
{ name = "graphene-django", specifier = "==3.2.3" }, { name = "graphene-django", specifier = "==3.2.3" },