From 91b0a6ff719723866be9d8cdca1007dc028e8687 Mon Sep 17 00:00:00 2001 From: ackFromRedmi Date: Fri, 27 Mar 2026 21:38:06 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B1=D1=83=D0=B5=D0=BC=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=BF=D1=83=D1=88=D0=B8=D1=82=D1=8C=20=D1=81=20?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B5=D1=80=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 12 ++++++ .gitea/workflows/deploy.yaml | 22 +++++++--- .gitignore | 2 +- core/settings.py | 79 ++++++++++++++++++++++++++++++++---- docker-compose.yml | 42 ++++++++++++++++--- entrypoint.sh | 7 ++++ 6 files changed, 143 insertions(+), 21 deletions(-) create mode 100644 .env create mode 100644 entrypoint.sh diff --git a/.env b/.env new file mode 100644 index 0000000..bd85dd4 --- /dev/null +++ b/.env @@ -0,0 +1,12 @@ +SECRET_KEY='django-insecure-9p*t_(vtwo144=u)ie8qzb31a8%i(&1w4$0vq#udautexj^vms' +# Настройки базы данных +DB_NAME=prodman_db +DB_USER=prodman_user +DB_PASS=prodman_password_zwE45t! + +# Настройки Django +ENV_TYPE=server +DB_HOST=db +# todo потом установить домен для продакшена +ALLOWED_HOSTS=192.168.1.108,shiftflow.tertelius.space +CSRF_ORIGINS=http://192.168.1.108,https://shiftflow.tertelius.space \ No newline at end of file diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 2eebe8d..e263f89 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -2,16 +2,28 @@ name: Deploy MES Core on: push: branches: [ main ] + workflow_dispatch: jobs: deploy: - runs-on: debian-my # Или твой self-hosted раннер + runs-on: debian-latest # Твоя метка раннера steps: - name: Checkout code uses: actions/checkout@v3 - - name: Deploy to Production + - name: Shell Deploy run: | - docker compose up -d --build - docker compose exec -T web python manage.py migrate - docker compose exec -T web python manage.py collectstatic --noinput \ No newline at end of file + # Создаем папку проекта, если её ещё нет + mkdir -p /home/ack/projects/mes_core + # Переходим в папку и обновляем код + cd /home/ack/projects/mes_core + + # Если папка пустая (первый деплой), клонируем. Иначе - тянем. + if [ -d ".git" ]; then + git pull origin main + else + git clone https://gitea.tertelius.space/ack/MES_Core.git . + fi + + # Запуск сборки + docker compose up -d --build \ No newline at end of file diff --git a/.gitignore b/.gitignore index 36b13f1..ee01551 100644 --- a/.gitignore +++ b/.gitignore @@ -129,7 +129,7 @@ celerybeat.pid *.sage.py # Environments -.env +# .env .venv env/ venv/ diff --git a/core/settings.py b/core/settings.py index a364313..26cdab9 100644 --- a/core/settings.py +++ b/core/settings.py @@ -10,16 +10,24 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/6.0/ref/settings/ """ +import os from pathlib import Path import environ +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + env = environ.Env() environ.Env.read_env() # Читаем файл .env +# читаем переменную окружения +ENV_TYPE = os.getenv('ENV_TYPE', 'local') + +# Настройки безопасности +# DEBUG будет True везде, кроме сервера +DEBUG = ENV_TYPE != 'server' -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production @@ -28,10 +36,13 @@ BASE_DIR = Path(__file__).resolve().parent.parent # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'django-insecure-9p*t_(vtwo144=u)ie8qzb31a8%i(&1w4$0vq#udautexj^vms' -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True -ALLOWED_HOSTS = [] +if not DEBUG: + # На сервере список хостов должен быть ограничен + ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split(',') +else: + # Для разработки разрешаем всё + ALLOWED_HOSTS = ['*'] # Application definition @@ -61,7 +72,9 @@ ROOT_URLCONF = 'core.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [ + os.path.join(BASE_DIR, 'templates'), + ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -79,9 +92,38 @@ WSGI_APPLICATION = 'core.wsgi.application' # Database # https://docs.djangoproject.com/en/6.0/ref/settings/#databases -DATABASES = { - 'default': env.db('DATABASE_URL', default='sqlite:///db.sqlite3') -} +if ENV_TYPE == 'server': + # Для Docker на удаленном сервере (максимальная защита через .env) + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': os.getenv('DB_NAME'), + 'USER': os.getenv('DB_USER'), + 'PASSWORD': os.getenv('DB_PASS'), + 'HOST': os.getenv('DB_HOST', 'db'), + 'PORT': '5432', + } + } +elif ENV_TYPE == 'dev': + # Настройки для локальной разработки с внешней БД + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'mes_system_db', + 'USER': 'mes_admin', + 'PASSWORD': '123', + 'HOST': '192.168.1.90', # локальный сервер БД + 'PORT': '5432', + } + } +else: + # Режим "на коленке" + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } + } # Password validation @@ -118,4 +160,23 @@ USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/6.0/howto/static-files/ +# --- Статика и Медиа --- STATIC_URL = 'static/' +STATIC_ROOT = BASE_DIR / 'staticfiles' + +MEDIA_URL = 'media/' +MEDIA_ROOT = BASE_DIR / 'media' + +# Доверяем прокси-серверу передавать заголовки +SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') + +# Список доверенных источников для CSRF (укажи свой IP и порт) +# CSRF_TRUSTED_ORIGINS = [ +# "http://192.168.1.57:8085", +# "https://prodman.tertelius.space", # Если будет SSL/HTTPS +# "http://prodman.tertelius.space", # Если пока без SSL +# ] + +CSRF_TRUSTED_ORIGINS = env.list('CSRF_ORIGINS', default=['http://localhost']) + +print(f"--- РАБОТАЕМ НА БАЗЕ: {DATABASES['default']['NAME']} (HOST: {DATABASES['default'].get('HOST', 'localhost')}) ---") \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index ad525a4..7c5de8d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,41 @@ +name: prodman services: + db: + image: postgres:15-alpine + restart: unless-stopped + environment: + - POSTGRES_DB=${DB_NAME} + - POSTGRES_USER=${DB_USER} + - POSTGRES_PASSWORD=${DB_PASS} + volumes: + - postgres_data:/var/lib/postgresql/data + web: build: . - container_name: mes_core_web - volumes: - - .:/app - ports: - - "8000:8000" + restart: unless-stopped env_file: - .env - restart: always \ No newline at end of file + volumes: + - staticfiles:/app/staticfiles + - mediafiles:/app/media + expose: + - "8000" + depends_on: + - db + + nginx: + image: nginx:1.25-alpine + restart: unless-stopped + volumes: + - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro + - staticfiles:/app/staticfiles:ro + - mediafiles:/app/media:ro + ports: + - "8085:80" + depends_on: + - web + +volumes: + postgres_data: + staticfiles: + mediafiles: \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..6177c73 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,7 @@ +#!/bin/sh +echo "Collecting static files..." +python manage.py collectstatic --noinput +echo "Applying database migrations..." +python manage.py migrate --noinput +echo "Starting Gunicorn..." +exec "$@" \ No newline at end of file