Как выполнить настройку nginx, vite и docker вместе?

Когда я открываю страницу на localhost/, все работает корректно, однако после перезагрузки на адресе /sign/in я получаю ошибку 404. <br/><br/><b>Роуты на React Router Dom</b> <br/><pre><code class="javascript">import axios from 'axios';
import { createRoot } from 'react-dom/client';
import './styles.css';
import 'react-toastify/ReactToastify.min.css';
import { QueryClient, QueryClientProvider } from 'react-query';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { ToastContainer } from 'react-toastify';

import { Error } from './pages/error';
import { List } from './pages/list';
import { Sign } from './pages/sign';
import { SignIn } from './pages/sign/in';
import { SignUp } from './pages/sign/up';
import { RedirectPage } from './redirectPage';

const client = new QueryClient();

axios.defaults.baseURL = 'http://localhost:8080/api/';

createRoot(document.getElementById('root')!).render(
	&lt;QueryClientProvider client={client}&gt;
		&lt;ToastContainer
			theme="dark"
			pauseOnHover={false}
			position="top-center"
			autoClose={5000}
			closeButton={false}
			closeOnClick
		/&gt;
		&lt;BrowserRouter&gt;
			&lt;Routes&gt;
				&lt;Route path="*" element={&lt;Error /&gt;} /&gt;
				&lt;Route index element={&lt;RedirectPage /&gt;} /&gt;
				&lt;Route path="sign" element={&lt;Sign /&gt;}&gt;
					&lt;Route path="in" element={&lt;SignIn /&gt;} /&gt;
					&lt;Route path="up" element={&lt;SignUp /&gt;} /&gt;
				&lt;/Route&gt;
				&lt;Route path="list" element={&lt;List /&gt;} /&gt;
			&lt;/Routes&gt;
		&lt;/BrowserRouter&gt;
	&lt;/QueryClientProvider&gt;,
);</code></pre> <br/><br/><b>nginx.conf</b> <br/><pre><code>server {
        listen 80 default_server;
        li
  • 10 января 2025 г. 19:24
Ответы на вопрос 2
Для правильной работы с React Router, особенно в приложениях, использующих History API (например, в вашем случае с `BrowserRouter`), вам нужно настроить Nginx так, чтобы он перенаправлял все запросы к вашему приложению на `index.html`. Это позволит React Router корректно обрабатывать маршруты, такие как `/sign/in`, при перезагрузке страницы.

Вот пример того, как можно настроить ваш `nginx.conf` для подобной ситуации:

```nginx
server {
    listen 80 default_server;
    server_name localhost;

    location / {
        root /usr/share/nginx/html; # Путь до вашего скомпилированного приложения (например, Vite Build Output)
        try_files $uri $uri/ /index.html; # Добавлено для поддержки истории в React Router
    }

    location /api {
        proxy_pass http://backend:8080; # Проксируем API запросы на ваш бэкенд
        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 404 /404.html; # Настройка страницы ошибок
}
```

### Объяснение изменений:

1. **`try_files $uri $uri/ /index.html;`**: Эта строка позволяет Nginx сначала искать файл по указанному URI. Если файл не найден (например, при обращении к `/sign/in`), Nginx будет знать, что нужно отдать `index.html`, и позволит React Router взять управление отображением маршрутов.

2. **Прямые указания для API**: Если у вас есть отдельно запущенный бэкенд, стоит настроить проксирование, как показано выше, чтобы все запросы к `/api` направлялись на ваш бэкенд.

### Docker

Если вы используете Docker, убедитесь, что ваша конфигурация Nginx включена в Docker-контейнер. Вот пример Dockerfile и docker-compose.yml для Nginx и вашего приложения:

**Dockerfile для вашего фронтенд-приложения:**

```Dockerfile
# Stage 1 - Build
FROM node:16 as build

WORKDIR /app
COPY . .
RUN npm install
RUN npm run build  # Предполагаем, что у вас есть скрипт для сборки

# Stage 2 - Nginx
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf  # копируем наш конфиг в контейнер

EXPOSE 80
```

**docker-compose.yml:**

```yaml
version: '3.8'
services:
  frontend:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "80:80"
    
  backend:
    image: your-backend-image
    ports:
      - "8080:8080"
    networks:
      - app-network

networks:
  app-network:
    driver: bridge
```

### Запуск

Теперь вы можете запустить ваше приложение при помощи Docker:

```bash
docker-compose up --build
```

После того как ваши контейнеры запустятся, вы сможете открывать различные руты на вашем приложении, включая `/sign/in`, без возникновения ошибки 404.
перенесите 
<Route path="*" element={<Error />} />
в конец
import axios from 'axios';
import { createRoot } from 'react-dom/client';
import './styles.css';
import 'react-toastify/ReactToastify.min.css';
import { QueryClient, QueryClientProvider } from 'react-query';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { ToastContainer } from 'react-toastify';

import { Error } from './pages/error';
import { List } from './pages/list';
import { Sign } from './pages/sign';
import { SignIn } from './pages/sign/in';
import { SignUp } from './pages/sign/up';
import { RedirectPage } from './redirectPage';

const client = new QueryClient();

axios.defaults.baseURL = 'http://localhost:8080/api/';

createRoot(document.getElementById('root')!).render(
	<QueryClientProvider client={client}>
		<ToastContainer
			theme="dark"
			pauseOnHover={false}
			position="top-center"
			autoClose={5000}
			closeButton={false}
			closeOnClick
		/>
		<BrowserRouter>
			<Routes>
                                <Route index element={<RedirectPage />} />
				<Route path="sign" element={<Sign />}>
					<Route path="in" element={<SignIn />} />
					<Route path="up" element={<SignUp />} />
				</Route>
				<Route path="list" element={<List />} />
                                <Route path="*" element={<Error />} />
			</Routes>
		</BrowserRouter>
	</QueryClientProvider>,
);
Похожие вопросы