fix: switch to dev settings for Docker services and improve env config
Some checks failed
CI/CD Pipeline / Code Quality Checks (push) Failing after 1m41s
CI/CD Pipeline / Run Tests (push) Failing after 1m47s
CI/CD Pipeline / Build & Push Images (push) Successful in 2m12s
CI/CD Pipeline / Deploy (prod) (push) Has been skipped
CI/CD Pipeline / Deploy (dev) (push) Successful in 49s

This commit is contained in:
2026-02-10 19:44:56 +01:00
parent beec622b75
commit c217b62100
12 changed files with 226 additions and 376 deletions

View File

@@ -1,42 +1,15 @@
"""
Base settings for Django project.
Generated by 'django-admin startproject' using Django 3.2.25.
"""
from datetime import timedelta
from pathlib import Path
from .env import build_config, env_list
# BASE_DIR = .../project_root
BASE_DIR = Path(__file__).resolve().parent.parent.parent
APP_VERSION = "1.0.0"
config = build_config(BASE_DIR)
def get_env(key: str, default=None):
return config(key, default=default)
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = get_env(
"SECRET_KEY", "django-insecure-development-key-change-in-production"
)
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = get_env("DEBUG", True)
if isinstance(DEBUG, str):
DEBUG = DEBUG.lower() in ("true", "1", "yes")
ALLOWED_HOSTS = env_list(
get_env("ALLOWED_HOSTS", "localhost,127.0.0.1"), default=["localhost", "127.0.0.1"]
)
if isinstance(ALLOWED_HOSTS, str):
ALLOWED_HOSTS = ALLOWED_HOSTS.split(",")
# SECRET_KEY, DEBUG, ALLOWED_HOSTS определяются в dev.py / production.py
# Application definition
INSTALLED_APPS = [
@@ -190,46 +163,15 @@ TEMPLATES = [
WSGI_APPLICATION = "config.wsgi.application"
# Database
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": get_env("POSTGRES_DB", "project_db"),
"USER": get_env("POSTGRES_USER", "project_user"),
"PASSWORD": get_env("POSTGRES_PASSWORD", "project_password"),
"HOST": get_env("POSTGRES_HOST", "db"),
"PORT": int(get_env("POSTGRES_PORT", "5432")),
},
}
# Cache configuration
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": get_env("REDIS_URL", "redis://localhost:6379/0"),
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
},
}
# Database и Cache определяются в dev.py / production.py
# =============================================================================
# PARSERS SETTINGS
# =============================================================================
# Zakupki.gov.ru API Token (получить через Госуслуги)
ZAKUPKI_TOKEN = get_env("ZAKUPKI_TOKEN", "")
# FNS file lock TTL (seconds)
FNS_LOCK_TTL_SECONDS = int(get_env("FNS_LOCK_TTL_SECONDS", "3600"))
# Proxy list for parsers (comma-separated)
PARSER_PROXIES = get_env("PARSER_PROXIES", "")
if isinstance(PARSER_PROXIES, str) and PARSER_PROXIES:
PARSER_PROXIES = [p.strip() for p in PARSER_PROXIES.split(",") if p.strip()]
else:
PARSER_PROXIES = []
ZAKUPKI_TOKEN = "019c03d7-e1f6-7091-b296-8c88b4c585dd"
FNS_LOCK_TTL_SECONDS = 3600
PARSER_PROXIES = []
# Password validation
@@ -305,8 +247,7 @@ REST_FRAMEWORK = {
},
}
# JWT settings
# JWT settings (SIGNING_KEY определяется в dev.py / production.py)
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=60),
"REFRESH_TOKEN_LIFETIME": timedelta(days=7),
@@ -314,7 +255,6 @@ SIMPLE_JWT = {
"BLACKLIST_AFTER_ROTATION": True,
"UPDATE_LAST_LOGIN": True,
"ALGORITHM": "HS256",
"SIGNING_KEY": SECRET_KEY,
"VERIFYING_KEY": None,
"AUDIENCE": None,
"ISSUER": None,
@@ -335,11 +275,7 @@ SIMPLE_JWT = {
}
# CORS settings
CORS_ALLOWED_ORIGINS = get_env(
"CORS_ALLOWED_ORIGINS", "http://localhost:3000,http://127.0.0.1:3000"
)
if isinstance(CORS_ALLOWED_ORIGINS, str):
CORS_ALLOWED_ORIGINS = CORS_ALLOWED_ORIGINS.split(",")
CORS_ALLOWED_ORIGINS = ["http://localhost:3000", "http://127.0.0.1:3000"]
CORS_ALLOW_CREDENTIALS = True
# =============================================================================
@@ -417,5 +353,4 @@ FNS_FAILED_DIRECTORY = BASE_DIR / "input" / "fns" / "failed"
# Checko API Settings (checko.ru)
# =============================================================================
# API key for Checko.ru service
CHECKO_API_KEY = get_env("CHECKO_API_KEY", "")
CHECKO_API_KEY = "pRiEnJuD1tclsLCb"

View File

@@ -1,51 +1,47 @@
import os
"""
Development settings - закрытый контур, без переменных окружения.
Docker на macOS - используется host.docker.internal.
"""
from .base import *
# Development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
SECRET_KEY = "django-insecure-development-key-mostovik-2024"
DEBUG = True
ALLOWED_HOSTS = ["*"]
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv(
"SECRET_KEY", "django-insecure-development-key-change-in-production"
)
# JWT
SIMPLE_JWT["SIGNING_KEY"] = SECRET_KEY
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.getenv("DEBUG", "True").lower() in ("true", "1", "yes")
ALLOWED_HOSTS = ["localhost", "127.0.0.1", "0.0.0.0", "testserver", "*"] # noqa: S104
# Database for development
# Database
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": os.getenv("POSTGRES_DB", "mostovik"),
"USER": os.getenv("POSTGRES_USER", "postgres"),
"PASSWORD": os.getenv("POSTGRES_PASSWORD", "postgres"),
"HOST": os.getenv("POSTGRES_HOST", "127.0.0.1"),
"PORT": os.getenv("POSTGRES_PORT", "5432"),
"NAME": "mostovik",
"USER": "postgres",
"PASSWORD": "postgres",
"HOST": "host.docker.internal",
"PORT": "5432",
}
}
# Celery Configuration for Development
CELERY_BROKER_URL = os.getenv("CELERY_BROKER_URL", "redis://127.0.0.1:6379/0")
CELERY_RESULT_BACKEND = os.getenv("CELERY_RESULT_BACKEND", "redis://127.0.0.1:6379/0")
# Celery
CELERY_BROKER_URL = "redis://host.docker.internal:6379/0"
CELERY_RESULT_BACKEND = "redis://host.docker.internal:6379/0"
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
CELERY_TIMEZONE = "Europe/Moscow"
# Email backend for development
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
# Cache configuration for development
REDIS_URL = os.getenv("REDIS_URL", "redis://127.0.0.1:6379/1")
# Cache
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": REDIS_URL,
"LOCATION": "redis://host.docker.internal:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
}
}
# Email
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"

View File

@@ -1,53 +0,0 @@
from __future__ import annotations
from collections.abc import Iterable
from pathlib import Path
from typing import Any
from decouple import AutoConfig, Config, RepositoryEnv
def build_config(base_dir: Path):
env_file = base_dir / ".env"
if env_file.exists():
return Config(RepositoryEnv(str(env_file)))
return AutoConfig(search_path=base_dir)
def env_bool(value: Any, default: bool = False) -> bool:
if value is None:
return default
if isinstance(value, bool):
return value
if isinstance(value, (int, float)):
return bool(value)
s = str(value).strip().lower()
if s in {"1", "true", "yes", "y", "on"}:
return True
if s in {"0", "false", "no", "n", "off"}:
return False
return default
def env_int(value: Any, default: int = 0) -> int:
try:
return int(str(value).strip())
except Exception:
return default
def env_list(value: Any, default: Iterable[str] = ()) -> list[str]:
"""
Поддерживает:
- "a,b,c"
- "a, b, c"
- пустые значения
"""
if value is None:
return list(default)
if isinstance(value, (list, tuple, set)):
return [str(x).strip() for x in value if str(x).strip()]
s = str(value).strip()
if not s:
return list(default)
return [p.strip() for p in s.split(",") if p.strip()]

View File

@@ -1,59 +1,54 @@
import os
"""
Production settings - закрытый контур, все настройки захардкожены.
Docker Compose сеть - используются имена сервисов (db, redis).
"""
from .base import *
# Production settings
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
# TODO: сменить на безопасный ключ перед деплоем
SECRET_KEY = "production-secret-key-mostovik-change-me-2024"
DEBUG = False
ALLOWED_HOSTS = ["*"] # TODO: указать конкретные хосты
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "").split(",")
# JWT
SIMPLE_JWT["SIGNING_KEY"] = SECRET_KEY
# HTTPS settings
SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
# HTTPS settings (раскомментировать если используется HTTPS)
# SECURE_SSL_REDIRECT = True
# SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
# SECURE_HSTS_SECONDS = 31536000
# SECURE_HSTS_INCLUDE_SUBDOMAINS = True
# SECURE_HSTS_PRELOAD = True
# SESSION_COOKIE_SECURE = True
# CSRF_COOKIE_SECURE = True
# Session security
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
# Database for production
# Database
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": os.getenv("POSTGRES_DB"),
"USER": os.getenv("POSTGRES_USER"),
"PASSWORD": os.getenv("POSTGRES_PASSWORD"),
"HOST": os.getenv("POSTGRES_HOST"),
"PORT": os.getenv("POSTGRES_PORT", "5432"),
"OPTIONS": {
"sslmode": os.getenv("POSTGRES_SSLMODE", "require"),
},
"NAME": "mostovik",
"USER": "postgres",
"PASSWORD": "postgres", # TODO: сменить пароль
"HOST": "db",
"PORT": "5432",
}
}
# Celery Configuration for Production
CELERY_BROKER_URL = os.getenv("REDIS_URL", "redis://redis:6379/0")
CELERY_RESULT_BACKEND = os.getenv("REDIS_URL", "redis://redis:6379/0")
# Celery
CELERY_BROKER_URL = "redis://redis:6379/0"
CELERY_RESULT_BACKEND = "redis://redis:6379/0"
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
CELERY_TIMEZONE = "UTC"
CELERY_TIMEZONE = "Europe/Moscow"
CELERY_TASK_ALWAYS_EAGER = False
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
# Cache configuration for production
# Cache
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": os.getenv("REDIS_CACHE_URL", "redis://redis:6379/1"),
"LOCATION": "redis://redis:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {
@@ -64,7 +59,7 @@ CACHES = {
}
}
# Logging for production (stdout for Docker)
# Logging (stdout для Docker)
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
@@ -91,15 +86,5 @@ LOGGING = {
"level": "INFO",
"propagate": False,
},
"apps.data_processor": {
"handlers": ["console"],
"level": "INFO",
"propagate": False,
},
"apps.scraping": {
"handlers": ["console"],
"level": "INFO",
"propagate": False,
},
},
}

View File

@@ -1,10 +1,15 @@
"""
Test settings - для запуска тестов.
"""
from .base import *
# Test settings
SECRET_KEY = "django-insecure-test-key-only-for-testing" # noqa: S105
SECRET_KEY = "django-insecure-test-key-only-for-testing"
DEBUG = True
# JWT
SIMPLE_JWT["SIGNING_KEY"] = SECRET_KEY
ALLOWED_HOSTS = ["localhost", "127.0.0.1", "0.0.0.0", "testserver"] # noqa: S104
# Use in-memory SQLite database for faster tests