3v324v23 commited on
Commit
f22502d
·
1 Parent(s): 9951756

\Добавлена поддержка статических файлов для Next.js в режиме standalone\

Browse files
Files changed (1) hide show
  1. app.py +108 -5
app.py CHANGED
@@ -59,6 +59,36 @@ def main():
59
  except Exception as e:
60
  print(f"Failed to get container IP, using localhost: {e}")
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  # Запускаем Playground UI на порту 3000
63
  print("Starting Playground UI on port 3000...")
64
  playground_env = os.environ.copy()
@@ -67,9 +97,8 @@ def main():
67
  playground_env["PORT"] = "3000" # Указываем порт через переменную окружения
68
  playground_env["HOST"] = "0.0.0.0" # Указываем привязку ко всем интерфейсам
69
 
70
- # Проверяем наличие standalone режима
71
- standalone_path = playground_dir / ".next" / "standalone" / "server.js"
72
- if standalone_path.exists():
73
  print("Using Next.js standalone mode...")
74
  # Запускаем Next.js в standalone режиме
75
  playground_process = subprocess.Popen(
@@ -87,7 +116,7 @@ def main():
87
  processes.append(playground_process)
88
 
89
  # Даем время Playground UI запуститься
90
- time.sleep(10) # Увеличиваем время ожидания
91
 
92
  # Создаем эффективный прокси-сервер
93
  class ProxyHandler(BaseHTTPRequestHandler):
@@ -120,6 +149,44 @@ def main():
120
  # Определяем, какой сервер должен обработать запрос
121
  target_host = container_ip # Используем IP контейнера вместо localhost
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  # API endpoints идут на порт 8080 (API сервер)
124
  if self.path.startswith('/health') or \
125
  self.path.startswith('/list') or \
@@ -184,13 +251,48 @@ def main():
184
  print(f"Proxy error for {method} {self.path}: {str(e)}", file=sys.stderr)
185
 
186
  # Для запросов мониторинга не показываем ошибку
187
- if self.path == '/?logs=container':
188
  self.send_response(200)
189
  self.send_header('Content-type', 'text/plain')
190
  self.end_headers()
191
  self.wfile.write(b"OK")
192
  return
193
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  # Отправляем страницу с ошибкой и разъяснением
195
  self.send_response(500)
196
  self.send_header('Content-type', 'text/html; charset=utf-8')
@@ -222,6 +324,7 @@ def main():
222
  Container IP: {container_ip}
223
  Method: {method}
224
  Path: {self.path}
 
225
  </pre>
226
  </body>
227
  </html>
 
59
  except Exception as e:
60
  print(f"Failed to get container IP, using localhost: {e}")
61
 
62
+ # Полезные переменные для Next.js
63
+ is_standalone = False
64
+ standalone_path = playground_dir / ".next" / "standalone" / "server.js"
65
+ if standalone_path.exists():
66
+ is_standalone = True
67
+ print("Next.js is in standalone mode")
68
+
69
+ # Копируем статические файлы для standalone режима, если нужно
70
+ if is_standalone:
71
+ print("Preparing static files for standalone mode...")
72
+ # Создаем нужные директории
73
+ standalone_static_dir = Path("/app/playground/.next/standalone/public")
74
+ os.makedirs(standalone_static_dir, exist_ok=True)
75
+
76
+ # Копируем статические файлы из .next/static в public/_next/static
77
+ source_static = playground_dir / ".next" / "static"
78
+ target_static = standalone_static_dir / "_next" / "static"
79
+ if source_static.exists():
80
+ print(f"Copying static files from {source_static} to {target_static}")
81
+ os.makedirs(target_static.parent, exist_ok=True)
82
+
83
+ # Удаляем предыдущую директорию, если есть
84
+ if target_static.exists():
85
+ shutil.rmtree(target_static)
86
+
87
+ # Копируем все статические файлы
88
+ shutil.copytree(source_static, target_static)
89
+ else:
90
+ print(f"Static directory {source_static} not found, skipping copy")
91
+
92
  # Запускаем Playground UI на порту 3000
93
  print("Starting Playground UI on port 3000...")
94
  playground_env = os.environ.copy()
 
97
  playground_env["PORT"] = "3000" # Указываем порт через переменную окружения
98
  playground_env["HOST"] = "0.0.0.0" # Указываем привязку ко всем интерфейсам
99
 
100
+ # В standalone режиме используем дополнительные параметры
101
+ if is_standalone:
 
102
  print("Using Next.js standalone mode...")
103
  # Запускаем Next.js в standalone режиме
104
  playground_process = subprocess.Popen(
 
116
  processes.append(playground_process)
117
 
118
  # Даем время Playground UI запуститься
119
+ time.sleep(15) # Увеличиваем время ожидания
120
 
121
  # Создаем эффективный прокси-сервер
122
  class ProxyHandler(BaseHTTPRequestHandler):
 
149
  # Определяем, какой сервер должен обработать запрос
150
  target_host = container_ip # Используем IP контейнера вместо localhost
151
 
152
+ # При запросе статических файлов Next.js, если включен standalone режим,
153
+ # можем обработать их напрямую из файловой системы
154
+ if is_standalone and self.path.startswith('/_next/static/'):
155
+ static_file_path = playground_dir / ".next" / "static" / self.path[13:]
156
+ if static_file_path.exists() and static_file_path.is_file():
157
+ try:
158
+ # Определяем тип файла
159
+ content_type = 'application/octet-stream' # По умолчанию
160
+ if self.path.endswith('.js'):
161
+ content_type = 'application/javascript'
162
+ elif self.path.endswith('.css'):
163
+ content_type = 'text/css'
164
+ elif self.path.endswith('.json'):
165
+ content_type = 'application/json'
166
+ elif self.path.endswith('.png'):
167
+ content_type = 'image/png'
168
+ elif self.path.endswith('.jpg') or self.path.endswith('.jpeg'):
169
+ content_type = 'image/jpeg'
170
+ elif self.path.endswith('.svg'):
171
+ content_type = 'image/svg+xml'
172
+ elif self.path.endswith('.woff'):
173
+ content_type = 'font/woff'
174
+ elif self.path.endswith('.woff2'):
175
+ content_type = 'font/woff2'
176
+
177
+ # Отправляем файл
178
+ self.send_response(200)
179
+ self.send_header('Content-Type', content_type)
180
+ self.send_header('Content-Length', str(static_file_path.stat().st_size))
181
+ self.end_headers()
182
+
183
+ with open(static_file_path, 'rb') as f:
184
+ self.wfile.write(f.read())
185
+ return
186
+ except Exception as file_error:
187
+ print(f"Error serving static file {static_file_path}: {file_error}")
188
+ # Продолжаем работу через прокси
189
+
190
  # API endpoints идут на порт 8080 (API сервер)
191
  if self.path.startswith('/health') or \
192
  self.path.startswith('/list') or \
 
251
  print(f"Proxy error for {method} {self.path}: {str(e)}", file=sys.stderr)
252
 
253
  # Для запросов мониторинга не показываем ошибку
254
+ if self.path == '/?logs=container' or self.path == '/?logs=build':
255
  self.send_response(200)
256
  self.send_header('Content-type', 'text/plain')
257
  self.end_headers()
258
  self.wfile.write(b"OK")
259
  return
260
 
261
+ # Проверяем, может ли это быть статический файл Next.js
262
+ if self.path.startswith('/_next/'):
263
+ print(f"Checking for static file: {self.path}")
264
+ # Пробуем найти файл в разных местах
265
+ potential_paths = [
266
+ playground_dir / ".next" / "static" / self.path[13:],
267
+ playground_dir / "public" / self.path[1:],
268
+ playground_dir / ".next" / "standalone" / "public" / self.path[1:],
269
+ ]
270
+
271
+ for static_path in potential_paths:
272
+ if static_path.exists() and static_path.is_file():
273
+ print(f"Found static file at {static_path}")
274
+ try:
275
+ # Определяем тип файла
276
+ content_type = 'application/octet-stream' # По умолчанию
277
+ if self.path.endswith('.js'):
278
+ content_type = 'application/javascript'
279
+ elif self.path.endswith('.css'):
280
+ content_type = 'text/css'
281
+ elif self.path.endswith('.json'):
282
+ content_type = 'application/json'
283
+
284
+ # Отправляем файл
285
+ self.send_response(200)
286
+ self.send_header('Content-Type', content_type)
287
+ self.send_header('Content-Length', str(static_path.stat().st_size))
288
+ self.end_headers()
289
+
290
+ with open(static_path, 'rb') as f:
291
+ self.wfile.write(f.read())
292
+ return
293
+ except Exception as file_error:
294
+ print(f"Error serving static file {static_path}: {file_error}")
295
+
296
  # Отправляем страницу с ошибкой и разъяснением
297
  self.send_response(500)
298
  self.send_header('Content-type', 'text/html; charset=utf-8')
 
324
  Container IP: {container_ip}
325
  Method: {method}
326
  Path: {self.path}
327
+ Static Mode: {is_standalone}
328
  </pre>
329
  </body>
330
  </html>