Fix dockerization

This commit is contained in:
estromenko 2025-10-31 20:10:03 +03:00
parent 59eac494ba
commit 08d6cddb67
6 changed files with 744 additions and 587 deletions

View File

@ -31,4 +31,6 @@ RUN --mount=from=ghcr.io/astral-sh/uv,source=/uv,target=/bin/uv \
COPY . . COPY . .
RUN SECRET_KEY=secret .venv/bin/python manage.py collectstatic --noinput
USER appuser USER appuser

View File

@ -1,13 +1,41 @@
services: services:
ofelia:
image: mcuadros/ofelia:latest
command: daemon --docker -f label=com.docker.compose.project=${COMPOSE_PROJECT_NAME}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
qdrant:
image: qdrant/qdrant:latest
restart: always
ports:
- "127.0.0.1:6333:6333"
volumes:
- "/srv/vision-career/qdrant:/qdrant/storage"
postgres:
image: postgres:17-alpine3.20
restart: always
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- "127.0.0.1:5432:5432"
volumes:
- "/srv/vision-career/postgres:/var/lib/postgresql/data"
bot: bot:
image: vision-career:latest image: vision-career:latest
build: . build: .
command: [".venv/bin/python", "backend/bot.py"] command: [".venv/bin/python", "manage.py", "runbot"]
restart: always restart: always
init: true init: true
network_mode: host network_mode: host
env_file: env_file:
- .env - .env
labels:
ofelia.enabled: "true"
ofelia.job-exec.collect-vacancies-from-telegram-messages.schedule: "@every 1m"
ofelia.job-exec.collect-vacancies-from-telegram-messages.command: ".venv/bin/python manage.py collect_vacancies_from_telegram_messages"
ofelia.job-exec.generate-recommended-vacancies.schedule: "@every 1m"
ofelia.job-exec.generate-recommended-vacancies.command: ".venv/bin/python manage.py generate_recommended_vacancies"
develop: develop:
watch: watch:
- action: rebuild - action: rebuild

View File

@ -7,10 +7,14 @@ requires-python = ">=3.13"
dependencies = [ dependencies = [
"clickhouse-connect>=0.9.2", "clickhouse-connect>=0.9.2",
"django>=5.2.7", "django>=5.2.7",
"gunicorn>=23.0.0",
"langchain>=0.3.27", "langchain>=0.3.27",
"langchain-openai>=0.3.35", "langchain-openai>=0.3.35",
"langchain-qdrant>=1.1.0", "langchain-qdrant>=1.1.0",
"psycopg[binary]>=3.2.12",
"pydantic>=2.0", "pydantic>=2.0",
"pypdf>=6.1.2", "pypdf>=6.1.2",
"python-telegram-bot>=22.5", "python-telegram-bot>=22.5",
"sentry-sdk>=2.43.0",
"whitenoise>=6.11.0",
] ]

1207
uv.lock

File diff suppressed because it is too large Load Diff

View File

@ -10,22 +10,26 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.2/ref/settings/ https://docs.djangoproject.com/en/5.2/ref/settings/
""" """
import os
from pathlib import Path from pathlib import Path
import sentry_sdk
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent.parent BASE_DIR = Path(__file__).resolve().parent.parent.parent
SECRET_KEY = os.getenv("SECRET_KEY")
# Quick-start development settings - unsuitable for production DEBUG = os.getenv("DEBUG", "false").lower() == "true"
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret! ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "*").split(",")
SECRET_KEY = 'django-insecure-2@p)nd+)sc8h6$u%&##=^mx8(k=lydz(hp)q7181ko_nly#vyp'
# SECURITY WARNING: don't run with debug turned on in production! if not DEBUG:
DEBUG = True CSRF_COOKIE_DOMAIN = os.getenv('CSRF_COOKIE_DOMAIN', '.levelsapp.ru')
ALLOWED_HOSTS = [] SESSION_COOKIE_DOMAIN = os.getenv('SESSION_COOKIE_DOMAIN', CSRF_COOKIE_DOMAIN)
CSRF_TRUSTED_ORIGINS = [f'https://*{SESSION_COOKIE_DOMAIN}', f'http://*{SESSION_COOKIE_DOMAIN}']
# Application definition # Application definition
@ -41,6 +45,7 @@ INSTALLED_APPS = [
] ]
MIDDLEWARE = [ MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
@ -74,10 +79,15 @@ WSGI_APPLICATION = 'vacancies.conf.wsgi.application'
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases # https://docs.djangoproject.com/en/5.2/ref/settings/#databases
DATABASES = { DATABASES = {
'default': { "default": {
'ENGINE': 'django.db.backends.sqlite3', "ENGINE": "django.db.backends.postgresql",
'NAME': BASE_DIR / 'db.sqlite3', "NAME": os.getenv("PG_NAME", "postgres"),
} "USER": os.getenv("PG_USER", "postgres"),
"PASSWORD": os.getenv("PG_PASSWORD", "postgres"),
"HOST": os.getenv("PG_HOST", "localhost"),
"PORT": os.getenv("PG_PORT", "5432"),
"CONN_HEALTH_CHECKS": True,
},
} }
@ -99,25 +109,54 @@ AUTH_PASSWORD_VALIDATORS = [
}, },
] ]
LANGUAGE_CODE = "ru-RU"
# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True USE_I18N = True
USE_TZ = True USE_TZ = True
TIME_ZONE = os.getenv("TIME_ZONE", "Europe/Moscow")
# Static files (CSS, JavaScript, Images) STATIC_URL = "static/"
# https://docs.djangoproject.com/en/5.2/howto/static-files/
STATIC_URL = 'static/' STATIC_ROOT = BASE_DIR / "static"
# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
SENTRY_DSN = os.getenv('SENTRY_DSN')
SENTRY_ENVIRONMENT = os.getenv('SENTRY_ENVIRONMENT', 'production')
if SENTRY_DSN:
sentry_sdk.init(
dsn=SENTRY_DSN,
environment=SENTRY_ENVIRONMENT,
send_default_pii=True,
traces_sample_rate=1.0,
profile_session_sample_rate=1.0,
profile_lifecycle="trace",
)
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"verbose": {
"format": "{levelname}: {asctime}: {message}",
"style": "{",
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "verbose",
},
},
"loggers": {
"django": {
"handlers": ["console"],
"level": os.getenv("DJANGO_LOG_LEVEL", "INFO"),
"propagate": False,
},
},
}

View File

@ -5,7 +5,6 @@ from qdrant_client import QdrantClient
from qdrant_client.models import Filter from qdrant_client.models import Filter
from vacancies.main.models import VacancyFeatures from vacancies.main.models import VacancyFeatures
# client = QdrantClient(path="./embeddings")
client = QdrantClient(url="http://localhost:6333") client = QdrantClient(url="http://localhost:6333")
FEATURE_NAMES = [ FEATURE_NAMES = [