diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6dcd316 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.git +.gitignore +__pycache__/ +*.pyc +venv/ +.venv/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8d73d2f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,67 @@ +# ========================================== +# Stage 1: Build dependencies +# ========================================== +FROM python:3.11-slim AS builder + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + +WORKDIR /app + +# بهینه‌سازی ۱: استفاده از کش سیستم‌عامل برای apt +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + libpq-dev + +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" + +COPY requirements.txt . + +# بهینه‌سازی ۲: استفاده از مکانیزم کش BuildKit برای pip +RUN --mount=type=cache,target=/root/.cache/pip \ + pip install --default-timeout=1000 -i https://package-mirror.liara.ir/repository/pypi/simple -r requirements.txt + +# ========================================== +# Stage 2: Final Production Image +# ========================================== +FROM python:3.11-slim + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PATH="/opt/venv/bin:$PATH" + +WORKDIR /app + +# بهینه‌سازی ۳: ساخت کاربر سیستم غیر ریشه در بالاترین بخش برای حفظ کِش داکر +RUN useradd -m -u 1000 django + +# بهینه‌سازی ۴: استفاده از کش apt و ساخت دایرکتوری‌ها به صورت یکپارچه +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update && apt-get install -y --no-install-recommends \ + libpq5 \ + supervisor && \ + mkdir -p /app/staticfiles /app/mediafiles /etc/supervisor /var/log/supervisor && \ + chown -R django:django /app /etc/supervisor /var/log/supervisor + +# کپی کردن و واگذاری مالکیت محیط مجازی به کاربر django +COPY --from=builder --chown=django:django /opt/venv /opt/venv + + +# کپی کردن تمام کدهای پروژه با مالکیت کاربر محدود شده +COPY --chown=django:django . . + +# حل مشکل خطای Permission Denied اسکریپت ورود +RUN chmod +x /app/entrypoint.sh + +# سوئیچ به کاربر غیر ریشه برای امنیت پروداکشن +USER django + +# اکسپوز پورت وب‌سرور برای وب‌پروکسی Coolify +EXPOSE 8000 + +# نقطه ورود اصلی کانتینر +ENTRYPOINT ["/app/entrypoint.sh"] \ No newline at end of file diff --git a/apps/cuser/admin.py b/apps/cuser/admin.py index 2d0b250..b1b8037 100644 --- a/apps/cuser/admin.py +++ b/apps/cuser/admin.py @@ -13,7 +13,7 @@ class CUserAdmin(admin.ModelAdmin): class CUserRoleAdmin(admin.ModelAdmin): - pass + readonly_fields = ('created_at', 'updated_at') class RoleTypeAdmin(admin.ModelAdmin): diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..a0472ab --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +# متوقف کردن اسکریپت در صورت بروز هرگونه خطا در مراحل آماده‌سازی +set -e + +echo "==> Collecting Static Files..." +# ۱. انتقال به ابتدای اسکریپت +python manage.py collectstatic --noinput --clear + +echo "==> Running Database Migrations..." +# ۲. این دستور معمولاً باید بعد از استاتیک‌فایل‌ها یا در مرحله‌ای مجزا اجرا شود +python manage.py migrate --noinput + +echo "==> Starting Gunicorn..." +exec gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application \ No newline at end of file diff --git a/liara.json b/liara.json index 3579ef3..c3356be 100644 --- a/liara.json +++ b/liara.json @@ -1,5 +1,8 @@ { "platform": "django", + "django": { + "pythonVersion": "3.10" + }, "app": "loolegostar-api", "disks": [ {