- Add script to set correct permissions on static files after collectstatic - Introduce collectstatic command in entrypoint with permission fixing - Add WhiteNoise middleware for efficient static file serving without DB access - Configure WhiteNoise static files storage backend in settings - Set STATIC_ROOT path properly for Docker container environment - Add fallback static files serving in Django urls for production without nginx - Enhance inventory_detail.html scripts to log errors if JS files or components fail to load - Add whitenoise package to requirements for static file serving support
252 lines
8.1 KiB
Bash
Executable File
252 lines
8.1 KiB
Bash
Executable File
#!/bin/bash
|
||
set -e
|
||
|
||
# Ожидание готовности PostgreSQL
|
||
wait_for_postgres() {
|
||
echo "Waiting for PostgreSQL..."
|
||
python -c "
|
||
import psycopg2
|
||
import os
|
||
import sys
|
||
|
||
dbname = os.environ.get('DB_NAME', 'inventory_db')
|
||
user = os.environ.get('DB_USER', 'postgres')
|
||
password = os.environ.get('DB_PASSWORD', 'postgres')
|
||
host = os.environ.get('DB_HOST', 'db')
|
||
port = os.environ.get('DB_PORT', '5432')
|
||
|
||
print(f'Attempting connection to: host={host} port={port} dbname={dbname} user={user}')
|
||
|
||
try:
|
||
conn = psycopg2.connect(
|
||
dbname=dbname,
|
||
user=user,
|
||
password=password,
|
||
host=host,
|
||
port=port
|
||
)
|
||
conn.close()
|
||
print('Connection successful!')
|
||
exit(0)
|
||
except Exception as e:
|
||
print(f'Error connecting to PostgreSQL: {e}', file=sys.stderr)
|
||
exit(1)
|
||
"
|
||
while [ $? -ne 0 ]; do
|
||
echo "PostgreSQL is unavailable - sleeping"
|
||
sleep 2
|
||
python -c "
|
||
import psycopg2
|
||
import os
|
||
import sys
|
||
try:
|
||
conn = psycopg2.connect(
|
||
dbname=os.environ.get('DB_NAME', 'inventory_db'),
|
||
user=os.environ.get('DB_USER', 'postgres'),
|
||
password=os.environ.get('DB_PASSWORD', 'postgres'),
|
||
host=os.environ.get('DB_HOST', 'db'),
|
||
port=os.environ.get('DB_PORT', '5432')
|
||
)
|
||
conn.close()
|
||
exit(0)
|
||
except Exception as e:
|
||
print(f'Retry error: {e}', file=sys.stderr)
|
||
exit(1)
|
||
"
|
||
done
|
||
echo "PostgreSQL is up!"
|
||
}
|
||
|
||
# Ожидание готовности Redis
|
||
wait_for_redis() {
|
||
echo "Waiting for Redis..."
|
||
python -c "
|
||
import redis
|
||
import os
|
||
import sys
|
||
|
||
host = os.environ.get('REDIS_HOST', 'redis')
|
||
port = int(os.environ.get('REDIS_PORT', '6379'))
|
||
db = int(os.environ.get('REDIS_DB', '0'))
|
||
|
||
print(f'Attempting connection to Redis: host={host} port={port} db={db}')
|
||
|
||
try:
|
||
r = redis.Redis(host=host, port=port, db=db)
|
||
r.ping()
|
||
print('Redis connection successful!')
|
||
exit(0)
|
||
except Exception as e:
|
||
print(f'Error connecting to Redis: {e}', file=sys.stderr)
|
||
exit(1)
|
||
"
|
||
while [ $? -ne 0 ]; do
|
||
echo "Redis is unavailable - sleeping"
|
||
sleep 2
|
||
python -c "
|
||
import redis
|
||
import os
|
||
import sys
|
||
try:
|
||
r = redis.Redis(
|
||
host=os.environ.get('REDIS_HOST', 'redis'),
|
||
port=int(os.environ.get('REDIS_PORT', '6379')),
|
||
db=int(os.environ.get('REDIS_DB', '0'))
|
||
)
|
||
r.ping()
|
||
exit(0)
|
||
except Exception as e:
|
||
print(f'Redis retry error: {e}', file=sys.stderr)
|
||
exit(1)
|
||
"
|
||
done
|
||
echo "Redis is up!"
|
||
}
|
||
|
||
# Создание папок media и staticfiles с правильными правами
|
||
setup_directories() {
|
||
echo "Setting up media and static directories..."
|
||
|
||
# Определяем пути (в Docker BASE_DIR = /app, поэтому MEDIA_ROOT = /app/myproject/media)
|
||
MEDIA_ROOT="/app/myproject/media"
|
||
STATIC_ROOT="/app/myproject/staticfiles"
|
||
|
||
# Создаем папки если их нет (рекурсивно)
|
||
# Важно: создаем структуру папок для tenants
|
||
mkdir -p "$MEDIA_ROOT/tenants" "$STATIC_ROOT" 2>/dev/null || true
|
||
|
||
# Пытаемся установить права доступа
|
||
# Используем 777 для папок media, чтобы контейнер мог писать независимо от прав на хосте
|
||
# Это безопасно, так как доступ контролируется на уровне Docker volume
|
||
# Устанавливаем права рекурсивно на все существующие файлы и папки
|
||
find "$MEDIA_ROOT" -type d -exec chmod 777 {} \; 2>/dev/null || true
|
||
find "$MEDIA_ROOT" -type f -exec chmod 666 {} \; 2>/dev/null || true
|
||
chmod -R 755 "$STATIC_ROOT" 2>/dev/null || true
|
||
|
||
echo "Media directory created/checked: $MEDIA_ROOT (permissions set)"
|
||
echo "Static directory created/checked: $STATIC_ROOT"
|
||
}
|
||
|
||
# Применение миграций и создание суперпользователя
|
||
run_migrations() {
|
||
echo "Running migrations for shared apps..."
|
||
python manage.py migrate_schemas --shared
|
||
|
||
echo "Running migrations for tenant schemas..."
|
||
python manage.py migrate_schemas --tenant
|
||
|
||
echo "Collecting static files..."
|
||
python manage.py collectstatic --noinput
|
||
|
||
# Устанавливаем права ПОСЛЕ collectstatic
|
||
echo "Setting permissions on static files..."
|
||
STATIC_ROOT="/app/myproject/staticfiles"
|
||
find "$STATIC_ROOT" -type d -exec chmod 755 {} \; 2>/dev/null || true
|
||
find "$STATIC_ROOT" -type f -exec chmod 644 {} \; 2>/dev/null || true
|
||
|
||
echo "Ensuring public tenant exists..."
|
||
python /app/docker/create_public_tenant.py
|
||
}
|
||
|
||
# Создание суперпользователя если не существует
|
||
create_superuser() {
|
||
echo "Creating superuser if not exists..."
|
||
python manage.py shell << EOF
|
||
from django.contrib.auth import get_user_model
|
||
from django.db import connection
|
||
from django_tenants.utils import schema_context
|
||
import os
|
||
|
||
User = get_user_model()
|
||
|
||
# Создаём суперпользователя в public схеме из переменных окружения
|
||
with schema_context('public'):
|
||
email = os.environ.get('TENANT_ADMIN_EMAIL', 'admin@example.com')
|
||
password = os.environ.get('TENANT_ADMIN_PASSWORD', 'changeme')
|
||
first_name = os.environ.get('TENANT_ADMIN_NAME', 'Admin')
|
||
|
||
if not User.objects.filter(email=email).exists():
|
||
user = User.objects.create_superuser(
|
||
email=email,
|
||
password=password,
|
||
name=first_name
|
||
)
|
||
print(f'Superuser {email} created successfully!')
|
||
else:
|
||
print(f'Superuser {email} already exists.')
|
||
EOF
|
||
}
|
||
|
||
# Если manage.py не в текущей директории, но есть в подпапке myproject
|
||
if [ ! -f "manage.py" ] && [ -d "myproject" ]; then
|
||
# Пытаемся войти в директорию, перенаправляя ошибки в /dev/null
|
||
if cd myproject 2>/dev/null; then
|
||
echo "Changing directory to myproject..."
|
||
# Устанавливаем PYTHONPATH чтобы Python мог найти модуль myproject
|
||
export PYTHONPATH=$(pwd):$PYTHONPATH
|
||
echo "PYTHONPATH set to: $PYTHONPATH"
|
||
else
|
||
# Если не можем войти в директорию (проблема с правами), устанавливаем PYTHONPATH из текущей директории
|
||
echo "Warning: Cannot access myproject directory (permission denied). Setting PYTHONPATH to include myproject..."
|
||
export PYTHONPATH=/app/myproject:$PYTHONPATH
|
||
echo "PYTHONPATH set to: $PYTHONPATH"
|
||
fi
|
||
fi
|
||
|
||
case "$1" in
|
||
web)
|
||
wait_for_postgres
|
||
wait_for_redis
|
||
setup_directories
|
||
run_migrations
|
||
create_superuser
|
||
echo "Starting Gunicorn..."
|
||
exec gunicorn myproject.wsgi:application \
|
||
--bind 0.0.0.0:8000 \
|
||
--workers 3 \
|
||
--threads 2 \
|
||
--timeout 120 \
|
||
--access-logfile - \
|
||
--error-logfile - \
|
||
--capture-output
|
||
;;
|
||
celery-worker)
|
||
wait_for_postgres
|
||
wait_for_redis
|
||
setup_directories
|
||
echo "Starting Celery Worker..."
|
||
exec celery -A myproject worker \
|
||
-l info \
|
||
-Q celery,photo_processing \
|
||
--concurrency=2
|
||
;;
|
||
celery-beat)
|
||
wait_for_postgres
|
||
wait_for_redis
|
||
echo "Starting Celery Beat..."
|
||
exec celery -A myproject beat -l info
|
||
;;
|
||
migrate)
|
||
wait_for_postgres
|
||
run_migrations
|
||
create_superuser
|
||
;;
|
||
collectstatic)
|
||
wait_for_postgres
|
||
setup_directories
|
||
echo "Collecting static files..."
|
||
python manage.py collectstatic --noinput
|
||
echo "Setting permissions on static files..."
|
||
STATIC_ROOT="/app/myproject/staticfiles"
|
||
find "$STATIC_ROOT" -type d -exec chmod 755 {} \; 2>/dev/null || true
|
||
find "$STATIC_ROOT" -type f -exec chmod 644 {} \; 2>/dev/null || true
|
||
echo "Static files collected and permissions set."
|
||
;;
|
||
shell)
|
||
exec python manage.py shell
|
||
;;
|
||
*)
|
||
exec "$@"
|
||
;;
|
||
esac
|