From cbb5b4917a0eda8b4d1afe390d6712f1f9a7c678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Fri, 22 May 2026 21:09:09 +0400 Subject: [PATCH] =?UTF-8?q?germany:=20server/=20=D0=BA=D0=BE=D0=BD=D1=84?= =?UTF-8?q?=D0=B8=D0=B3=D0=B8=20=D0=B2=20=D1=80=D0=B5=D0=BF=D0=B5,=20deplo?= =?UTF-8?q?y=5Flang.sh=20=E2=86=92=20rsync=20+=20build=20=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=92=D0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy_lang.sh | 32 +++++++++++++++++++----------- server/lang.kube5s.ru.conf | 40 ++++++++++++++++++++++++++++++++++++++ server/proxy.py | 34 ++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 server/lang.kube5s.ru.conf create mode 100644 server/proxy.py diff --git a/deploy_lang.sh b/deploy_lang.sh index 9e32280..781824f 100755 --- a/deploy_lang.sh +++ b/deploy_lang.sh @@ -1,16 +1,26 @@ #!/bin/bash set -e +VM="root@95.179.252.111" +SSH="ssh -i ~/.ssh/vultr_openssh -o StrictHostKeyChecking=no" -# Собираем dist/index.html (CSS + JS встроены) -~/lang/.venv/bin/python3 ~/lang/build.sh +echo "=== rsync repo -> VM ===" +rsync -az -e "$SSH" --exclude='.git' --exclude='.venv' --exclude='__pycache__' ~/lang/ ${VM}:/opt/lyngvo/ -# Вклеиваем Groq API ключ в dist/index.html -KEY=$(cat ~/lang/token.txt) -cp ~/lang/dist/index.html /tmp/lyngvo_index.html -sed -i "s|const GROQ_API_KEY = '';|const GROQ_API_KEY = '${KEY}';|" /tmp/lyngvo_index.html +echo "=== build + deploy ===" +$SSH $VM "bash -c ' + cd /opt/lyngvo + python3 build.sh + KEY=\$(cat token.txt) + sed -i \"s|const GROQ_API_KEY = .*;|const GROQ_API_KEY = '\\\''\$KEY'\\\'';|\" dist/index.html + cp dist/index.html /var/www/lyngvo/index.html + if [ -f server/lang.kube5s.ru.conf ]; then + cp server/lang.kube5s.ru.conf /etc/nginx/conf.d/ + nginx -t && systemctl reload nginx + fi + if [ -f server/proxy.py ]; then + cp server/proxy.py /opt/groq-proxy/proxy.py + systemctl reload groq-proxy 2>/dev/null || true + fi +'" -# Деплой на германскую ВМ (nginx + Groq прокси) -scp -i ~/.ssh/vultr_openssh -o StrictHostKeyChecking=no /tmp/lyngvo_index.html root@95.179.252.111:/var/www/lyngvo/index.html - -rm -f /tmp/lyngvo_index.html -echo "\n=== Деплой завершён. Проверяй https://lang.kube5s.ru ===" +echo "=== https://lang.kube5s.ru ===" diff --git a/server/lang.kube5s.ru.conf b/server/lang.kube5s.ru.conf new file mode 100644 index 0000000..fd7e60f --- /dev/null +++ b/server/lang.kube5s.ru.conf @@ -0,0 +1,40 @@ +# Lyngvo — тренажёр произношения +server { + listen 80; + server_name lang.kube5s.ru; + location /.well-known/acme-challenge/ { root /var/www/certbot; } + location / { return 301 https://$host$request_uri; } +} +server { + listen 443 ssl; + http2 on; + server_name lang.kube5s.ru; + + ssl_certificate /etc/letsencrypt/live/lang.kube5s.ru/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/lang.kube5s.ru/privkey.pem; + + root /var/www/lyngvo; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + # Groq API proxy + location /openai/ { + proxy_pass http://127.0.0.1:8765; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_read_timeout 120s; + proxy_send_timeout 120s; + proxy_request_buffering off; + } + + # Будущий бэкенд (Python/Go) + location /api/ { + proxy_pass http://127.0.0.1:8080; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_read_timeout 120s; + } +} diff --git a/server/proxy.py b/server/proxy.py new file mode 100644 index 0000000..f2e9ba8 --- /dev/null +++ b/server/proxy.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +from flask import Flask, request, Response +import requests + +app = Flask(__name__) +GROQ_BASE = "https://api.groq.com" + +CORS = { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET, POST, OPTIONS", + "Access-Control-Allow-Headers": "Authorization, Content-Type", +} + +@app.route("/", methods=["OPTIONS"]) +def options(path): + return Response(status=204, headers=CORS) + +# Generic proxy for ALL Groq paths +@app.route("/", methods=["GET", "POST", "PUT", "DELETE", "PATCH"]) +def proxy(subpath): + url = f"{GROQ_BASE}/{subpath}" + hdrs = {} + if request.headers.get("Authorization"): + hdrs["Authorization"] = request.headers["Authorization"] + if request.headers.get("Content-Type"): + hdrs["Content-Type"] = request.headers["Content-Type"] + r = requests.request(request.method, url, headers=hdrs, + data=request.get_data(), timeout=60, stream=True) + out = dict(CORS) + out["Content-Type"] = r.headers.get("Content-Type", "application/json") + return Response(r.iter_content(8192), status=r.status_code, headers=out) + +if __name__ == "__main__": + app.run(host="127.0.0.1", port=8765)