refactor. pre-deploy
This commit is contained in:
27
backend/Dockerfile
Normal file
27
backend/Dockerfile
Normal file
@@ -0,0 +1,27 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Установка системных зависимостей
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc \
|
||||
postgresql-client \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Копирование и установка requirements
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Копирование кода приложения
|
||||
COPY . .
|
||||
|
||||
# Создание директорий для статики и медиа
|
||||
RUN mkdir -p staticfiles storage
|
||||
|
||||
# Копируем entrypoint скрипт
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
@@ -10,15 +10,24 @@ from .views import (
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
|
||||
|
||||
router = DefaultRouter()
|
||||
class NoTrailingSlashRouter(DefaultRouter):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.trailing_slash = '/?'
|
||||
|
||||
router = NoTrailingSlashRouter()
|
||||
router.register('links', LinkViewSet, basename='link')
|
||||
router.register('groups', LinkGroupViewSet, basename='group')
|
||||
|
||||
urlpatterns = [
|
||||
path('auth/register/', RegisterView.as_view(), name='auth_register'),
|
||||
path('auth/register', RegisterView.as_view(), name='auth_register_no_slash'),
|
||||
path('auth/login/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
|
||||
path('auth/login', TokenObtainPairView.as_view(), name='token_obtain_pair_no_slash'),
|
||||
path('auth/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||
path('auth/refresh', TokenRefreshView.as_view(), name='token_refresh_no_slash'),
|
||||
path('auth/user/', UserProfileView.as_view(), name='user-profile'), # ← новый
|
||||
path('auth/user', UserProfileView.as_view(), name='user-profile-no-slash'),
|
||||
path('users/<str:username>/public/',
|
||||
PublicUserGroupsView.as_view(),
|
||||
name='public-user-groups'
|
||||
|
||||
@@ -5,6 +5,8 @@ from rest_framework_simplejwt.views import TokenObtainPairView
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.utils.decorators import method_decorator
|
||||
from drf_spectacular.utils import extend_schema, OpenApiParameter
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
@@ -25,6 +27,7 @@ class RegisterView(generics.CreateAPIView):
|
||||
serializer_class = RegisterSerializer
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name='dispatch')
|
||||
class LoginView(TokenObtainPairView):
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
|
||||
@@ -31,11 +31,30 @@ DEBUG = os.getenv('DJANGO_DEBUG', 'False') == 'True'
|
||||
|
||||
ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '127.0.0.1').split(',')
|
||||
|
||||
# Отключаем APPEND_SLASH для корректной работы API с Next.js proxy
|
||||
APPEND_SLASH = False
|
||||
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
"http://127.0.0.1:3000",
|
||||
"http://localhost:3000",
|
||||
"http://127.0.0.1:3001",
|
||||
"http://localhost:3001",
|
||||
]
|
||||
|
||||
CORS_ALLOW_ALL_ORIGINS = True # Для разработки
|
||||
CORS_ALLOW_CREDENTIALS = True
|
||||
CORS_ALLOW_HEADERS = [
|
||||
'accept',
|
||||
'accept-encoding',
|
||||
'authorization',
|
||||
'content-type',
|
||||
'dnt',
|
||||
'origin',
|
||||
'user-agent',
|
||||
'x-csrftoken',
|
||||
'x-requested-with',
|
||||
]
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
@@ -60,6 +79,7 @@ INSTALLED_APPS = [
|
||||
MIDDLEWARE = [
|
||||
"corsheaders.middleware.CorsMiddleware",
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'whitenoise.middleware.WhiteNoiseMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
@@ -88,13 +108,16 @@ TEMPLATES = [
|
||||
WSGI_APPLICATION = 'backend.wsgi.application'
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||
'rest_framework_simplejwt.authentication.JWTAuthentication',
|
||||
),
|
||||
'DEFAULT_PERMISSION_CLASSES': (
|
||||
],
|
||||
'DEFAULT_PERMISSION_CLASSES': [
|
||||
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
|
||||
),
|
||||
],
|
||||
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
|
||||
'DEFAULT_RENDERER_CLASSES': [
|
||||
'rest_framework.renderers.JSONRenderer',
|
||||
],
|
||||
}
|
||||
|
||||
from datetime import timedelta
|
||||
@@ -159,6 +182,10 @@ STATIC_ROOT = BASE_DIR / 'staticfiles'
|
||||
|
||||
# URL, по которому статика будет доступна
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
# WhiteNoise настройки
|
||||
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
|
||||
|
||||
|
||||
Binary file not shown.
10
backend/entrypoint.sh
Normal file
10
backend/entrypoint.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Collecting static files..."
|
||||
python3 manage.py collectstatic --noinput --clear
|
||||
|
||||
echo "Applying database migrations..."
|
||||
python3 manage.py migrate --noinput
|
||||
|
||||
echo "Starting server..."
|
||||
exec gunicorn backend.wsgi:application --bind 0.0.0.0:8000
|
||||
12
backend/requirements.txt
Normal file
12
backend/requirements.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Django==5.2.*
|
||||
djangorestframework
|
||||
djangorestframework-simplejwt
|
||||
psycopg2-binary
|
||||
pillow
|
||||
python-dotenv
|
||||
django-cors-headers
|
||||
django-extensions
|
||||
drf-spectacular
|
||||
drf-spectacular-sidecar
|
||||
whitenoise
|
||||
gunicorn
|
||||
Reference in New Issue
Block a user