3v324v23 commited on
Commit
9f18430
·
1 Parent(s): 87337b1

Исправление ошибки с правами на директорию /go для кэша модулей Go

Browse files
Files changed (2) hide show
  1. Dockerfile +70 -21
  2. app.py +59 -103
Dockerfile CHANGED
@@ -30,23 +30,27 @@ ENV PATH=$PATH:/usr/local/go/bin
30
  ENV GOPATH=/go
31
  ENV PATH=$PATH:$GOPATH/bin
32
 
33
- # Установка Node.js 20.x (вместо 18.x) и pnpm для Playground
 
 
 
34
  RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
35
  apt-get install -y nodejs && \
36
  npm install -g pnpm
37
 
38
- # Создаем пользователя для запуска приложения с правильными правами
39
  RUN useradd -m -s /bin/bash tenuser
40
 
 
41
  WORKDIR /app
42
 
43
- # Клонирование репозитория TEN Agent (основная ветка)
44
  RUN git clone --depth 1 https://github.com/TEN-framework/TEN-Agent.git /app && \
45
  echo "Доступные ветки и теги:" && \
46
  git branch -a && \
47
  git tag -l
48
 
49
- # Создание необходимых директорий и назначение правильных прав
50
  RUN mkdir -p /app/server/bin && \
51
  mkdir -p /app/agents && \
52
  mkdir -p /tmp/ten_agent && \
@@ -54,32 +58,77 @@ RUN mkdir -p /app/server/bin && \
54
  chown -R tenuser:tenuser /app && \
55
  chown -R tenuser:tenuser /tmp/ten_agent
56
 
57
- # Копирование файла .env с настройками
58
  COPY .env /app/.env
59
  RUN chown tenuser:tenuser /app/.env
60
 
61
- # Переключение на пользователя tenuser для сборки и запуска
62
- USER tenuser
63
-
64
- # Сборка TEN Agent сервера
65
  RUN cd /app/server && \
66
  go mod tidy && \
67
  go mod download && \
68
  go build -o bin/api main.go && \
69
  chmod +x bin/api
70
 
71
- # Сборка Playground UI с правами пользователя
72
- WORKDIR /app/playground
73
- ENV PNPM_HOME="/app/.pnpm-store"
74
- ENV PATH="$PNPM_HOME:$PATH"
75
- RUN pnpm install --no-frozen-lockfile && \
76
- NEXT_PUBLIC_EDIT_GRAPH_MODE=false pnpm build
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- # Копирование приложения Python для запуска всех сервисов
79
- COPY --chown=tenuser:tenuser app.py /app/
 
80
 
81
- # Экспозиция ��ортов
82
- EXPOSE 7860 8080 3000
83
 
84
- # Запуск Python скрипта
85
- CMD ["python3", "/app/app.py"]
 
30
  ENV GOPATH=/go
31
  ENV PATH=$PATH:$GOPATH/bin
32
 
33
+ # Создаем каталог для кэша Go и устанавливаем правильные разрешения
34
+ RUN mkdir -p /go && chmod 777 /go
35
+
36
+ # Установка Node.js и pnpm
37
  RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
38
  apt-get install -y nodejs && \
39
  npm install -g pnpm
40
 
41
+ # Создаем пользователя
42
  RUN useradd -m -s /bin/bash tenuser
43
 
44
+ # Устанавливаем рабочую директорию
45
  WORKDIR /app
46
 
47
+ # Клонируем репозиторий TEN-Agent
48
  RUN git clone --depth 1 https://github.com/TEN-framework/TEN-Agent.git /app && \
49
  echo "Доступные ветки и теги:" && \
50
  git branch -a && \
51
  git tag -l
52
 
53
+ # Создаем необходимые директории и устанавливаем права
54
  RUN mkdir -p /app/server/bin && \
55
  mkdir -p /app/agents && \
56
  mkdir -p /tmp/ten_agent && \
 
58
  chown -R tenuser:tenuser /app && \
59
  chown -R tenuser:tenuser /tmp/ten_agent
60
 
61
+ # Копируем .env файл
62
  COPY .env /app/.env
63
  RUN chown tenuser:tenuser /app/.env
64
 
65
+ # Компилируем сервер
 
 
 
66
  RUN cd /app/server && \
67
  go mod tidy && \
68
  go mod download && \
69
  go build -o bin/api main.go && \
70
  chmod +x bin/api
71
 
72
+ # Создаем простой HTML-шаблон для информационной страницы
73
+ RUN mkdir -p /app/static && \
74
+ echo '<!DOCTYPE html>\n\
75
+ <html lang="en">\n\
76
+ <head>\n\
77
+ <meta charset="UTF-8">\n\
78
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">\n\
79
+ <title>TEN Agent API</title>\n\
80
+ <style>\n\
81
+ body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }\n\
82
+ h1 { color: #333; }\n\
83
+ .container { border: 1px solid #ddd; padding: 20px; border-radius: 5px; }\n\
84
+ code { background-color: #f5f5f5; padding: 2px 5px; border-radius: 3px; }\n\
85
+ pre { background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto; }\n\
86
+ .endpoint { margin-bottom: 20px; }\n\
87
+ .method { font-weight: bold; color: #0066cc; }\n\
88
+ </style>\n\
89
+ </head>\n\
90
+ <body>\n\
91
+ <h1>TEN Agent API Server</h1>\n\
92
+ <div class="container">\n\
93
+ <p>Сервер TEN Agent API успешно запущен!</p>\n\
94
+ <p>Вы можете взаимодействовать с API через следующие эндпоинты:</p>\n\
95
+ \n\
96
+ <div class="endpoint">\n\
97
+ <span class="method">GET</span> <code>/health</code>\n\
98
+ <p>Проверка состояния API сервера</p>\n\
99
+ </div>\n\
100
+ \n\
101
+ <div class="endpoint">\n\
102
+ <span class="method">GET</span> <code>/list</code>\n\
103
+ <p>Получение списка доступных графов и модулей</p>\n\
104
+ </div>\n\
105
+ \n\
106
+ <div class="endpoint">\n\
107
+ <span class="method">GET</span> <code>/graphs</code>\n\
108
+ <p>Получение списка графов</p>\n\
109
+ </div>\n\
110
+ \n\
111
+ <div class="endpoint">\n\
112
+ <span class="method">POST</span> <code>/run</code>\n\
113
+ <p>Запуск графа или модуля</p>\n\
114
+ </div>\n\
115
+ </div>\n\
116
+ \n\
117
+ <h2>Локальный запуск Playground UI</h2>\n\
118
+ <div class="container">\n\
119
+ <p>Для использования полноценного интерфейса TEN Agent Playground локально:</p>\n\
120
+ <pre>git clone https://github.com/TEN-framework/TEN-Agent.git\ncd TEN-Agent/playground\npnpm install\nAGENT_SERVER_URL=https://nitrox-ten.hf.space pnpm dev</pre>\n\
121
+ <p>Затем откройте <code>http://localhost:3000</code> в браузере.</p>\n\
122
+ </div>\n\
123
+ </body>\n\
124
+ </html>' > /app/static/index.html
125
 
126
+ # Установка точки входа
127
+ COPY app.py /app/app.py
128
+ RUN chmod +x /app/app.py
129
 
130
+ # Открываем порт
131
+ EXPOSE 8080
132
 
133
+ # Запускаем API сервер
134
+ ENTRYPOINT ["python3", "/app/app.py"]
app.py CHANGED
@@ -5,118 +5,74 @@ import sys
5
  import time
6
  from pathlib import Path
7
  import signal
8
- import shutil
 
 
9
 
10
- def main():
11
- processes = []
12
- try:
13
- # Пути к исполняемым файлам
14
- api_binary = Path("/app/server/bin/api")
15
- playground_dir = Path("/app/playground")
16
-
17
- # Проверяем существование файлов
18
- if not api_binary.exists():
19
- print(f"ERROR: API binary not found at {api_binary}", file=sys.stderr)
20
- return 1
21
-
22
- if not playground_dir.exists():
23
- print(f"ERROR: Playground directory not found at {playground_dir}", file=sys.stderr)
24
- return 1
25
-
26
- # Запускаем простой HTTP сервер для Hugging Face
27
- from http.server import HTTPServer, SimpleHTTPRequestHandler
28
-
29
- class CustomHandler(SimpleHTTPRequestHandler):
30
- def do_GET(self):
31
- if self.path == '/':
32
- self.send_response(200)
33
- self.send_header('Content-type', 'text/html; charset=utf-8')
34
- self.end_headers()
35
-
36
- html_content = """
37
- <!DOCTYPE html>
38
- <html>
39
- <head>
40
- <title>TEN Agent - Hugging Face Space</title>
41
- <meta charset="utf-8">
42
- <style>
43
- body { font-family: Arial, sans-serif; line-height: 1.6; max-width: 800px; margin: 0 auto; padding: 20px; }
44
- h1 { color: #333; }
45
- .info { background: #f8f9fa; border-left: 4px solid #28a745; padding: 15px; margin-bottom: 20px; }
46
- .endpoint { background: #e9ecef; padding: 10px; border-radius: 5px; font-family: monospace; }
47
- .api { margin-top: 30px; }
48
- </style>
49
- </head>
50
- <body>
51
- <h1>TEN Agent запущен успешно!</h1>
52
- <div class="info">
53
- <p>TEN Agent API сервер работает на порту 8080.</p>
54
- <p>В связи с ограничениями Hugging Face Space, полноценный интерфейс Playground UI не может быть запущен напрямую.</p>
55
- </div>
56
-
57
- <div class="api">
58
- <h2>API эндпоинты:</h2>
59
- <ul>
60
- <li><span class="endpoint">GET /health</span> - проверка состояния сервера</li>
61
- <li><span class="endpoint">GET /list</span> - список запущенных агентов</li>
62
- <li><span class="endpoint">GET /graphs</span> - доступные графы</li>
63
- </ul>
64
- </div>
65
-
66
- <h2>Инструкция по локальному использованию</h2>
67
- <p>Для использования полного интерфейса, подключите локальный Playground к этому API:</p>
68
- <ol>
69
- <li>Клонируйте репозиторий: <code>git clone https://github.com/TEN-framework/TEN-Agent.git</code></li>
70
- <li>Перейдите в директорию playground: <code>cd TEN-Agent/playground</code></li>
71
- <li>Установите зависимости: <code>pnpm install</code></li>
72
- <li>Запустите Playground с подключением к API: <code>AGENT_SERVER_URL=https://nitrox-ten.hf.space pnpm dev</code></li>
73
- <li>Откройте в браузере: <code>http://localhost:3000</code></li>
74
- </ol>
75
-
76
- <p>См. <a href="https://github.com/TEN-framework/TEN-Agent" target="_blank">документацию TEN Agent</a> для получения дополнительной информации.</p>
77
- </body>
78
- </html>
79
- """
80
-
81
- self.wfile.write(html_content.encode('utf-8'))
82
- elif self.path.startswith('/health') or self.path.startswith('/list') or self.path.startswith('/graphs'):
83
- # Проксирование API запросов к API серверу
84
- self.send_response(301)
85
- self.send_header('Location', f'http://localhost:8080{self.path}')
86
- self.end_headers()
87
- else:
88
- self.send_response(404)
89
- self.send_header('Content-type', 'text/plain; charset=utf-8')
90
- self.end_headers()
91
- self.wfile.write(b'Not Found')
92
-
93
- # Запускаем API сервер
94
- print("Starting TEN-Agent API server on port 8080...")
95
- api_server_process = subprocess.Popen([str(api_binary)])
96
- processes.append(api_server_process)
97
 
98
- # Запускаем HTTP сервер для Hugging Face
99
- port = 7860 # Hugging Face Space обычно ожидает сервер на порту 7860
100
- print(f"Starting HTTP server on port {port}...")
101
- httpd = HTTPServer(('0.0.0.0', port), CustomHandler)
 
 
 
 
 
 
 
 
 
 
 
 
102
  httpd.serve_forever()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
 
 
 
104
  except KeyboardInterrupt:
105
  print("Shutting down...")
106
  finally:
107
- # Завершаем все процессы при выходе
108
- for proc in processes:
109
- try:
110
- proc.terminate()
111
- proc.wait(timeout=5)
112
- except:
113
- proc.kill()
114
 
115
  return 0
116
 
117
  if __name__ == "__main__":
118
- # Корректная обработка сигналов завершения
119
- signal.signal(signal.SIGINT, lambda sig, frame: sys.exit(0))
120
- signal.signal(signal.SIGTERM, lambda sig, frame: sys.exit(0))
121
-
122
  sys.exit(main())
 
5
  import time
6
  from pathlib import Path
7
  import signal
8
+ import http.server
9
+ import socketserver
10
+ import threading
11
 
12
+ # Настройка путей
13
+ API_BINARY = Path("/app/server/bin/api")
14
+ STATIC_DIR = Path("/app/static")
15
+
16
+ # Проверка наличия файлов
17
+ if not API_BINARY.exists():
18
+ print(f"ERROR: API binary not found at {API_BINARY}", file=sys.stderr)
19
+ sys.exit(1)
20
+
21
+ # Класс для обработки HTTP запросов
22
+ class RequestHandler(http.server.SimpleHTTPRequestHandler):
23
+ def __init__(self, *args, **kwargs):
24
+ # Устанавливаем корневую директорию для статических файлов
25
+ super().__init__(*args, directory=STATIC_DIR, **kwargs)
26
+
27
+ def do_GET(self):
28
+ # Перенаправление корневого пути на статическую страницу
29
+ if self.path == '/':
30
+ self.path = '/index.html'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ # Передача всех остальных запросов в SimpleHTTPRequestHandler
33
+ return super().do_GET()
34
+
35
+ # Запуск API сервера в отдельном потоке
36
+ def run_api_server():
37
+ print("Starting TEN-Agent API server on port 8080...")
38
+ api_process = subprocess.Popen([str(API_BINARY)])
39
+ return api_process
40
+
41
+ # Запуск HTTP сервера для статических файлов
42
+ def run_http_server():
43
+ try:
44
+ # Сначала пытаемся запустить на порте 7860 (для HuggingFace)
45
+ PORT = 7860
46
+ httpd = socketserver.TCPServer(("", PORT), RequestHandler)
47
+ print(f"Serving static files on port {PORT}")
48
  httpd.serve_forever()
49
+ except OSError:
50
+ # Если порт 7860 занят, используем 8000
51
+ PORT = 8000
52
+ httpd = socketserver.TCPServer(("", PORT), RequestHandler)
53
+ print(f"Serving static files on port {PORT}")
54
+ httpd.serve_forever()
55
+
56
+ def main():
57
+ # Запуск API сервера
58
+ api_process = run_api_server()
59
+
60
+ # Запуск HTTP сервера в отдельном потоке
61
+ http_thread = threading.Thread(target=run_http_server, daemon=True)
62
+ http_thread.start()
63
 
64
+ try:
65
+ # Ожидание сигнала остановки
66
+ api_process.wait()
67
  except KeyboardInterrupt:
68
  print("Shutting down...")
69
  finally:
70
+ # Завершение процессов
71
+ if api_process and api_process.poll() is None:
72
+ api_process.terminate()
73
+ api_process.wait(timeout=5)
 
 
 
74
 
75
  return 0
76
 
77
  if __name__ == "__main__":
 
 
 
 
78
  sys.exit(main())