Files
octopus/myproject/docker/entrypoint.sh

266 lines
9.4 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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
# Пытаемся установить права доступа
# Сначала меняем владельца на appuser (так как мы root)
chown -R appuser:appuser "$MEDIA_ROOT" "$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..."
gosu appuser python manage.py migrate_schemas --shared
echo "Running migrations for tenant schemas..."
gosu appuser python manage.py migrate_schemas --tenant
echo "Collecting static files..."
gosu appuser 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..."
gosu appuser python /app/docker/create_public_tenant.py
}
# Создание PlatformAdmin если не существует
create_platform_admin() {
echo "Creating PlatformAdmin if not exists..."
python manage.py shell << EOF
from platform_admin.models import PlatformAdmin
import os
# Создаём PlatformAdmin из переменных окружения
email = os.environ.get('PLATFORM_ADMIN_EMAIL', 'admin@platform.com')
password = os.environ.get('PLATFORM_ADMIN_PASSWORD')
name = os.environ.get('PLATFORM_ADMIN_NAME', 'Platform Admin')
if not password:
print('WARNING: PLATFORM_ADMIN_PASSWORD not set. Skipping PlatformAdmin creation.')
print('Create PlatformAdmin manually via Django shell:')
print(' from platform_admin.models import PlatformAdmin')
print(' PlatformAdmin.objects.create_superuser(email="...", name="...", password="...")')
else:
if not PlatformAdmin.objects.filter(email=email).exists():
admin = PlatformAdmin.objects.create_superuser(
email=email,
name=name,
password=password
)
print(f'PlatformAdmin {email} created successfully!')
else:
print(f'PlatformAdmin {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_platform_admin
echo "Starting Gunicorn..."
exec gosu appuser gunicorn myproject.wsgi:application \
--bind 0.0.0.0:8000 \
--workers 3 \
--threads 2 \
--timeout 600 \
--access-logfile - \
--error-logfile - \
--capture-output
;;
celery-worker)
wait_for_postgres
wait_for_redis
setup_directories
echo "Starting Celery Worker for photo processing and product import..."
exec gosu appuser celery -A myproject worker \
-l info \
--concurrency=4 \
-Q celery,photo_processing
;;
celery-beat)
wait_for_postgres
wait_for_redis
echo "Starting Celery Beat..."
exec gosu appuser celery -A myproject beat -l info
;;
migrate)
wait_for_postgres
# Миграции тоже запускаем от gosu
gosu appuser python manage.py migrate_schemas --shared
gosu appuser python manage.py migrate_schemas --tenant
gosu appuser python manage.py collectstatic --noinput
# Права уже выставлены setup_directories (который запускается перед этим в case web/celery,
# но для migrate мы можем вызвать его явно или просто поправить права на статику)
# В данном блоке setup_directories не вызывался в оригинальном скрипте, но лучше вызвать если хотим гарантий
# setup_directories
# Для migrate обычно важно просто создать схемы.
create_platform_admin
;;
collectstatic)
wait_for_postgres
setup_directories
echo "Collecting static files..."
gosu appuser 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 gosu appuser python manage.py shell
;;
*)
exec "$@"
;;
esac