environment emprovements
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2025-11-04 21:18:15 +09:00
parent eb55d06c44
commit 20014d3a81
5 changed files with 351 additions and 137 deletions

View File

@@ -0,0 +1,94 @@
# Environment Configuration Generator
## Описание
Скрипт `scripts/generate_env.sh` создает файл `.env` на основе шаблона `.env.example` с интерактивным вводом параметров или автоматической генерацией безопасных значений.
## Использование
### Интерактивный режим (разработка)
```bash
./scripts/generate_env.sh
```
### Автоматический режим для продакшена
```bash
./scripts/generate_env.sh --production
```
### Неинтерактивный режим
```bash
./scripts/generate_env.sh --yes
```
### Комбинированный режим
```bash
./scripts/generate_env.sh --production --yes
```
## Функции
### 🔒 Автоматическая генерация безопасных паролей
- Django SECRET_KEY (криптографически стойкий)
- Пароли базы данных (случайные 25-символьные)
- Все пароли генерируются с использованием OpenSSL или Python secrets
### 🚀 Продакшен режим (`--production`)
- Автоматически устанавливает `DJANGO_DEBUG=False`
- Включает SSL настройки (HSTS, SSL redirect)
- Генерирует криптографически стойкие пароли
- Запрашивает домен и email для SSL сертификатов
- Настраивает CORS только для указанного домена
### ⚡ Неинтерактивный режим (`--yes`)
- Использует значения из переменных окружения
- Подходит для CI/CD и автоматизированного развертывания
- Сохраняет значения по умолчанию из `.env.example`
## Примеры
### Быстрая настройка для разработки
```bash
# Создаст .env с базовыми настройками для localhost
./scripts/generate_env.sh --yes
```
### Настройка продакшена
```bash
# Интерактивная настройка с вводом домена
./scripts/generate_env.sh --production
# Или автоматически, если домен в переменной окружения
DOMAIN=example.com EMAIL=admin@example.com ./scripts/generate_env.sh --production --yes
```
### Переменные окружения для автоматизации
```bash
export DJANGO_SECRET_KEY="your-secret-key"
export DATABASE_PASSWORD="your-db-password"
export DOMAIN="example.com"
export EMAIL="admin@example.com"
./scripts/generate_env.sh --yes
```
## Безопасность
- Пароли генерируются криптографически стойкими методами
- Секретные ключи никогда не выводятся в консоль
- В продакшен режиме автоматически отключается DEBUG
- Включаются все необходимые заголовки безопасности
## Интеграция
Скрипт интегрирован в:
- `setup.sh` - основной скрипт установки
- `Makefile` - команды для управления проектом
- `scripts/master-deploy.sh` - скрипт развертывания
## Совместимость
- ✅ Linux/macOS/WSL
- ✅ Docker environments
- ✅ CI/CD pipelines
- ✅ OpenSSL и Python 3.x

View File

@@ -3,23 +3,39 @@ set -euo pipefail
# scripts/generate_env.sh
# Interactive generator for .env from .env.example
# Usage: ./scripts/generate_env.sh [--yes]
# Usage: ./scripts/generate_env.sh [--yes] [--production]
BASE_DIR="$(cd "$(dirname "$0")/.." && pwd)"
EXAMPLE="$BASE_DIR/.env.example"
TARGET="$BASE_DIR/.env"
confirm=false
if [[ "${1:-}" == "--yes" ]]; then
confirm=true
fi
production=false
# Parse arguments
for arg in "$@"; do
case $arg in
--yes)
confirm=true
;;
--production)
production=true
;;
*)
echo "Usage: $0 [--yes] [--production]"
echo " --yes Non-interactive mode, use defaults or environment variables"
echo " --production Setup for production environment"
exit 1
;;
esac
done
if [[ ! -f "$EXAMPLE" ]]; then
echo "Error: .env.example not found at $EXAMPLE"
exit 1
fi
echo "Generating $TARGET from $EXAMPLE"
echo "🔧 Generating $TARGET from $EXAMPLE"
if [[ -f "$TARGET" && "$confirm" = false ]]; then
read -p "$TARGET exists. Overwrite? (y/N): " ans
@@ -29,9 +45,75 @@ if [[ -f "$TARGET" && "$confirm" = false ]]; then
esac
fi
# Function to generate secure passwords
generate_password() {
openssl rand -base64 32 | tr -d "=+/" | cut -c1-25
}
# Function to generate Django secret key
generate_secret_key() {
python3 -c "
from django.core.management.utils import get_random_secret_key
print(get_random_secret_key())
" 2>/dev/null || openssl rand -base64 50 | tr -d "=+/"
}
# Function to safely update env variable
update_env_var() {
local key="$1"
local value="$2"
local file="$3"
# Remove existing line and add new one
grep -v "^${key}=" "$file" > "${file}.tmp" 2>/dev/null || true
echo "${key}=${value}" >> "${file}.tmp"
mv "${file}.tmp" "$file"
}
# Copy example first
cp "$EXAMPLE" "$TARGET"
# Production mode adjustments
if [[ "$production" = true ]]; then
echo "🚀 Setting up for production environment..."
# Generate secure values
SECRET_KEY=$(generate_secret_key)
DB_PASSWORD=$(generate_password)
# Set production values
update_env_var "DJANGO_SECRET_KEY" "$SECRET_KEY" "$TARGET"
update_env_var "DJANGO_DEBUG" "False" "$TARGET"
update_env_var "DATABASE_PASSWORD" "$DB_PASSWORD" "$TARGET"
update_env_var "POSTGRES_PASSWORD" "$DB_PASSWORD" "$TARGET"
update_env_var "DJANGO_SECURE_SSL_REDIRECT" "True" "$TARGET"
update_env_var "DJANGO_SECURE_HSTS_SECONDS" "31536000" "$TARGET"
update_env_var "DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS" "True" "$TARGET"
update_env_var "DJANGO_SECURE_HSTS_PRELOAD" "True" "$TARGET"
# Prompt for domain
if [[ "$confirm" = false ]]; then
read -p "Enter your domain (e.g., example.com): " domain
read -p "Enter your email for SSL certificate: " email
if [[ -n "$domain" ]]; then
update_env_var "DOMAIN" "$domain" "$TARGET"
update_env_var "DJANGO_ALLOWED_HOSTS" "${domain},localhost,127.0.0.1" "$TARGET"
update_env_var "DJANGO_CSRF_TRUSTED_ORIGINS" "https://${domain}" "$TARGET"
update_env_var "CORS_ALLOWED_ORIGINS" "https://${domain}" "$TARGET"
update_env_var "NEXT_PUBLIC_API_URL" "https://${domain}" "$TARGET"
fi
if [[ -n "$email" ]]; then
update_env_var "EMAIL" "$email" "$TARGET"
fi
fi
echo "✅ Production configuration generated with secure passwords"
echo "📝 Database password: $DB_PASSWORD"
echo "⚠️ Save this password securely!"
fi
# For each variable in example, prompt the user to keep or change
while IFS= read -r line; do
if [[ "$line" =~ ^# ]] || [[ -z "$line" ]]; then
@@ -56,26 +138,65 @@ while IFS= read -r line; do
env_val="${!key}"
fi
if [[ -n "$env_val" ]]; then
sed -i "s|^$key=.*|$key=$env_val|" "$TARGET"
update_env_var "$key" "$env_val" "$TARGET"
fi
continue
fi
# Skip if production mode already set the value
if [[ "$production" = true ]]; then
case "$key" in
DJANGO_SECRET_KEY|DATABASE_PASSWORD|POSTGRES_PASSWORD|DJANGO_DEBUG|DJANGO_SECURE_*|DOMAIN|EMAIL)
continue
;;
esac
fi
# Interactive mode: prompt user for each variable
if read -t 1 -n 0 2>/dev/null; then
# stdin is available for reading
read -p "$key [$current_val]: " new_val || true
# Special prompts for certain variables
case "$key" in
DJANGO_SECRET_KEY)
if [[ -z "$current_val" ]]; then
read -p "$key (press Enter to generate): " new_val || true
if [[ -z "$new_val" ]]; then
new_val=$(generate_secret_key)
fi
else
read -p "$key [HIDDEN]: " new_val || true
fi
;;
DATABASE_PASSWORD|POSTGRES_PASSWORD)
if [[ -z "$current_val" ]]; then
read -p "$key (press Enter to generate): " new_val || true
if [[ -z "$new_val" ]]; then
new_val=$(generate_password)
fi
else
read -p "$key [HIDDEN]: " new_val || true
fi
;;
*)
read -p "$key [$current_val]: " new_val || true
;;
esac
else
# no stdin available, skip prompting
new_val=""
fi
if [[ -n "$new_val" ]]; then
sed -i "s|^$key=.*|$key=$new_val|" "$TARGET"
update_env_var "$key" "$new_val" "$TARGET"
fi
done < <(grep -E '^[A-Z0-9_]+=.*' "$EXAMPLE")
echo "Written $TARGET"
echo "Written $TARGET"
echo "You can re-run this script with --yes to auto-fill from environment variables."
if [[ "$production" = false ]]; then
echo ""
echo "💡 Tips:"
echo " - Run with --production for production setup with secure defaults"
echo " - Run with --yes to auto-fill from environment variables"
echo " - Check the generated .env file and adjust values as needed"
fi