feat: CI/CD pipeline + Learning/Medicine/Travel services
Some checks failed
Build and Deploy GooSeek / build-backend (push) Failing after 1m4s
Build and Deploy GooSeek / build-webui (push) Failing after 1m2s
Build and Deploy GooSeek / deploy (push) Has been skipped

- Add Gitea Actions workflow for automated build & deploy
- Add K8s manifests: webui, travel-svc, medicine-svc, sandbox-svc
- Update kustomization for localhost:5000 registry
- Add ingress for gooseek.ru and api.gooseek.ru
- Learning cabinet with onboarding, courses, sandbox integration
- Medicine service with symptom analysis and doctor matching
- Travel service with itinerary planning
- Server setup scripts (NVIDIA/CUDA, K3s, Gitea runner)

Made-with: Cursor
This commit is contained in:
home
2026-03-02 20:25:44 +03:00
parent 08bd41e75c
commit ab48a0632b
92 changed files with 15562 additions and 2198 deletions

View File

@@ -0,0 +1,49 @@
# Установка NVIDIA + CUDA на сервере (Ubuntu 24.04)
Скрипт `setup-nvidia-cuda-ubuntu24.sh` ставит драйвер NVIDIA и CUDA Toolkit для работы с нейросетями (PyTorch, TensorFlow и т.д.).
## Что уже сделано на 192.168.31.59
- **Драйвер:** nvidia-driver-570-server (Open kernel module)
- **CUDA:** 12.6 в `/usr/local/cuda-12.6`
- **Окружение:** `/etc/profile.d/cuda.sh` — подключать: `source /etc/profile.d/cuda.sh`
## Обязательно после установки
**Перезагрузка** (без неё драйвер не загрузится):
```bash
sudo reboot
```
После перезагрузки проверка:
```bash
nvidia-smi
source /etc/profile.d/cuda.sh && nvcc --version
```
## Проверка для нейросетей (PyTorch)
```bash
source /etc/profile.d/cuda.sh
pip install torch --index-url https://download.pytorch.org/whl/cu124
python3 -c "import torch; print('CUDA:', torch.cuda.is_available()); print('Device:', torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'N/A')"
```
Для CUDA 12.6 подойдёт индекс `cu124` (PyTorch совместим с 12.4+).
## Запуск скрипта вручную
Если нужно переустановить или поставить на другом сервере:
```bash
scp backend/deploy/scripts/setup-nvidia-cuda-ubuntu24.sh user@server:/tmp/
ssh user@server "echo YOUR_SUDO_PASSWORD | sudo -S bash /tmp/setup-nvidia-cuda-ubuntu24.sh"
sudo reboot
```
## Железо на текущем сервере
- **GPU:** NVIDIA GeForce RTX 4060 Ti 16GB
- **ОС:** Ubuntu 24.04.4 LTS, ядро 6.8.0-101-generic

View File

@@ -0,0 +1,14 @@
[Unit]
Description=Gitea Actions Runner
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/gitea-runner
ExecStart=/usr/local/bin/act_runner daemon --config /opt/gitea-runner/config.yaml
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,55 @@
#!/bin/bash
set -e
echo "=== Installing Helm ==="
cd /tmp
curl -fsSL https://get.helm.sh/helm-v3.17.0-linux-amd64.tar.gz -o helm.tar.gz
tar -zxf helm.tar.gz
mv linux-amd64/helm /usr/local/bin/helm
rm -rf linux-amd64 helm.tar.gz
helm version
echo "=== Adding Helm repos ==="
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add jetstack https://charts.jetstack.io
helm repo update
echo "=== Installing Nginx Ingress Controller ==="
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespace \
--set controller.hostNetwork=true \
--set controller.kind=DaemonSet \
--set controller.service.type=ClusterIP \
--wait --timeout 300s
echo "=== Installing Cert-Manager ==="
helm upgrade --install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace \
--set crds.enabled=true \
--wait --timeout 300s
echo "=== Creating Let's Encrypt ClusterIssuer ==="
cat <<'EOF' | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@gooseek.ru
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
EOF
echo "=== Creating namespaces ==="
kubectl create namespace gooseek --dry-run=client -o yaml | kubectl apply -f -
kubectl create namespace gitea --dry-run=client -o yaml | kubectl apply -f -
echo "=== Done! Checking status ==="
kubectl get nodes
kubectl get pods -A

View File

@@ -0,0 +1,248 @@
#!/bin/bash
set -e
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
echo "=== Installing Gitea via manifests ==="
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitea-data
namespace: gitea
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: ConfigMap
metadata:
name: gitea-config
namespace: gitea
data:
app.ini: |
APP_NAME = GooSeek Git
RUN_MODE = prod
[server]
DOMAIN = git.gooseek.ru
ROOT_URL = https://git.gooseek.ru/
HTTP_PORT = 3000
SSH_PORT = 22
SSH_DOMAIN = git.gooseek.ru
[database]
DB_TYPE = sqlite3
PATH = /data/gitea/gitea.db
[security]
INSTALL_LOCK = true
SECRET_KEY = $(openssl rand -hex 32)
[service]
DISABLE_REGISTRATION = false
REQUIRE_SIGNIN_VIEW = false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea
namespace: gitea
spec:
replicas: 1
selector:
matchLabels:
app: gitea
template:
metadata:
labels:
app: gitea
spec:
containers:
- name: gitea
image: gitea/gitea:1.22
ports:
- containerPort: 3000
name: http
- containerPort: 22
name: ssh
volumeMounts:
- name: data
mountPath: /data
- name: config
mountPath: /data/gitea/conf
env:
- name: GITEA__database__DB_TYPE
value: sqlite3
- name: GITEA__database__PATH
value: /data/gitea/gitea.db
- name: GITEA__server__DOMAIN
value: git.gooseek.ru
- name: GITEA__server__ROOT_URL
value: https://git.gooseek.ru/
- name: GITEA__security__INSTALL_LOCK
value: "false"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
volumes:
- name: data
persistentVolumeClaim:
claimName: gitea-data
- name: config
configMap:
name: gitea-config
---
apiVersion: v1
kind: Service
metadata:
name: gitea
namespace: gitea
spec:
selector:
app: gitea
ports:
- port: 3000
targetPort: 3000
name: http
- port: 22
targetPort: 22
name: ssh
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitea-ingress
namespace: gitea
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- git.gooseek.ru
secretName: gitea-tls
rules:
- host: git.gooseek.ru
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitea
port:
number: 3000
EOF
echo "=== Installing Docker Registry ==="
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: registry-pvc
namespace: gooseek
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: registry
namespace: gooseek
spec:
replicas: 1
selector:
matchLabels:
app: registry
template:
metadata:
labels:
app: registry
spec:
containers:
- name: registry
image: registry:2
ports:
- containerPort: 5000
volumeMounts:
- name: registry-data
mountPath: /var/lib/registry
env:
- name: REGISTRY_STORAGE_DELETE_ENABLED
value: "true"
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "200m"
volumes:
- name: registry-data
persistentVolumeClaim:
claimName: registry-pvc
---
apiVersion: v1
kind: Service
metadata:
name: registry
namespace: gooseek
spec:
selector:
app: registry
ports:
- port: 5000
targetPort: 5000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: registry-ingress
namespace: gooseek
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
ingressClassName: nginx
tls:
- hosts:
- registry.gooseek.ru
secretName: registry-tls
rules:
- host: registry.gooseek.ru
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: registry
port:
number: 5000
EOF
echo "=== Waiting for deployments ==="
kubectl -n gitea rollout status deployment/gitea --timeout=180s || true
kubectl -n gooseek rollout status deployment/registry --timeout=120s || true
echo "=== Status ==="
kubectl get pods -A
kubectl get ingress -A
kubectl get certificates -A
echo ""
echo "=== DONE ==="
echo "Gitea: https://git.gooseek.ru (first user to register will be admin)"
echo "Registry: https://registry.gooseek.ru"

View File

@@ -0,0 +1,130 @@
#!/bin/bash
set -e
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
echo "=== Adding Gitea Helm repo ==="
helm repo add gitea-charts https://dl.gitea.com/charts/
helm repo update
echo "=== Installing Gitea ==="
helm upgrade --install gitea gitea-charts/gitea \
--namespace gitea \
--set gitea.admin.username=admin \
--set gitea.admin.password=GooSeek2026! \
--set gitea.admin.email=admin@gooseek.ru \
--set persistence.enabled=true \
--set persistence.size=10Gi \
--set postgresql-ha.enabled=false \
--set postgresql.enabled=false \
--set redis-cluster.enabled=false \
--set redis.enabled=false \
--set gitea.config.database.DB_TYPE=sqlite3 \
--set gitea.config.server.ROOT_URL=https://git.gooseek.ru \
--set gitea.config.server.DOMAIN=git.gooseek.ru \
--set ingress.enabled=true \
--set ingress.className=nginx \
--set ingress.hosts[0].host=git.gooseek.ru \
--set ingress.hosts[0].paths[0].path=/ \
--set ingress.hosts[0].paths[0].pathType=Prefix \
--set ingress.tls[0].secretName=gitea-tls \
--set ingress.tls[0].hosts[0]=git.gooseek.ru \
--set ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod \
--wait --timeout 300s
echo "=== Installing Docker Registry ==="
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: registry-pvc
namespace: gooseek
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: registry
namespace: gooseek
spec:
replicas: 1
selector:
matchLabels:
app: registry
template:
metadata:
labels:
app: registry
spec:
containers:
- name: registry
image: registry:2
ports:
- containerPort: 5000
volumeMounts:
- name: registry-data
mountPath: /var/lib/registry
env:
- name: REGISTRY_STORAGE_DELETE_ENABLED
value: "true"
volumes:
- name: registry-data
persistentVolumeClaim:
claimName: registry-pvc
---
apiVersion: v1
kind: Service
metadata:
name: registry
namespace: gooseek
spec:
selector:
app: registry
ports:
- port: 5000
targetPort: 5000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: registry-ingress
namespace: gooseek
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
ingressClassName: nginx
tls:
- hosts:
- registry.gooseek.ru
secretName: registry-tls
rules:
- host: registry.gooseek.ru
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: registry
port:
number: 5000
EOF
echo "=== Waiting for pods ==="
kubectl -n gitea wait --for=condition=Ready pod -l app.kubernetes.io/name=gitea --timeout=300s || true
kubectl -n gooseek wait --for=condition=Ready pod -l app=registry --timeout=120s || true
echo "=== Final status ==="
kubectl get pods -A
kubectl get ingress -A
kubectl get certificates -A
echo ""
echo "=== DONE ==="
echo "Gitea: https://git.gooseek.ru (admin / GooSeek2026!)"
echo "Registry: https://registry.gooseek.ru"

View File

@@ -0,0 +1,65 @@
#!/bin/bash
set -e
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
echo "=== Enabling Gitea Actions ==="
# Update Gitea config to enable actions
kubectl -n gitea exec deploy/gitea -- sh -c '
cat >> /data/gitea/conf/app.ini << EOF
[actions]
ENABLED = true
DEFAULT_ACTIONS_URL = https://github.com
EOF
'
echo "=== Restarting Gitea ==="
kubectl -n gitea rollout restart deploy/gitea
kubectl -n gitea rollout status deploy/gitea --timeout=120s
echo "=== Installing Act Runner ==="
cd /tmp
curl -sL https://gitea.com/gitea/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64 -o act_runner
chmod +x act_runner
mv act_runner /usr/local/bin/
echo "=== Creating runner service ==="
mkdir -p /opt/gitea-runner
cd /opt/gitea-runner
# Create config
cat > config.yaml << 'EOF'
log:
level: info
runner:
file: .runner
capacity: 2
timeout: 3h
insecure: false
fetch_timeout: 5s
fetch_interval: 2s
labels:
- ubuntu-latest:docker://node:20-bullseye
- ubuntu-22.04:docker://node:20-bullseye
cache:
enabled: true
dir: /opt/gitea-runner/cache
container:
network: host
privileged: true
options:
workdir_parent:
valid_volumes:
- /opt/gitea-runner/cache
host:
workdir_parent: /opt/gitea-runner/workspace
EOF
echo "=== Runner installed ==="
echo ""
echo "NEXT STEPS:"
echo "1. Go to https://git.gooseek.ru and register/login as admin"
echo "2. Go to Site Administration -> Actions -> Runners"
echo "3. Click 'Create new Runner' and copy the registration token"
echo "4. Run: act_runner register --config /opt/gitea-runner/config.yaml --instance https://git.gooseek.ru --token YOUR_TOKEN"
echo "5. Run: act_runner daemon --config /opt/gitea-runner/config.yaml"

View File

@@ -0,0 +1,60 @@
#!/bin/bash
set -e
echo "=== Installing K3s ==="
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable traefik --disable servicelb --tls-san gooseek.ru --tls-san 5.187.77.89" sh -
echo "=== Waiting for K3s to be ready ==="
sleep 10
sudo k3s kubectl wait --for=condition=Ready node --all --timeout=120s
echo "=== Setting up kubectl for user ==="
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
chmod 600 ~/.kube/config
echo "=== Installing Helm ==="
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
echo "=== Installing Nginx Ingress Controller ==="
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx --create-namespace \
--set controller.service.type=NodePort \
--set controller.service.nodePorts.http=80 \
--set controller.service.nodePorts.https=443 \
--set controller.hostNetwork=true \
--set controller.kind=DaemonSet
echo "=== Installing Cert-Manager ==="
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace \
--set crds.enabled=true
echo "=== Waiting for cert-manager ==="
kubectl -n cert-manager wait --for=condition=Available deployment --all --timeout=120s
echo "=== Creating Let's Encrypt ClusterIssuer ==="
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@gooseek.ru
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
EOF
echo "=== K3s + Ingress + Cert-Manager installed ==="
kubectl get nodes
kubectl get pods -A

View File

@@ -0,0 +1,73 @@
#!/bin/bash
# Установка драйвера NVIDIA и CUDA на Ubuntu 24.04 для работы с нейросетями (RTX 40xx).
# Запуск: sudo bash setup-nvidia-cuda-ubuntu24.sh
# После выполнения нужна перезагрузка: sudo reboot
set -e
if [ "$(id -u)" -ne 0 ]; then
echo "Запустите скрипт с sudo."
exit 1
fi
echo "=== 1/6 Отключение драйвера Nouveau ==="
cat > /etc/modprobe.d/blacklist-nvidia-nouveau.conf << 'EOF'
blacklist nouveau
options nouveau modeset=0
EOF
update-initramfs -u 2>/dev/null || true
echo "=== 2/6 Обновление системы и установка зависимостей ==="
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y build-essential wget
echo "=== 3/6 Установка драйвера NVIDIA (рекомендуемый для железа) ==="
# Для RTX 4060 Ti подойдёт драйвер 550+; ubuntu-drivers выберет подходящий
apt-get install -y ubuntu-drivers-common
DRIVER=$(ubuntu-drivers list 2>/dev/null | grep -m1 "nvidia-driver-" || echo "nvidia-driver-560")
if apt-cache show "$DRIVER" &>/dev/null; then
apt-get install -y "$DRIVER"
else
apt-get install -y nvidia-driver-560 || apt-get install -y nvidia-driver-550 || ubuntu-drivers autoinstall
fi
echo "=== 4/6 Добавление репозитория CUDA и установка CUDA Toolkit 12 ==="
KEYRING_DEB="/tmp/cuda-keyring.deb"
wget -q -O "$KEYRING_DEB" "https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb" || {
echo "Ошибка загрузки cuda-keyring. Проверьте сеть."
exit 1
}
dpkg -i "$KEYRING_DEB"
rm -f "$KEYRING_DEB"
apt-get update -qq
apt-get install -y cuda-toolkit-12-6 || apt-get install -y cuda-toolkit-12-5 || apt-get install -y cuda
echo "=== 5/6 Настройка окружения CUDA (PATH и библиотеки) ==="
# Ubuntu/NVIDIA repo ставит в /usr/local/cuda-12.6, симлинк /usr/local/cuda создаётся пакетом cuda
for CUDA_ROOT in /usr/local/cuda /usr/local/cuda-12.6 /usr/local/cuda-12.5; do
if [ -d "$CUDA_ROOT" ]; then
cat > /etc/profile.d/cuda.sh << EOF
# CUDA for neural networks
export PATH=$CUDA_ROOT/bin:\$PATH
export LD_LIBRARY_PATH=$CUDA_ROOT/lib64:\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}
EOF
chmod 644 /etc/profile.d/cuda.sh
echo "Файл /etc/profile.d/cuda.sh создан (CUDA_ROOT=$CUDA_ROOT)."
break
fi
done
if [ ! -f /etc/profile.d/cuda.sh ]; then
echo "Предупреждение: каталог CUDA не найден. После установки cuda-toolkit выполните: sudo bash -c 'echo \"export PATH=/usr/local/cuda/bin:\\\$PATH\" > /etc/profile.d/cuda.sh'"
fi
echo "=== 6/6 Готово ==="
echo ""
echo "Драйвер NVIDIA и CUDA Toolkit установлены."
echo "ОБЯЗАТЕЛЬНО перезагрузите сервер для загрузки драйвера:"
echo " sudo reboot"
echo ""
echo "После перезагрузки проверьте:"
echo " nvidia-smi"
echo " source /etc/profile.d/cuda.sh && nvcc --version"
echo " python3 -c 'import torch; print(torch.cuda.is_available())' # если ставите PyTorch"