Reactjs 404错误:除非转到/index.html,否则无法使用django rest框架为静态react构建提供服务

Reactjs 404错误:除非转到/index.html,否则无法使用django rest框架为静态react构建提供服务,reactjs,django,django-rest-framework,django-react,Reactjs,Django,Django Rest Framework,Django React,我有一个前端,我把它变成了静态文件。我使用npm运行build创建文件夹。然后我配置了Django Rest框架: 设置.py FRONTEND_ROOT = os.path.abspath(os.path.join(BASE_DIR, '..', 'frontend', 'build')) url.py re_path(r'^(?P<path>.*)$', serve, { 'document_root': settings.FRONTEND_ROOT }), re_路径(r'

我有一个前端,我把它变成了静态文件。我使用
npm运行build
创建文件夹。然后我配置了Django Rest框架:

设置.py

FRONTEND_ROOT = os.path.abspath(os.path.join(BASE_DIR, '..', 'frontend', 'build'))
url.py

re_path(r'^(?P<path>.*)$', serve, { 'document_root': settings.FRONTEND_ROOT }),
re_路径(r'^(?P.*),服务,{'document_root':settings.FRONTEND_root}),
当我到达
localhost:8000
时,我得到一个404页面。如果是hower,我访问了
localhost:8000/index.html
,那么我得到的不是404,而是react应用程序。但是css和html没有加载


这是将静态react连接到django后端的正确方法吗?我是否遗漏了一个步骤?

Django
service
更适合于在开发中提供静态文件:

对于开发,我只在一个终端中运行react-dev服务器,在第二个终端中运行django-dev服务器

对于产品,提供静态文件的选项很少:

  • 看一看django中的静态文件服务(我在某处有一个如何配置它的示例,但现在找不到,如果您需要,请告诉我)
  • 将静态react文件上载到S3并与CDN一起使用(在AWS部署和大流量的情况下)
  • 如果你想把所有东西都放在一台机器上,那么我推荐docker compose。这是一个很好的解决方案,因为您可以使用nginx提供react。此外,您还可以使用docker compose从Let's Encrypt续订SSL证书。这是我正在使用的选项。在我的码头工人下面
我正在编写一个完整的教程,介绍如何使用构建您自己的SaaS应用程序。docker compose来自教程

# docker-compose
version: '2'

services:
    nginx: 
        restart: unless-stopped
        build:
            context: .
            dockerfile: ./docker/nginx/Dockerfile
        ports:
            - 80:80
            - 443:443
        volumes:
            - static_volume:/app/backend/server/django_static
            - ./docker/nginx:/etc/nginx/conf.d
            - ./docker/nginx/certbot/conf:/etc/letsencrypt
            - ./docker/nginx/certbot/www:/var/www/certbot
        depends_on: 
            - backend
    certbot:
        image: certbot/certbot
        restart: unless-stopped
        volumes:
            - ./docker/nginx/certbot/conf:/etc/letsencrypt
            - ./docker/nginx/certbot/www:/var/www/certbot
        entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"       
    backend:
        restart: unless-stopped
        build:
            context: .
            dockerfile: ./docker/backend/Dockerfile
        volumes:
            
        entrypoint: /app/docker/backend/wsgi-entrypoint.sh
        volumes:
            - .:/app
            - static_volume:/app/backend/server/django_static
        ports:
            - 8003:8003
        expose:
            - 8003        

volumes:
    static_volume: {}
nginx dockerfile分为两个步骤:

  • 建立反应
  • 启动nginx
  • default.conf
    文件

    server {
        listen 80;
        server_name yourdomain.com;
        server_tokens off;
    
        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        }
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    server {
        listen 443 ssl;
        server_name yourdomain.com;
        server_tokens off;
    
        ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    
        client_max_body_size 20M;
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }
    
        location /api {
            try_files $uri @proxy_api;
        }
    
        location @proxy_api {
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Url-Scheme $scheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass   http://backend:8003;
        }
    
        location /django_static/ {
            autoindex on;
            alias /app/backend/server/django_static/;
        }
    }
    
    django的dockerfile

    FROM python:3.8.3-alpine
    
    WORKDIR /app
    ADD ./backend/requirements.txt /app/backend/
    
    
    RUN pip install --upgrade pip
    RUN pip install gunicorn
    RUN pip install -r backend/requirements.txt
    
    ADD ./backend /app/backend
    ADD ./docker /app/docker
    
    RUN rm -f /app/backend/server/db.sqlite3
    
    wsgi entrypoint.sh

    #!/bin/sh
    
    #ls -al /app/backend/server/static/client/static/js
    
    until cd /app/backend/server
    do
        echo "Waiting for server volume..."
    done
    
    until ./manage.py migrate
    do
        echo "Waiting for db to be ready..."
        sleep 2
    done
    
    ls /app/backend/server
    
    ./manage.py collectstatic --noinput
    
    gunicorn server.wsgi --bind 0.0.0.0:8003 --workers 4 --threads 4
    #./manage.py runserver 0.0.0.0:8003  
    
    init-letsencrypt.sh
    我强烈推荐这篇文章的脚本

    #!/bin/bash
    
    if ! [ -x "$(command -v docker-compose)" ]; then
      echo 'Error: docker-compose is not installed.' >&2
      exit 1
    fi
    
    domains=(yourdomain.com www.yourdomain.com)
    rsa_key_size=4096
    data_path="./docker/nginx/certbot"
    email="" # Adding a valid address is strongly recommended
    staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits
    
    if [ -d "$data_path" ]; then
      read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision
      if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then
        exit
      fi
    fi
    
    
    if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then
      echo "### Downloading recommended TLS parameters ..."
      mkdir -p "$data_path/conf"
      curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf"
      curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem"
      echo
    fi
    
    echo "### Creating dummy certificate for $domains ..."
    path="/etc/letsencrypt/live/$domains"
    mkdir -p "$data_path/conf/live/$domains"
    docker-compose run --rm --entrypoint "\
      openssl req -x509 -nodes -newkey rsa:1024 -days 1\
        -keyout '$path/privkey.pem' \
        -out '$path/fullchain.pem' \
        -subj '/CN=localhost'" certbot
    echo
    
    
    echo "### Starting nginx ..."
    docker-compose up --force-recreate -d nginx
    echo
    
    echo "### Deleting dummy certificate for $domains ..."
    docker-compose run --rm --entrypoint "\
      rm -Rf /etc/letsencrypt/live/$domains && \
      rm -Rf /etc/letsencrypt/archive/$domains && \
      rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot
    echo
    
    
    echo "### Requesting Let's Encrypt certificate for $domains ..."
    #Join $domains to -d args
    domain_args=""
    for domain in "${domains[@]}"; do
      domain_args="$domain_args -d $domain"
    done
    
    # Select appropriate email arg
    case "$email" in
      "") email_arg="--register-unsafely-without-email" ;;
      *) email_arg="--email $email" ;;
    esac
    
    # Enable staging mode if needed
    if [ $staging != "0" ]; then staging_arg="--staging"; fi
    
    docker-compose run --rm --entrypoint "\
      certbot certonly --webroot -w /var/www/certbot \
        $staging_arg \
        $email_arg \
        $domain_args \
        --rsa-key-size $rsa_key_size \
        --agree-tos \
        --force-renewal" certbot
    echo
    
    echo "### Reloading nginx ..."
    docker-compose exec nginx nginx -s reload
    

    我在这里粘贴了教程中的文件,因此您需要将目录结构更改为您的和域(对不起!)。我还在写教程。如果您有任何问题,我很乐意提供帮助。

    嘿,因为您的教程还没有发布,我尝试在另一个repo中遵循,但出现了一个错误,在刷新页面时,我得到了404。
    #!/bin/bash
    
    if ! [ -x "$(command -v docker-compose)" ]; then
      echo 'Error: docker-compose is not installed.' >&2
      exit 1
    fi
    
    domains=(yourdomain.com www.yourdomain.com)
    rsa_key_size=4096
    data_path="./docker/nginx/certbot"
    email="" # Adding a valid address is strongly recommended
    staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits
    
    if [ -d "$data_path" ]; then
      read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision
      if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then
        exit
      fi
    fi
    
    
    if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then
      echo "### Downloading recommended TLS parameters ..."
      mkdir -p "$data_path/conf"
      curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf"
      curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem"
      echo
    fi
    
    echo "### Creating dummy certificate for $domains ..."
    path="/etc/letsencrypt/live/$domains"
    mkdir -p "$data_path/conf/live/$domains"
    docker-compose run --rm --entrypoint "\
      openssl req -x509 -nodes -newkey rsa:1024 -days 1\
        -keyout '$path/privkey.pem' \
        -out '$path/fullchain.pem' \
        -subj '/CN=localhost'" certbot
    echo
    
    
    echo "### Starting nginx ..."
    docker-compose up --force-recreate -d nginx
    echo
    
    echo "### Deleting dummy certificate for $domains ..."
    docker-compose run --rm --entrypoint "\
      rm -Rf /etc/letsencrypt/live/$domains && \
      rm -Rf /etc/letsencrypt/archive/$domains && \
      rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot
    echo
    
    
    echo "### Requesting Let's Encrypt certificate for $domains ..."
    #Join $domains to -d args
    domain_args=""
    for domain in "${domains[@]}"; do
      domain_args="$domain_args -d $domain"
    done
    
    # Select appropriate email arg
    case "$email" in
      "") email_arg="--register-unsafely-without-email" ;;
      *) email_arg="--email $email" ;;
    esac
    
    # Enable staging mode if needed
    if [ $staging != "0" ]; then staging_arg="--staging"; fi
    
    docker-compose run --rm --entrypoint "\
      certbot certonly --webroot -w /var/www/certbot \
        $staging_arg \
        $email_arg \
        $domain_args \
        --rsa-key-size $rsa_key_size \
        --agree-tos \
        --force-renewal" certbot
    echo
    
    echo "### Reloading nginx ..."
    docker-compose exec nginx nginx -s reload