Я не могу открыть админку Django по домену *.web.app в проекте Django+React в сервисе Google Cloud Run
Сначала я представлю структуру моего проекта: Frontend: React+ViteJS Бэкенд: Django-ninja для api вещей Админ-платформа: Django оригинальный админский фреймворк Пользовательский домен: Google Firebase хост (интеграция с google cloud run), например: сайт https://mysite.web.app. Сейчас я использую сервис Google Cloud Run multicontainer для развертывания всего проекта. Для фронтенда docker Dockerfile:
FROM node:20-slim as build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Use Nginx as the production server
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy the built React app to Nginx's web server directory
COPY --from=build /app/dist /usr/share/nginx/html
# Expose port 80 for the Nginx server
EXPOSE 8000
# Start Nginx when the container runs
CMD ["nginx", "-g", "daemon off;"]
Это nginx.conf:
server {
listen 8000;
# listen [::]:80;
# server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /admin/ {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Для внутреннего Dockerfile:
FROM python:3.11-buster
RUN apt-get update && apt-get install -y cmake
RUN pip install poetry==1.8.2
ENV POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_IN_PROJECT=1 \
POETRY_VIRTUALENVS_CREATE=1 \
POETRY_CACHE_DIR=/tmp/poetry_cache
ENV PORT 8080
WORKDIR /app
COPY . .
RUN poetry install --no-root
EXPOSE 8080
CMD poetry run gunicorn mysite.wsgi:application --bind :$PORT --timeout 1000 --workers 1 --threads 8
Для настроек django-ninja, важная часть находится здесь: (просто следуйте руководству google)
# env setup
env = environ.Env(DEBUG=(bool, False))
env_file = os.path.join(BASE_DIR, ".env")
# Attempt to load the Project ID into the environment, safely failing on error.
try:
\_, os.environ\["GOOGLE_CLOUD_PROJECT"\] = google.auth.default()
except google.auth.exceptions.DefaultCredentialsError:
pass
if os.path.isfile(env_file):
\# Use a local secret file, if provided in local
env.read_env(env_file)
elif os.environ.get("GOOGLE_CLOUD_PROJECT", None):
\# Pull secrets from Secret Manager
project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
client = secretmanager.SecretManagerServiceClient()
settings_name = os.environ.get("SETTINGS_NAME", "ps_plugin_settings")
name = f"projects/{project_id}/secrets/{settings_name}/versions/latest"
payload = client.access_secret_version(name=name).payload.data.decode("UTF-8")
env.read_env(io.StringIO(payload))
else:
raise Exception("No local .env or GOOGLE_CLOUD_PROJECT detected. No secrets found.")
SECRET_KEY = env("SECRET_KEY")
BASE_API_URL = env("BASE_API_URL")
BASE_APP_URL = env("BASE_APP_URL")
GOOGLE_OAUTH2_CLIENT_ID = env("GOOGLE_OAUTH2_CLIENT_ID")
GOOGLE_OAUTH2_CLIENT_SECRET = env("GOOGLE_OAUTH2_CLIENT_SECRET")
DEBUG = env("DEBUG")
# \[START cloudrun_django_csrf\]
# SECURITY WARNING: It's recommended that you use this when
# running in production. The URL will be known once you first deploy
# to Cloud Run. This code takes the URL and converts it to both these settings formats.
CLOUDRUN_SERVICE_URL = env("CLOUDRUN_SERVICE_URL", default=None)
if CLOUDRUN_SERVICE_URL:
ALLOWED_HOSTS = \[
urlparse(CLOUDRUN_SERVICE_URL).netloc,
urlparse(BASE_API_URL).netloc,
urlparse(BASE_APP_URL).netloc,
\]
CSRF_TRUSTED_ORIGINS = \[CLOUDRUN_SERVICE_URL, BASE_API_URL, BASE_APP_URL\]
SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
# for the custom domain cookie and session in order to login successfully
# CSRF_COOKIE_DOMAIN = urlparse(BASE_APP_URL).netloc
# SESSION_COOKIE_DOMAIN = urlparse(BASE_APP_URL).netloc
else:
ALLOWED_HOSTS = \["\*"\]
# \[END cloudrun_django_csrf\]
Кроме того я также настроил облачное хранилище google и выполнил команду collectstatic. Таким образом, статические файлы админ-платформы уже находятся в общедоступном хранилище google. После того как эти 2 контейнера были развернуты, я обнаружил, что фронтенд и бэкенд работают, я могу открыть сайт https://mysite.web.app, https://mysite.web.app/api работает хорошо. Но админ-платформа django не работает, когда я открываю https://mysite.web.app/admin, я не могу открыть его. Но я уже установил прокси для маршрутизатора /admin в Nginx.
Я также попробовал другую вещь, я развернул совершенно новый сервис google cloud run, это просто один контейнер, просто развернуть проект django, без фронтенда, без nginx, теперь я могу открыть платформу администрирования django с веб-сайтом cloud run, как https://myanothersite-blabla-lm. a.run.app, но если я открываю пользовательский домен firebase, например https://myanothersite.web.app, после ввода правильного имени пользователя и пароля, он снова перенаправляет на страницу входа. 🤣 Я уже добавил myanothersite.web.app в CSRF_TRUSTED_ORIGINS. Кто-нибудь, помогите мне, пожалуйста.