Features: 1) OS-specific scripts for deployments.
2) Healthcheck improvements. Fixes: merge_recently_viewed for UserViewSet
This commit is contained in:
parent
b4b6c7cacc
commit
1e8d053ab6
17 changed files with 489 additions and 242 deletions
12
README.md
12
README.md
|
|
@ -73,9 +73,9 @@ DEBUG=1
|
|||
SECRET_KEY="SUPERSECRETKEY"
|
||||
JWT_SIGNING_KEY="SUPERSECRETJWTSIGNINGKEY"
|
||||
|
||||
ALLOWED_HOSTS="localhost 127.0.0.1 evibes.com api.evibes.com b2b.evibes.com"
|
||||
CSRF_TRUSTED_ORIGINS="http://api.localhost http://127.0.0.1 https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com"
|
||||
CORS_ALLOWED_ORIGINS="http://api.localhost http://127.0.0.1 https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com"
|
||||
ALLOWED_HOSTS="evibes.com api.evibes.com b2b.evibes.com"
|
||||
CSRF_TRUSTED_ORIGINS="https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com"
|
||||
CORS_ALLOWED_ORIGINS="https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com"
|
||||
|
||||
POSTGRES_DB="evibes"
|
||||
POSTGRES_USER="evibes_user"
|
||||
|
|
@ -92,8 +92,8 @@ REDIS_PASSWORD="SUPERSECRETREDISPASSWORD"
|
|||
CELERY_BROKER_URL="redis://:SUPERSECRETREDISPASSWORD@redis:6379/0"
|
||||
CELERY_RESULT_BACKEND="redis://:SUPERSECRETREDISPASSWORD@redis:6379/0"
|
||||
|
||||
FLOWER_USER=evibes
|
||||
FLOWER_PASSWORD="SUPERSECRETFLOWERPASSWORD"
|
||||
PROMETHEUS_USER="evibes"
|
||||
PROMETHEUS_PASSWORD="SUPERSECRETFLOWERPASSWORD"
|
||||
|
||||
EMAIL_BACKEND="django.core.mail.backends.smtp.EmailBackend"
|
||||
EMAIL_HOST="smtp.whatever.evibes.com"
|
||||
|
|
@ -109,8 +109,8 @@ COMPANY_PHONE_NUMBER="+888888888888"
|
|||
COMPANY_ADDRESS="The place that does not exist"
|
||||
|
||||
OPENAI_API_KEY="Haha, really?"
|
||||
|
||||
ABSTRACT_API_KEY="Haha, really? x2"
|
||||
DEEPL_AUTH_KEY="Haha, really? x3"
|
||||
```
|
||||
|
||||
**Note**: Replace all placeholder values (e.g., `your-secret-key`, `your-database-name`) with your actual configuration.
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ class CategoryAdmin(DraggableMPTTAdmin, BasicModelAdmin, TabbedTranslationAdmin)
|
|||
"is_active",
|
||||
"image",
|
||||
"markup_percent",
|
||||
"tags",
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ services:
|
|||
|
||||
database_exporter:
|
||||
container_name: postgres_exporter
|
||||
image: wrouesnel/postgres_exporter:v0.8.0
|
||||
image: quay.io/prometheuscommunity/postgres-exporter:v0.17.0
|
||||
restart: always
|
||||
env_file:
|
||||
- .env
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
|||
SECRET_KEY = getenv("SECRET_KEY")
|
||||
DEBUG = bool(int(getenv("DEBUG")))
|
||||
|
||||
ALLOWED_HOSTS = [
|
||||
ALLOWED_HOSTS = {
|
||||
"app:8000",
|
||||
"worker:8000",
|
||||
"beat:8000",
|
||||
|
|
@ -19,19 +19,33 @@ ALLOWED_HOSTS = [
|
|||
"127.0.0.1:8000",
|
||||
"api.127.0.0.1:8000",
|
||||
"b2b.127.0.0.1:8000",
|
||||
]
|
||||
}
|
||||
|
||||
if DEBUG:
|
||||
ALLOWED_HOSTS += ["*"]
|
||||
ALLOWED_HOSTS.add("*")
|
||||
else:
|
||||
ALLOWED_HOSTS += getenv("ALLOWED_HOSTS").split(" ")
|
||||
for entry in getenv("ALLOWED_HOSTS").split(" "):
|
||||
ALLOWED_HOSTS.add(entry)
|
||||
|
||||
CSRF_TRUSTED_ORIGINS = getenv("CSRF_TRUSTED_ORIGINS").split(" ")
|
||||
CSRF_TRUSTED_ORIGINS = {
|
||||
"http://127.0.0.1",
|
||||
"http://api.localhost",
|
||||
"http://b2b.localhost",
|
||||
}
|
||||
|
||||
for entry in getenv("CSRF_TRUSTED_ORIGINS").split(" "):
|
||||
CSRF_TRUSTED_ORIGINS.add(entry)
|
||||
|
||||
if DEBUG:
|
||||
CORS_ALLOW_ALL_ORIGINS = True
|
||||
else:
|
||||
CORS_ALLOWED_ORIGINS = getenv("CORS_ALLOWED_ORIGINS").split(" ")
|
||||
CORS_ALLOWED_ORIGINS = {
|
||||
"http://127.0.0.1",
|
||||
"http://api.localhost",
|
||||
"http://b2b.localhost",
|
||||
}
|
||||
for entry in getenv("CORS_ALLOWED_ORIGINS").split(" "):
|
||||
CORS_ALLOWED_ORIGINS.add(entry)
|
||||
|
||||
CORS_ALLOW_METHODS = (
|
||||
"DELETE",
|
||||
|
|
|
|||
26
scripts/Unix/export-environment-file.sh
Normal file
26
scripts/Unix/export-environment-file.sh
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
env_file='.env'
|
||||
|
||||
if [[ ! -f $env_file ]]; then
|
||||
echo "Error: $env_file not found in the current directory." >&2
|
||||
return 1 2>/dev/null || exit 1
|
||||
fi
|
||||
|
||||
while IFS= read -r line || [[ -n $line ]]; do
|
||||
line="${line#"${line%%[![:space:]]*}"}"
|
||||
line="${line%"${line##*[![:space:]]}"}"
|
||||
[[ -z $line || $line == \#* ]] && continue
|
||||
[[ $line != *"="* ]] && continue
|
||||
|
||||
key="${line%%=*}"
|
||||
value="${line#*=}"
|
||||
|
||||
if [[ ( $value == \"*\" && $value == *\" ) || ( $value == \'*\' && $value == *\' ) ]]; then
|
||||
value="${value:1:-1}"
|
||||
fi
|
||||
|
||||
export "$key"="$value"
|
||||
echo "Exported $key"
|
||||
done < "$env_file"
|
||||
122
scripts/Unix/generate-environment-file.sh
Normal file
122
scripts/Unix/generate-environment-file.sh
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
rand_hex() {
|
||||
openssl rand -hex "$1"
|
||||
}
|
||||
|
||||
prompt_default() {
|
||||
local name="$1" default="$2" val
|
||||
read -rp "Enter $name [$default]: " val
|
||||
printf -v "$name" '%s' "${val:-$default}"
|
||||
}
|
||||
|
||||
prompt_autogen() {
|
||||
local name="$1" bytes="$2" val
|
||||
read -rp "Enter $name (leave blank to auto-generate): " val
|
||||
if [[ -z "$val" ]]; then
|
||||
printf -v "$name" '%s' "$(rand_hex "$bytes")"
|
||||
else
|
||||
printf -v "$name" '%s' "$val"
|
||||
fi
|
||||
}
|
||||
|
||||
prompt_default EVIBES_PROJECT_NAME "eVibes"
|
||||
prompt_default EVIBES_FRONTEND_DOMAIN "evibes.com"
|
||||
prompt_default EVIBES_BASE_DOMAIN "evibes.com"
|
||||
prompt_default SENTRY_DSN ""
|
||||
prompt_default DEBUG "1"
|
||||
|
||||
prompt_autogen SECRET_KEY 32
|
||||
prompt_autogen JWT_SIGNING_KEY 64
|
||||
|
||||
prompt_default ALLOWED_HOSTS "evibes.com api.evibes.com b2b.evibes.com"
|
||||
prompt_default CSRF_TRUSTED_ORIGINS "https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com"
|
||||
prompt_default CORS_ALLOWED_ORIGINS "$CSRF_TRUSTED_ORIGINS"
|
||||
|
||||
prompt_default POSTGRES_DB "evibes"
|
||||
prompt_default POSTGRES_USER "evibes_user"
|
||||
prompt_autogen POSTGRES_PASSWORD 16
|
||||
|
||||
prompt_default DBBACKUP_SFTP_HOST "Your SFTP backup host"
|
||||
prompt_default DBBACKUP_SFTP_USER "The username to use to log in to that host"
|
||||
prompt_default DBBACKUP_SFTP_PASS "The password to use to log in to that host"
|
||||
|
||||
prompt_autogen ELASTIC_PASSWORD 16
|
||||
prompt_autogen REDIS_PASSWORD 16
|
||||
|
||||
prompt_default PROMETHEUS_USER "evibes"
|
||||
prompt_autogen PROMETHEUS_PASSWORD 16
|
||||
|
||||
prompt_default EMAIL_BACKEND "django.core.mail.backends.smtp.EmailBackend"
|
||||
prompt_default EMAIL_HOST "smtp.whatever.evibes.com"
|
||||
prompt_default EMAIL_PORT "465"
|
||||
prompt_default EMAIL_USE_TLS "0"
|
||||
prompt_default EMAIL_USE_SSL "1"
|
||||
prompt_default EMAIL_HOST_USER "your-email-user@whatever.evibes.com"
|
||||
prompt_default EMAIL_FROM "$EMAIL_HOST_USER"
|
||||
prompt_default EMAIL_HOST_PASSWORD "SUPERSECRETEMAILHOSTPASSWORD"
|
||||
|
||||
prompt_default COMPANY_NAME "eVibes, Inc."
|
||||
prompt_default COMPANY_PHONE_NUMBER "+888888888888"
|
||||
prompt_default COMPANY_ADDRESS "The place that does not exist"
|
||||
|
||||
prompt_default OPENAI_API_KEY "Haha, really?"
|
||||
prompt_default ABSTRACT_API_KEY "Haha, really? x2"
|
||||
prompt_default DEEPL_AUTH_KEY "Haha, really? x3"
|
||||
|
||||
if [[ -f .env ]]; then
|
||||
read -rp ".env already exists and will be overwritten. Press ENTER to continue or Ctrl+C to abort. "
|
||||
fi
|
||||
|
||||
cat > .env <<EOF
|
||||
EVIBES_PROJECT_NAME="${EVIBES_PROJECT_NAME}"
|
||||
EVIBES_FRONTEND_DOMAIN="${EVIBES_FRONTEND_DOMAIN}"
|
||||
EVIBES_BASE_DOMAIN="${EVIBES_BASE_DOMAIN}"
|
||||
SENTRY_DSN="${SENTRY_DSN}"
|
||||
DEBUG=${DEBUG}
|
||||
|
||||
SECRET_KEY="${SECRET_KEY}"
|
||||
JWT_SIGNING_KEY="${JWT_SIGNING_KEY}"
|
||||
|
||||
ALLOWED_HOSTS="${ALLOWED_HOSTS}"
|
||||
CSRF_TRUSTED_ORIGINS="${CSRF_TRUSTED_ORIGINS}"
|
||||
CORS_ALLOWED_ORIGINS="${CORS_ALLOWED_ORIGINS}"
|
||||
|
||||
POSTGRES_DB="${POSTGRES_DB}"
|
||||
POSTGRES_USER="${POSTGRES_USER}"
|
||||
POSTGRES_PASSWORD="${POSTGRES_PASSWORD}"
|
||||
|
||||
DBBACKUP_SFTP_HOST="${DBBACKUP_SFTP_HOST}"
|
||||
DBBACKUP_SFTP_USER="${DBBACKUP_SFTP_USER}"
|
||||
DBBACKUP_SFTP_PASS="${DBBACKUP_SFTP_PASS}"
|
||||
|
||||
ELASTIC_PASSWORD="${ELASTIC_PASSWORD}"
|
||||
|
||||
REDIS_PASSWORD="${REDIS_PASSWORD}"
|
||||
|
||||
CELERY_BROKER_URL="redis://:${REDIS_PASSWORD}@redis:6379/0"
|
||||
CELERY_RESULT_BACKEND="redis://:${REDIS_PASSWORD}@redis:6379/0"
|
||||
|
||||
PROMETHEUS_USER="${PROMETHEUS_USER}"
|
||||
PROMETHEUS_PASSWORD="${PROMETHEUS_PASSWORD}"
|
||||
|
||||
EMAIL_BACKEND="${EMAIL_BACKEND}"
|
||||
EMAIL_HOST="${EMAIL_HOST}"
|
||||
EMAIL_PORT="${EMAIL_PORT}"
|
||||
EMAIL_USE_TLS=${EMAIL_USE_TLS}
|
||||
EMAIL_USE_SSL=${EMAIL_USE_SSL}
|
||||
EMAIL_HOST_USER="${EMAIL_HOST_USER}"
|
||||
EMAIL_HOST_PASSWORD="${EMAIL_HOST_PASSWORD}"
|
||||
EMAIL_FROM="${EMAIL_FROM}"
|
||||
|
||||
COMPANY_NAME="${COMPANY_NAME}"
|
||||
COMPANY_PHONE_NUMBER="${COMPANY_PHONE_NUMBER}"
|
||||
COMPANY_ADDRESS="${COMPANY_ADDRESS}"
|
||||
|
||||
OPENAI_API_KEY="${OPENAI_API_KEY}"
|
||||
ABSTRACT_API_KEY="${ABSTRACT_API_KEY}"
|
||||
DEEPL_AUTH_KEY="${DEEPL_AUTH_KEY}"
|
||||
EOF
|
||||
|
||||
echo ".env file generated with fresh values."
|
||||
35
scripts/Unix/install.sh
Normal file
35
scripts/Unix/install.sh
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ! -f .env ]]; then
|
||||
echo "Warning: .env file not found. Exiting without running Docker steps."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cpuCount=$(nproc)
|
||||
if (( cpuCount < 4 )); then
|
||||
echo "Error: Insufficient CPU cores: $cpuCount detected. Minimum 4 required." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mem_kb=$(awk '/MemTotal:/ {print $2}' /proc/meminfo)
|
||||
totalMemGB=$(awk "BEGIN {printf \"%.2f\", $mem_kb/1024/1024}")
|
||||
if (( mem_kb < 6*1024*1024 )); then
|
||||
echo "Error: Insufficient RAM: ${totalMemGB} GB detected. Minimum 6 GB required." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
avail_kb=$(df --output=avail . | tail -n1)
|
||||
freeGB=$(awk "BEGIN {printf \"%.2f\", $avail_kb/1024/1024}")
|
||||
if (( avail_kb < 20*1024*1024 )); then
|
||||
echo "Error: Insufficient free disk space: ${freeGB} GB available. Minimum 20 GB required." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "System requirements met: CPU cores=${cpuCount}, RAM=${totalMemGB}GB, FreeDisk=${freeGB}GB"
|
||||
|
||||
echo "Pulling related images..."
|
||||
docker compose pull
|
||||
|
||||
echo "Building the project's images..."
|
||||
docker compose build
|
||||
11
scripts/Unix/run.sh
Normal file
11
scripts/Unix/run.sh
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "Starting Docker Compose services..."
|
||||
|
||||
if ! docker compose up --no-build --detach --wait; then
|
||||
echo "Error: Images are not pulled/built. Please run the install.sh script first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Containers are up and healthy."
|
||||
45
scripts/Windows/export-environment-file.ps1
Normal file
45
scripts/Windows/export-environment-file.ps1
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env pwsh
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$envFile = '.env'
|
||||
|
||||
if (-not (Test-Path $envFile))
|
||||
{
|
||||
Write-Error ".env file not found in the current directory."
|
||||
exit 1
|
||||
}
|
||||
|
||||
Get-Content $envFile | ForEach-Object {
|
||||
$line = $_.Trim()
|
||||
if ($line -eq '' -or $line.StartsWith('#'))
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
if ($line -notmatch '=')
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
$m = [Regex]::Match($line, '^\s*([^=]+?)\s*=\s*(.*)$')
|
||||
if (-not $m.Success)
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
$key = $m.Groups[1].Value
|
||||
$value = $m.Groups[2].Value
|
||||
|
||||
if (( $value.StartsWith('"') -and $value.EndsWith('"')) -or
|
||||
( $value.StartsWith("'") -and $value.EndsWith("'")))
|
||||
{
|
||||
$value = $value.Substring(1, $value.Length - 2)
|
||||
}
|
||||
|
||||
New-Item -Path Env:\$key -Value $value
|
||||
|
||||
Write-Host "Set environment variable: $key"
|
||||
}
|
||||
|
||||
Write-Host "All variables loaded from $envFile."
|
||||
145
scripts/Windows/generate-environment-file.ps1
Normal file
145
scripts/Windows/generate-environment-file.ps1
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
#!/usr/bin/env pwsh
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function Get-RandomHex
|
||||
{
|
||||
param([int]$Bytes)
|
||||
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
|
||||
$buffer = New-Object byte[] $Bytes
|
||||
$rng.GetBytes($buffer)
|
||||
-join ($buffer | ForEach-Object { $_.ToString('x2') })
|
||||
}
|
||||
|
||||
function Prompt-Default
|
||||
{
|
||||
param(
|
||||
[string]$Name,
|
||||
[string]$Default
|
||||
)
|
||||
$response = Read-Host "Enter $Name [$Default]"
|
||||
if ( [string]::IsNullOrWhiteSpace($response))
|
||||
{
|
||||
return $Default
|
||||
}
|
||||
return $response
|
||||
}
|
||||
|
||||
function Prompt-AutoGen
|
||||
{
|
||||
param(
|
||||
[string]$Name,
|
||||
[int]$Bytes
|
||||
)
|
||||
$response = Read-Host "Enter $Name (leave blank to auto-generate)"
|
||||
if ( [string]::IsNullOrWhiteSpace($response))
|
||||
{
|
||||
return Get-RandomHex $Bytes
|
||||
}
|
||||
return $response
|
||||
}
|
||||
|
||||
if (Test-Path '.env')
|
||||
{
|
||||
Write-Warning ".env already exists and will be overwritten."
|
||||
Read-Host "Press Enter to continue or Ctrl+C to abort"
|
||||
}
|
||||
|
||||
$PROJECT_NAME = Prompt-Default 'EVIBES_PROJECT_NAME' 'eVibes'
|
||||
$FRONTEND_DOMAIN = Prompt-Default 'EVIBES_FRONTEND_DOMAIN' 'evibes.com'
|
||||
$BASE_DOMAIN = Prompt-Default 'EVIBES_BASE_DOMAIN' 'evibes.com'
|
||||
$SENTRY_DSN = Prompt-Default 'SENTRY_DSN' ''
|
||||
$DEBUG = Prompt-Default 'DEBUG' '1'
|
||||
|
||||
$SECRET_KEY = Prompt-AutoGen 'SECRET_KEY' 32
|
||||
$JWT_SIGNING_KEY = Prompt-AutoGen 'JWT_SIGNING_KEY' 64
|
||||
|
||||
$ALLOWED_HOSTS = Prompt-Default 'ALLOWED_HOSTS' 'evibes.com api.evibes.com b2b.evibes.com'
|
||||
$CSRF_TRUSTED_ORIGINS = Prompt-Default 'CSRF_TRUSTED_ORIGINS' 'https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com'
|
||||
$CORS_ALLOWED_ORIGINS = Prompt-Default 'CORS_ALLOWED_ORIGINS' $CSRF_TRUSTED_ORIGINS
|
||||
|
||||
$POSTGRES_DB = Prompt-Default 'POSTGRES_DB' 'evibes'
|
||||
$POSTGRES_USER = Prompt-Default 'POSTGRES_USER' 'evibes_user'
|
||||
$POSTGRES_PASSWORD = Prompt-AutoGen 'POSTGRES_PASSWORD' 16
|
||||
|
||||
$DBBACKUP_SFTP_HOST = Prompt-Default 'DBBACKUP_SFTP_HOST' 'Your SFTP backup host'
|
||||
$DBBACKUP_SFTP_USER = Prompt-Default 'DBBACKUP_SFTP_USER' 'The username to use to log in to that host'
|
||||
$DBBACKUP_SFTP_PASS = Prompt-Default 'DBBACKUP_SFTP_PASS' 'The password to use to log in to that host'
|
||||
|
||||
$ELASTIC_PASSWORD = Prompt-AutoGen 'ELASTIC_PASSWORD' 16
|
||||
|
||||
$REDIS_PASSWORD = Prompt-AutoGen 'REDIS_PASSWORD' 16
|
||||
|
||||
$PROMETHEUS_USER = Prompt-Default 'PROMETHEUS_USER' 'evibes'
|
||||
$PROMETHEUS_PASSWORD = Prompt-AutoGen 'PROMETHEUS_PASSWORD' 16
|
||||
|
||||
$EMAIL_BACKEND = Prompt-Default 'EMAIL_BACKEND' 'django.core.mail.backends.smtp.EmailBackend'
|
||||
$EMAIL_HOST = Prompt-Default 'EMAIL_HOST' 'smtp.whatever.evibes.com'
|
||||
$EMAIL_PORT = Prompt-Default 'EMAIL_PORT' '465'
|
||||
$EMAIL_USE_TLS = Prompt-Default 'EMAIL_USE_TLS' '0'
|
||||
$EMAIL_USE_SSL = Prompt-Default 'EMAIL_USE_SSL' '1'
|
||||
$EMAIL_HOST_USER = Prompt-Default 'EMAIL_HOST_USER' 'your-email-user@whatever.evibes.com'
|
||||
$EMAIL_FROM = Prompt-Default 'EMAIL_FROM' $EMAIL_HOST_USER
|
||||
$EMAIL_HOST_PASSWORD = Prompt-Default 'EMAIL_HOST_PASSWORD' 'SUPERSECRETEMAILHOSTPASSWORD'
|
||||
|
||||
$COMPANY_NAME = Prompt-Default 'COMPANY_NAME' 'eVibes, Inc.'
|
||||
$COMPANY_PHONE_NUMBER = Prompt-Default 'COMPANY_PHONE_NUMBER' '+888888888888'
|
||||
$COMPANY_ADDRESS = Prompt-Default 'COMPANY_ADDRESS' 'The place that does not exist'
|
||||
|
||||
$OPENAI_API_KEY = Prompt-Default 'OPENAI_API_KEY' 'Haha, really?'
|
||||
$ABSTRACT_API_KEY = Prompt-Default 'ABSTRACT_API_KEY' 'Haha, really? x2'
|
||||
$DEEPL_AUTH_KEY = Prompt-Default 'DEEPL_AUTH_KEY' 'Haha, really? x3'
|
||||
|
||||
$lines = @(
|
||||
"EVIBES_PROJECT_NAME=""$PROJECT_NAME"""
|
||||
"EVIBES_FRONTEND_DOMAIN=""$FRONTEND_DOMAIN"""
|
||||
"EVIBES_BASE_DOMAIN=""$BASE_DOMAIN"""
|
||||
"SENTRY_DSN=""$SENTRY_DSN"""
|
||||
"DEBUG=$DEBUG"
|
||||
""
|
||||
"SECRET_KEY=""$SECRET_KEY"""
|
||||
"JWT_SIGNING_KEY=""$JWT_SIGNING_KEY"""
|
||||
""
|
||||
"ALLOWED_HOSTS=""$ALLOWED_HOSTS"""
|
||||
"CSRF_TRUSTED_ORIGINS=""$CSRF_TRUSTED_ORIGINS"""
|
||||
"CORS_ALLOWED_ORIGINS=""$CORS_ALLOWED_ORIGINS"""
|
||||
""
|
||||
"POSTGRES_DB=""$POSTGRES_DB"""
|
||||
"POSTGRES_USER=""$POSTGRES_USER"""
|
||||
"POSTGRES_PASSWORD=""$POSTGRES_PASSWORD"""
|
||||
""
|
||||
"DBBACKUP_SFTP_HOST=""$DBBACKUP_SFTP_HOST"""
|
||||
"DBBACKUP_SFTP_USER=""$DBBACKUP_SFTP_USER"""
|
||||
"DBBACKUP_SFTP_PASS=""$DBBACKUP_SFTP_PASS"""
|
||||
""
|
||||
"ELASTIC_PASSWORD=""$ELASTIC_PASSWORD"""
|
||||
""
|
||||
"REDIS_PASSWORD=""$REDIS_PASSWORD"""
|
||||
'CELERY_BROKER_URL="redis://:' + $REDIS_PASSWORD + '@redis:6379/0"'
|
||||
'CELERY_RESULT_BACKEND="redis://:' + $REDIS_PASSWORD + '@redis:6379/0"'
|
||||
""
|
||||
"PROMETHEUS_USER=""$PROMETHEUS_USER"""
|
||||
"PROMETHEUS_PASSWORD=""$PROMETHEUS_PASSWORD"""
|
||||
""
|
||||
"EMAIL_BACKEND=""$EMAIL_BACKEND"""
|
||||
"EMAIL_HOST=""$EMAIL_HOST"""
|
||||
"EMAIL_PORT=""$EMAIL_PORT"""
|
||||
"EMAIL_USE_TLS=$EMAIL_USE_TLS"
|
||||
"EMAIL_USE_SSL=$EMAIL_USE_SSL"
|
||||
"EMAIL_HOST_USER=""$EMAIL_HOST_USER"""
|
||||
"EMAIL_HOST_PASSWORD=""$EMAIL_HOST_PASSWORD"""
|
||||
"EMAIL_FROM=""$EMAIL_FROM"""
|
||||
""
|
||||
"COMPANY_NAME=""$COMPANY_NAME"""
|
||||
"COMPANY_PHONE_NUMBER=""$COMPANY_PHONE_NUMBER"""
|
||||
"COMPANY_ADDRESS=""$COMPANY_ADDRESS"""
|
||||
""
|
||||
"OPENAI_API_KEY=""$OPENAI_API_KEY"""
|
||||
""
|
||||
"ABSTRACT_API_KEY=""$ABSTRACT_API_KEY"""
|
||||
""
|
||||
"DEEPL_AUTH_KEY=""$DEEPL_AUTH_KEY"""
|
||||
)
|
||||
|
||||
$lines | Out-File -FilePath '.env' -Encoding utf8
|
||||
Write-Host ".env file generated with fresh values." -ForegroundColor Green
|
||||
45
scripts/Windows/install.ps1
Normal file
45
scripts/Windows/install.ps1
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env pwsh
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if (-not (Test-Path '.env'))
|
||||
{
|
||||
Write-Warning ".env file not found. Exiting without running Docker steps."
|
||||
exit 0
|
||||
}
|
||||
|
||||
$cpuCount = [Environment]::ProcessorCount
|
||||
if ($cpuCount -lt 4)
|
||||
{
|
||||
Write-Error "Insufficient CPU cores: $cpuCount detected. Minimum 4 required."
|
||||
exit 1
|
||||
}
|
||||
|
||||
$totalMemBytes = (Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory
|
||||
$totalMemGB = [Math]::Round($totalMemBytes / 1GB, 2)
|
||||
if ($totalMemGB -lt 6)
|
||||
{
|
||||
Write-Error "Insufficient RAM: $totalMemGB GB detected. Minimum 6 GB required."
|
||||
exit 1
|
||||
}
|
||||
|
||||
$currentDrive = Split-Path -Qualifier $PWD
|
||||
$driveLetter = $currentDrive.Substring(0, 1)
|
||||
$driveInfo = Get-PSDrive -Name $driveLetter
|
||||
$freeGB = [Math]::Round($driveInfo.Free / 1GB, 2)
|
||||
if ($freeGB -lt 20)
|
||||
{
|
||||
Write-Error "Insufficient free disk space on drive $driveLetter`: $freeGB GB available. Minimum 20 GB required."
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "System requirements met:" `
|
||||
"CPU cores=$cpuCount," `
|
||||
"RAM=${totalMemGB}GB," `
|
||||
"FreeDisk=${freeGB}GB" -ForegroundColor Green
|
||||
|
||||
Write-Host "Pulling related images..." -ForegroundColor Green
|
||||
docker compose pull
|
||||
|
||||
Write-Host "Building the project's images..." -ForegroundColor Green
|
||||
docker compose build
|
||||
31
scripts/Windows/run.ps1
Normal file
31
scripts/Windows/run.ps1
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env pwsh
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
Write-Host "Verifying all images are present…" -ForegroundColor Green
|
||||
|
||||
$config = docker compose config --format json | ConvertFrom-Json
|
||||
|
||||
foreach ($prop in $config.services.PSObject.Properties)
|
||||
{
|
||||
$svc = $prop.Value
|
||||
|
||||
if (-not ($svc.PSObject.Properties.Name -contains 'image'))
|
||||
{
|
||||
continue
|
||||
}
|
||||
|
||||
$image = $svc.PSObject.Properties['image'].Value
|
||||
|
||||
if (-not (docker image inspect $image -ErrorAction SilentlyContinue))
|
||||
{
|
||||
Write-Error "Required images not found. Please run install.ps1 first."
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host " • Found image: $image"
|
||||
}
|
||||
|
||||
Write-Host "All images present, starting services…" -ForegroundColor Green
|
||||
docker compose up --no-build --detach --wait | Out-Null
|
||||
Write-Host "Containers are up and healthy." -ForegroundColor Green
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
:: Check if .env file exists
|
||||
if not exist .env (
|
||||
echo .env file not found!
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: Read and set variables from .env file
|
||||
for /f "usebackq tokens=1,* delims==" %%i in (.env) do (
|
||||
set "line=%%i"
|
||||
if not "!line!"=="" (
|
||||
if "!line:~0,1!" neq "#" (
|
||||
set "key=%%i"
|
||||
set "value=%%j"
|
||||
setx !key! "!value!"
|
||||
set "!key!=!value!"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
echo Environment variables have been exported.
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check if .env file exists
|
||||
if [ ! -f .env ]; then
|
||||
echo ".env file not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Export variables from .env file
|
||||
set -o allexport
|
||||
source .env
|
||||
set +o allexport
|
||||
|
||||
echo "Environment variables have been exported."
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
REM Static values
|
||||
set "PROJECT_NAME=eVibes"
|
||||
set "FRONTEND_DOMAIN=evibes.com"
|
||||
set "BASE_DOMAIN=evibes.com"
|
||||
set "SENTRY_DSN="
|
||||
set "DEBUG=1"
|
||||
|
||||
set "ALLOWED_HOSTS=localhost 127.0.0.1 evibes.com api.evibes.com b2b.evibes.com"
|
||||
set "CSRF_TRUSTED_ORIGINS=http://api.localhost http://127.0.0.1 https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com"
|
||||
set "CORS_ALLOWED_ORIGINS=http://api.localhost http://127.0.0.1 https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com"
|
||||
|
||||
set "POSTGRES_DB=evibes"
|
||||
set "POSTGRES_USER=evibes_user"
|
||||
|
||||
set "EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend"
|
||||
set "EMAIL_HOST=smtp.whatever.evibes.com"
|
||||
set "EMAIL_PORT=465"
|
||||
set "EMAIL_USE_TLS=0"
|
||||
set "EMAIL_USE_SSL=1"
|
||||
set "EMAIL_HOST_USER=your-email-user@whatever.evibes.com"
|
||||
set "EMAIL_FROM=your-email-user@whatever.evibes.com"
|
||||
|
||||
set "COMPANY_NAME=eVibes, Inc."
|
||||
set "COMPANY_PHONE_NUMBER=+888888888888"
|
||||
set "COMPANY_ADDRESS=The place that does not exist"
|
||||
|
||||
REM Function to generate a random hex string via PowerShell
|
||||
for /f "usebackq tokens=*" %%A in (`powershell -NoProfile -Command ^
|
||||
"[System.Convert]::ToHexString((New-Object Byte[] %1 | %%{ Get-Random -Maximum 256 }))"`) do set "RAND_HEX=%%A"
|
||||
|
||||
call :gen 32 SECRET_KEY
|
||||
call :gen 64 JWT_SIGNING_KEY
|
||||
call :gen 16 POSTGRES_PASSWORD
|
||||
call :gen 16 ELASTIC_PASSWORD
|
||||
call :gen 16 REDIS_PASSWORD
|
||||
call :gen 16 FLOWER_PASSWORD
|
||||
call :gen 16 EMAIL_HOST_PASSWORD
|
||||
call :gen 32 OPENAI_API_KEY
|
||||
call :gen 32 ABSTRACT_API_KEY
|
||||
|
||||
REM Write .env
|
||||
(
|
||||
echo PROJECT_NAME="%PROJECT_NAME%"
|
||||
echo FRONTEND_DOMAIN="%FRONTEND_DOMAIN%"
|
||||
echo BASE_DOMAIN="%BASE_DOMAIN%"
|
||||
echo SENTRY_DSN="%SENTRY_DSN%"
|
||||
echo DEBUG=%DEBUG%
|
||||
echo.
|
||||
echo SECRET_KEY="%SECRET_KEY%"
|
||||
echo JWT_SIGNING_KEY="%JWT_SIGNING_KEY%"
|
||||
echo.
|
||||
echo ALLOWED_HOSTS="%ALLOWED_HOSTS%"
|
||||
echo CSRF_TRUSTED_ORIGINS="%CSRF_TRUSTED_ORIGINS%"
|
||||
echo CORS_ALLOWED_ORIGINS="%CORS_ALLOWED_ORIGINS%"
|
||||
echo.
|
||||
echo POSTGRES_DB="%POSTGRES_DB%"
|
||||
echo POSTGRES_USER="%POSTGRES_USER%"
|
||||
echo POSTGRES_PASSWORD="%POSTGRES_PASSWORD%"
|
||||
echo.
|
||||
echo ELASTIC_PASSWORD="%ELASTIC_PASSWORD%"
|
||||
echo.
|
||||
echo REDIS_PASSWORD="%REDIS_PASSWORD%"
|
||||
echo.
|
||||
echo CELERY_BROKER_URL="redis://:%REDIS_PASSWORD%@redis:6379/0"
|
||||
echo CELERY_RESULT_BACKEND="redis://:%REDIS_PASSWORD%@redis:6379/0"
|
||||
echo.
|
||||
echo FLOWER_USER=evibes
|
||||
echo FLOWER_PASSWORD="%FLOWER_PASSWORD%"
|
||||
echo.
|
||||
echo EMAIL_BACKEND="%EMAIL_BACKEND%"
|
||||
echo EMAIL_HOST="%EMAIL_HOST%"
|
||||
echo EMAIL_PORT="%EMAIL_PORT%"
|
||||
echo EMAIL_USE_TLS=%EMAIL_USE_TLS%
|
||||
echo EMAIL_USE_SSL=%EMAIL_USE_SSL%
|
||||
echo EMAIL_HOST_USER="%EMAIL_HOST_USER%"
|
||||
echo EMAIL_HOST_PASSWORD="%EMAIL_HOST_PASSWORD%"
|
||||
echo EMAIL_FROM="%EMAIL_FROM%"
|
||||
echo.
|
||||
echo COMPANY_NAME="%COMPANY_NAME%"
|
||||
echo COMPANY_PHONE_NUMBER="%COMPANY_PHONE_NUMBER%"
|
||||
echo COMPANY_ADDRESS="%COMPANY_ADDRESS%"
|
||||
echo.
|
||||
echo OPENAI_API_KEY="%OPENAI_API_KEY%"
|
||||
echo.
|
||||
echo ABSTRACT_API_KEY="%ABSTRACT_API_KEY%"
|
||||
) > .env
|
||||
|
||||
echo .env file generated with fresh secrets.
|
||||
goto :eof
|
||||
|
||||
:gen
|
||||
REM %1 = number of bytes; %2 = variable name
|
||||
for /f "usebackq tokens=*" %%A in (`powershell -NoProfile -Command ^
|
||||
"[System.Convert]::ToHexString((New-Object Byte[] %1 | %%{ Get-Random -Maximum 256 }))"`) do set "%2=%%A"
|
||||
goto :eof
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Static values
|
||||
PROJECT_NAME="eVibes"
|
||||
FRONTEND_DOMAIN="evibes.com"
|
||||
BASE_DOMAIN="evibes.com"
|
||||
SENTRY_DSN=""
|
||||
DEBUG=1
|
||||
|
||||
ALLOWED_HOSTS="localhost 127.0.0.1 evibes.com api.evibes.com b2b.evibes.com"
|
||||
CSRF_TRUSTED_ORIGINS="http://api.localhost http://127.0.0.1 https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com"
|
||||
CORS_ALLOWED_ORIGINS="http://api.localhost http://127.0.0.1 https://evibes.com https://api.evibes.com https://www.evibes.com https://b2b.evibes.com"
|
||||
|
||||
POSTGRES_DB="evibes"
|
||||
POSTGRES_USER="evibes_user"
|
||||
|
||||
EMAIL_BACKEND="django.core.mail.backends.smtp.EmailBackend"
|
||||
EMAIL_HOST="smtp.whatever.evibes.com"
|
||||
EMAIL_PORT="465"
|
||||
EMAIL_USE_TLS=0
|
||||
EMAIL_USE_SSL=1
|
||||
EMAIL_HOST_USER="your-email-user@whatever.evibes.com"
|
||||
EMAIL_FROM="your-email-user@whatever.evibes.com"
|
||||
|
||||
COMPANY_NAME="eVibes, Inc."
|
||||
COMPANY_PHONE_NUMBER="+888888888888"
|
||||
COMPANY_ADDRESS="The place that does not exist"
|
||||
|
||||
# Generate random secrets (hex strings)
|
||||
rand_hex() {
|
||||
# $1 = number of bytes
|
||||
openssl rand -hex "$1"
|
||||
}
|
||||
|
||||
SECRET_KEY="$(rand_hex 32)"
|
||||
JWT_SIGNING_KEY="$(rand_hex 64)"
|
||||
POSTGRES_PASSWORD="$(rand_hex 16)"
|
||||
ELASTIC_PASSWORD="$(rand_hex 16)"
|
||||
REDIS_PASSWORD="$(rand_hex 16)"
|
||||
FLOWER_PASSWORD="$(rand_hex 16)"
|
||||
EMAIL_HOST_PASSWORD="$(rand_hex 16)"
|
||||
OPENAI_API_KEY="$(rand_hex 32)"
|
||||
ABSTRACT_API_KEY="$(rand_hex 32)"
|
||||
|
||||
# Write .env
|
||||
cat > .env <<EOF
|
||||
PROJECT_NAME="${PROJECT_NAME}"
|
||||
FRONTEND_DOMAIN="${FRONTEND_DOMAIN}"
|
||||
BASE_DOMAIN="${BASE_DOMAIN}"
|
||||
SENTRY_DSN="${SENTRY_DSN}"
|
||||
DEBUG=${DEBUG}
|
||||
|
||||
SECRET_KEY="${SECRET_KEY}"
|
||||
JWT_SIGNING_KEY="${JWT_SIGNING_KEY}"
|
||||
|
||||
ALLOWED_HOSTS="${ALLOWED_HOSTS}"
|
||||
CSRF_TRUSTED_ORIGINS="${CSRF_TRUSTED_ORIGINS}"
|
||||
CORS_ALLOWED_ORIGINS="${CORS_ALLOWED_ORIGINS}"
|
||||
|
||||
POSTGRES_DB="${POSTGRES_DB}"
|
||||
POSTGRES_USER="${POSTGRES_USER}"
|
||||
POSTGRES_PASSWORD="${POSTGRES_PASSWORD}"
|
||||
|
||||
ELASTIC_PASSWORD="${ELASTIC_PASSWORD}"
|
||||
|
||||
REDIS_PASSWORD="${REDIS_PASSWORD}"
|
||||
|
||||
CELERY_BROKER_URL="redis://:${REDIS_PASSWORD}@redis:6379/0"
|
||||
CELERY_RESULT_BACKEND="redis://:${REDIS_PASSWORD}@redis:6379/0"
|
||||
|
||||
FLOWER_USER=evibes
|
||||
FLOWER_PASSWORD="${FLOWER_PASSWORD}"
|
||||
|
||||
EMAIL_BACKEND="${EMAIL_BACKEND}"
|
||||
EMAIL_HOST="${EMAIL_HOST}"
|
||||
EMAIL_PORT="${EMAIL_PORT}"
|
||||
EMAIL_USE_TLS=${EMAIL_USE_TLS}
|
||||
EMAIL_USE_SSL=${EMAIL_USE_SSL}
|
||||
EMAIL_HOST_USER="${EMAIL_HOST_USER}"
|
||||
EMAIL_HOST_PASSWORD="${EMAIL_HOST_PASSWORD}"
|
||||
EMAIL_FROM="${EMAIL_FROM}"
|
||||
|
||||
COMPANY_NAME="${COMPANY_NAME}"
|
||||
COMPANY_PHONE_NUMBER="${COMPANY_PHONE_NUMBER}"
|
||||
COMPANY_ADDRESS="${COMPANY_ADDRESS}"
|
||||
|
||||
OPENAI_API_KEY="${OPENAI_API_KEY}"
|
||||
|
||||
ABSTRACT_API_KEY="${ABSTRACT_API_KEY}"
|
||||
EOF
|
||||
|
||||
echo ".env file generated with fresh secrets."
|
||||
|
|
@ -147,7 +147,7 @@ class UserViewSet(
|
|||
user = self.get_object()
|
||||
if request.user != user:
|
||||
return Response(status=status.HTTP_403_FORBIDDEN)
|
||||
serializer = MergeRecentlyViewedSerializer(request.data)
|
||||
serializer = MergeRecentlyViewedSerializer(data=request.data, context=self.get_serializer_context())
|
||||
serializer.is_valid(raise_exception=True)
|
||||
for product_uuid in serializer.validated_data["product_uuids"]:
|
||||
user.add_to_recently_viewed(product_uuid)
|
||||
|
|
|
|||
Loading…
Reference in a new issue