feat: CI/CD pipeline + Learning/Medicine/Travel services
- 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:
@@ -24,7 +24,9 @@ RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/file-svc ./cmd/fi
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/thread-svc ./cmd/thread-svc
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/finance-heatmap-svc ./cmd/finance-heatmap-svc
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/learning-svc ./cmd/learning-svc
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/sandbox-svc ./cmd/sandbox-svc
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/travel-svc ./cmd/travel-svc
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/medicine-svc ./cmd/medicine-svc
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/labs-svc ./cmd/labs-svc
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/podcast-svc ./cmd/podcast-svc
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /bin/admin-svc ./cmd/admin-svc
|
||||
@@ -43,7 +45,7 @@ COPY --from=builder /bin/* /app/
|
||||
ENV SERVICE=api-gateway
|
||||
ENV PORT=3015
|
||||
|
||||
EXPOSE 3015 3018 3005 3001 3020 3021 3002 3025 3026 3027 3035 3040
|
||||
EXPOSE 3015 3018 3005 3001 3020 3021 3002 3025 3026 3027 3034 3035 3036 3037 3040
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:${PORT}/health || exit 1
|
||||
|
||||
@@ -5,11 +5,11 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=auth-svc
|
||||
- PORT=3050
|
||||
- DATABASE_URL=postgres://gooseek:gooseek@postgres:5432/gooseek?sslmode=disable
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- AUTH_SVC_URL=http://auth-svc:3050
|
||||
ports:
|
||||
- "3050:3050"
|
||||
depends_on:
|
||||
@@ -26,6 +26,7 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=api-gateway
|
||||
- PORT=3015
|
||||
@@ -39,9 +40,10 @@ services:
|
||||
- DISCOVER_SVC_URL=http://discover-svc:3002
|
||||
- FINANCE_HEATMAP_SVC_URL=http://finance-heatmap-svc:3033
|
||||
- LEARNING_SVC_URL=http://learning-svc:3034
|
||||
- SANDBOX_SVC_URL=http://sandbox-svc:3036
|
||||
- TRAVEL_SVC_URL=http://travel-svc:3035
|
||||
- MEDICINE_SVC_URL=http://medicine-svc:3037
|
||||
- ADMIN_SVC_URL=http://admin-svc:3040
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- REDIS_URL=redis://redis:6379
|
||||
ports:
|
||||
- "3015:3015"
|
||||
@@ -52,6 +54,7 @@ services:
|
||||
- thread-svc
|
||||
- admin-svc
|
||||
- travel-svc
|
||||
- medicine-svc
|
||||
- redis
|
||||
networks:
|
||||
- gooseek
|
||||
@@ -60,10 +63,10 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.chat-svc
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=chat-svc
|
||||
- PORT=3005
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- AUTH_SVC_URL=http://auth-svc:3050
|
||||
- MASTER_AGENTS_SVC_URL=http://agent-svc:3018
|
||||
- DISCOVER_SVC_URL=http://discover-svc:3002
|
||||
@@ -79,23 +82,15 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.agent-svc
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=agent-svc
|
||||
- PORT=3018
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- AUTH_SVC_URL=http://auth-svc:3050
|
||||
- SEARXNG_URL=http://searxng:8080
|
||||
- DISCOVER_SVC_URL=http://discover-svc:3002
|
||||
- CRAWL4AI_URL=http://crawl4ai:11235
|
||||
- TRAVEL_SVC_URL=http://travel-svc:3035
|
||||
- TRAVELPAYOUTS_TOKEN=${TRAVELPAYOUTS_TOKEN}
|
||||
- TRAVELPAYOUTS_MARKER=${TRAVELPAYOUTS_MARKER}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- GEMINI_API_KEY=${GEMINI_API_KEY}
|
||||
- TIMEWEB_API_BASE_URL=${TIMEWEB_API_BASE_URL}
|
||||
- TIMEWEB_AGENT_ACCESS_ID=${TIMEWEB_AGENT_ACCESS_ID}
|
||||
- TIMEWEB_API_KEY=${TIMEWEB_API_KEY}
|
||||
ports:
|
||||
- "3018:3018"
|
||||
depends_on:
|
||||
@@ -111,6 +106,7 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.search-svc
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=search-svc
|
||||
- PORT=3001
|
||||
@@ -126,12 +122,10 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=llm-svc
|
||||
- PORT=3020
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- GEMINI_API_KEY=${GEMINI_API_KEY}
|
||||
ports:
|
||||
- "3020:3020"
|
||||
networks:
|
||||
@@ -141,6 +135,7 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=scraper-svc
|
||||
- PORT=3021
|
||||
@@ -154,6 +149,7 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.discover-svc
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=discover-svc
|
||||
- PORT=3002
|
||||
@@ -173,12 +169,12 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=collection-svc
|
||||
- PORT=3025
|
||||
- DATABASE_URL=postgres://gooseek:gooseek@postgres:5432/gooseek?sslmode=disable
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- AUTH_SVC_URL=${AUTH_SVC_URL}
|
||||
- AUTH_SVC_URL=http://auth-svc:3050
|
||||
ports:
|
||||
- "3025:3025"
|
||||
depends_on:
|
||||
@@ -190,13 +186,11 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=file-svc
|
||||
- PORT=3026
|
||||
- DATABASE_URL=postgres://gooseek:gooseek@postgres:5432/gooseek?sslmode=disable
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- FILE_STORAGE_PATH=/data/files
|
||||
ports:
|
||||
- "3026:3026"
|
||||
@@ -211,13 +205,12 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=thread-svc
|
||||
- PORT=3027
|
||||
- DATABASE_URL=postgres://gooseek:gooseek@postgres:5432/gooseek?sslmode=disable
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- AUTH_SVC_URL=${AUTH_SVC_URL}
|
||||
- AUTH_SVC_URL=http://auth-svc:3050
|
||||
ports:
|
||||
- "3027:3027"
|
||||
depends_on:
|
||||
@@ -229,12 +222,11 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=labs-svc
|
||||
- PORT=3031
|
||||
- LABS_SVC_PORT=3031
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
ports:
|
||||
- "3031:3031"
|
||||
networks:
|
||||
@@ -244,13 +236,11 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=podcast-svc
|
||||
- PORT=3032
|
||||
- PODCAST_SVC_PORT=3032
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- ELEVENLABS_API_KEY=${ELEVENLABS_API_KEY}
|
||||
ports:
|
||||
- "3032:3032"
|
||||
volumes:
|
||||
@@ -262,12 +252,11 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=finance-heatmap-svc
|
||||
- PORT=3033
|
||||
- REDIS_URL=redis://redis:6379
|
||||
# MOEX, Крипто, Валюты работают без URL (встроенные провайдеры). Для своих рынков — URL сервиса, GET ?market=...&range=...
|
||||
- FINANCE_DATA_PROVIDER_URL=${FINANCE_DATA_PROVIDER_URL:-}
|
||||
ports:
|
||||
- "3033:3033"
|
||||
depends_on:
|
||||
@@ -279,16 +268,12 @@ services:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=learning-svc
|
||||
- PORT=3034
|
||||
- LEARNING_SVC_PORT=3034
|
||||
- TIMEWEB_API_BASE_URL=${TIMEWEB_API_BASE_URL}
|
||||
- TIMEWEB_AGENT_ACCESS_ID=${TIMEWEB_AGENT_ACCESS_ID}
|
||||
- TIMEWEB_API_KEY=${TIMEWEB_API_KEY}
|
||||
- DEFAULT_LLM_MODEL=${DEFAULT_LLM_MODEL:-gpt-4o-mini}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- AUTH_SVC_URL=http://auth-svc:3050
|
||||
- DATABASE_URL=postgres://gooseek:gooseek@postgres:5432/gooseek?sslmode=disable
|
||||
ports:
|
||||
- "3034:3034"
|
||||
@@ -297,31 +282,37 @@ services:
|
||||
networks:
|
||||
- gooseek
|
||||
|
||||
sandbox-svc:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=sandbox-svc
|
||||
- PORT=3036
|
||||
- SANDBOX_SVC_PORT=3036
|
||||
- AUTH_SVC_URL=http://auth-svc:3050
|
||||
- DATABASE_URL=postgres://gooseek:gooseek@postgres:5432/gooseek?sslmode=disable
|
||||
- OPENSANDBOX_URL=http://opensandbox-server:8080
|
||||
ports:
|
||||
- "3036:3036"
|
||||
depends_on:
|
||||
- postgres
|
||||
networks:
|
||||
- gooseek
|
||||
|
||||
travel-svc:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=travel-svc
|
||||
- PORT=3035
|
||||
- DATABASE_URL=postgres://gooseek:gooseek@postgres:5432/gooseek?sslmode=disable
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- AUTH_SVC_URL=http://auth-svc:3050
|
||||
# Российские API (по умолчанию)
|
||||
- USE_RUSSIAN_APIS=true
|
||||
- TRAVELPAYOUTS_TOKEN=${TRAVELPAYOUTS_TOKEN}
|
||||
- TRAVELPAYOUTS_MARKER=${TRAVELPAYOUTS_MARKER}
|
||||
- TWOGIS_API_KEY=${TWOGIS_API_KEY}
|
||||
# Международные API (опционально)
|
||||
- AMADEUS_API_KEY=${AMADEUS_API_KEY}
|
||||
- AMADEUS_API_SECRET=${AMADEUS_API_SECRET}
|
||||
- OPENROUTE_API_KEY=${OPENROUTE_API_KEY}
|
||||
# LLM (TimeWeb)
|
||||
- LLM_PROVIDER=timeweb
|
||||
- LLM_MODEL=${DEFAULT_LLM_MODEL:-gpt-4o-mini}
|
||||
- TIMEWEB_API_BASE_URL=${TIMEWEB_API_BASE_URL}
|
||||
- TIMEWEB_AGENT_ACCESS_ID=${TIMEWEB_AGENT_ACCESS_ID}
|
||||
- TIMEWEB_API_KEY=${TIMEWEB_API_KEY}
|
||||
ports:
|
||||
- "3035:3035"
|
||||
depends_on:
|
||||
@@ -330,17 +321,36 @@ services:
|
||||
networks:
|
||||
- gooseek
|
||||
|
||||
medicine-svc:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=medicine-svc
|
||||
- PORT=3037
|
||||
- AUTH_SVC_URL=http://auth-svc:3050
|
||||
- SEARXNG_URL=http://searxng:8080
|
||||
- LLM_PROVIDER=timeweb
|
||||
ports:
|
||||
- "3037:3037"
|
||||
depends_on:
|
||||
- auth-svc
|
||||
- searxng
|
||||
networks:
|
||||
- gooseek
|
||||
|
||||
admin-svc:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile.all
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- SERVICE=admin-svc
|
||||
- PORT=3040
|
||||
- ADMIN_SVC_PORT=3040
|
||||
- DATABASE_URL=postgres://gooseek:gooseek@postgres:5432/gooseek?sslmode=disable
|
||||
- JWT_SECRET=${JWT_SECRET}
|
||||
- AUTH_SVC_URL=${AUTH_SVC_URL}
|
||||
- AUTH_SVC_URL=http://auth-svc:3050
|
||||
- MINIO_ENDPOINT=minio:9000
|
||||
- MINIO_ACCESS_KEY=minioadmin
|
||||
- MINIO_SECRET_KEY=minioadmin
|
||||
@@ -378,12 +388,12 @@ services:
|
||||
context: ../../webui
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- NEXT_PUBLIC_DISABLED_ROUTES=${NEXT_PUBLIC_DISABLED_ROUTES:-/medicine}
|
||||
NEXT_PUBLIC_ENABLED_ROUTES: ${NEXT_PUBLIC_ENABLED_ROUTES:-}
|
||||
NEXT_PUBLIC_TWOGIS_API_KEY: ${NEXT_PUBLIC_TWOGIS_API_KEY:-}
|
||||
env_file: ../../../.env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- API_URL=http://api-gateway:3015
|
||||
- NEXT_PUBLIC_API_URL=
|
||||
- NEXT_PUBLIC_DISABLED_ROUTES=${NEXT_PUBLIC_DISABLED_ROUTES:-/medicine}
|
||||
ports:
|
||||
- "3000:3000"
|
||||
depends_on:
|
||||
|
||||
@@ -16,6 +16,27 @@ data:
|
||||
COLLECTION_SVC_URL: "http://collection-svc:3025"
|
||||
FILE_SVC_URL: "http://file-svc:3026"
|
||||
THREAD_SVC_URL: "http://thread-svc:3027"
|
||||
LEARNING_SVC_URL: "http://learning-svc:3034"
|
||||
MEDICINE_SVC_URL: "http://medicine-svc:3037"
|
||||
SANDBOX_SVC_URL: "http://sandbox-svc:3036"
|
||||
OPENSANDBOX_URL: "http://opensandbox-server:8080"
|
||||
AUTH_SVC_URL: "http://auth-svc:3050"
|
||||
TRAVEL_SVC_URL: "http://travel-svc:3035"
|
||||
ADMIN_SVC_URL: "http://admin-svc:3040"
|
||||
DEFAULT_LLM_MODEL: "${DEFAULT_LLM_MODEL}"
|
||||
DEFAULT_LLM_PROVIDER: "${DEFAULT_LLM_PROVIDER}"
|
||||
TIMEWEB_API_BASE_URL: "${TIMEWEB_API_BASE_URL}"
|
||||
TIMEWEB_AGENT_ACCESS_ID: "${TIMEWEB_AGENT_ACCESS_ID}"
|
||||
TRAVELPAYOUTS_TOKEN: "${TRAVELPAYOUTS_TOKEN}"
|
||||
NEXT_PUBLIC_ENABLED_ROUTES: "${NEXT_PUBLIC_ENABLED_ROUTES}"
|
||||
NEXT_PUBLIC_TWOGIS_API_KEY: "${NEXT_PUBLIC_TWOGIS_API_KEY}"
|
||||
S3_ENDPOINT: "${S3_ENDPOINT}"
|
||||
S3_ACCESS_KEY: "${S3_ACCESS_KEY}"
|
||||
S3_SECRET_KEY: "${S3_SECRET_KEY}"
|
||||
S3_BUCKET: "${S3_BUCKET}"
|
||||
S3_USE_SSL: "${S3_USE_SSL}"
|
||||
S3_REGION: "${S3_REGION}"
|
||||
S3_PUBLIC_URL: "${S3_PUBLIC_URL}"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
@@ -28,5 +49,6 @@ stringData:
|
||||
ANTHROPIC_API_KEY: "${ANTHROPIC_API_KEY}"
|
||||
GEMINI_API_KEY: "${GEMINI_API_KEY}"
|
||||
JWT_SECRET: "${JWT_SECRET}"
|
||||
TIMEWEB_API_KEY: "${TIMEWEB_API_KEY}"
|
||||
POSTGRES_USER: "gooseek"
|
||||
POSTGRES_PASSWORD: "gooseek"
|
||||
|
||||
@@ -3,9 +3,24 @@ set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
BACKEND_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
ROOT_DIR="$(cd "$BACKEND_DIR/.." && pwd)"
|
||||
ENV_FILE="$ROOT_DIR/.env"
|
||||
|
||||
echo "=== GooSeek Go Backend K8s Deployment ==="
|
||||
REGISTRY="localhost:5000"
|
||||
IMAGE_TAG="${IMAGE_TAG:-latest}"
|
||||
|
||||
echo "=== GooSeek K8s Deployment ==="
|
||||
echo "Backend dir: $BACKEND_DIR"
|
||||
echo "Registry: $REGISTRY"
|
||||
echo "Tag: $IMAGE_TAG"
|
||||
|
||||
# Load .env
|
||||
if [ -f "$ENV_FILE" ]; then
|
||||
echo "Loading env from $ENV_FILE"
|
||||
set -a
|
||||
source "$ENV_FILE"
|
||||
set +a
|
||||
fi
|
||||
|
||||
# Check kubectl
|
||||
if ! command -v kubectl &> /dev/null; then
|
||||
@@ -13,17 +28,40 @@ if ! command -v kubectl &> /dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build Docker image
|
||||
# Build and push backend image
|
||||
echo ""
|
||||
echo "=== Building Docker image ==="
|
||||
echo "=== Building Go backend image ==="
|
||||
cd "$BACKEND_DIR"
|
||||
docker build -f deploy/docker/Dockerfile.all -t gooseek/backend:latest .
|
||||
docker build -f deploy/docker/Dockerfile.all \
|
||||
-t "$REGISTRY/gooseek/backend:$IMAGE_TAG" \
|
||||
-t "$REGISTRY/gooseek/backend:latest" \
|
||||
.
|
||||
|
||||
# Load to k3s (if using k3s)
|
||||
if command -v k3s &> /dev/null; then
|
||||
echo ""
|
||||
echo "=== Loading image to k3s ==="
|
||||
docker save gooseek/backend:latest | sudo k3s ctr images import -
|
||||
echo "=== Pushing backend to registry ==="
|
||||
docker push "$REGISTRY/gooseek/backend:$IMAGE_TAG"
|
||||
docker push "$REGISTRY/gooseek/backend:latest"
|
||||
|
||||
# Build and push webui image
|
||||
echo ""
|
||||
echo "=== Building webui image ==="
|
||||
docker build \
|
||||
-f "$BACKEND_DIR/webui/Dockerfile" \
|
||||
--build-arg "NEXT_PUBLIC_ENABLED_ROUTES=${NEXT_PUBLIC_ENABLED_ROUTES:-}" \
|
||||
--build-arg "NEXT_PUBLIC_TWOGIS_API_KEY=${NEXT_PUBLIC_TWOGIS_API_KEY:-}" \
|
||||
-t "$REGISTRY/gooseek/webui:$IMAGE_TAG" \
|
||||
-t "$REGISTRY/gooseek/webui:latest" \
|
||||
"$BACKEND_DIR/webui"
|
||||
|
||||
echo "=== Pushing webui to registry ==="
|
||||
docker push "$REGISTRY/gooseek/webui:$IMAGE_TAG"
|
||||
docker push "$REGISTRY/gooseek/webui:latest"
|
||||
|
||||
# Generate configmap/secrets from .env via envsubst
|
||||
echo ""
|
||||
echo "=== Generating K8s manifests from .env ==="
|
||||
if command -v envsubst &> /dev/null && [ -f "$ENV_FILE" ]; then
|
||||
envsubst < "$SCRIPT_DIR/configmap.yaml" > "$SCRIPT_DIR/_generated_configmap.yaml"
|
||||
kubectl apply -f "$SCRIPT_DIR/_generated_configmap.yaml" -n gooseek
|
||||
fi
|
||||
|
||||
# Apply kustomization
|
||||
@@ -32,20 +70,31 @@ echo "=== Applying K8s manifests ==="
|
||||
cd "$SCRIPT_DIR"
|
||||
kubectl apply -k .
|
||||
|
||||
# Rolling restart to pull new images
|
||||
echo ""
|
||||
echo "=== Rolling restart deployments ==="
|
||||
kubectl -n gooseek rollout restart deployment/api-gateway
|
||||
kubectl -n gooseek rollout restart deployment/webui
|
||||
kubectl -n gooseek rollout restart deployment/chat-svc
|
||||
kubectl -n gooseek rollout restart deployment/agent-svc
|
||||
kubectl -n gooseek rollout restart deployment/discover-svc
|
||||
kubectl -n gooseek rollout restart deployment/search-svc
|
||||
kubectl -n gooseek rollout restart deployment/learning-svc
|
||||
kubectl -n gooseek rollout restart deployment/medicine-svc
|
||||
kubectl -n gooseek rollout restart deployment/travel-svc
|
||||
kubectl -n gooseek rollout restart deployment/sandbox-svc
|
||||
|
||||
# Wait for rollout
|
||||
echo ""
|
||||
echo "=== Waiting for deployments ==="
|
||||
kubectl -n gooseek rollout status deployment/api-gateway --timeout=120s || true
|
||||
echo "=== Waiting for rollouts ==="
|
||||
kubectl -n gooseek rollout status deployment/api-gateway --timeout=180s || true
|
||||
kubectl -n gooseek rollout status deployment/chat-svc --timeout=120s || true
|
||||
kubectl -n gooseek rollout status deployment/agent-svc --timeout=120s || true
|
||||
kubectl -n gooseek rollout status deployment/discover-svc --timeout=120s || true
|
||||
kubectl -n gooseek rollout status deployment/search-svc --timeout=120s || true
|
||||
kubectl -n gooseek rollout status deployment/redis --timeout=60s || true
|
||||
|
||||
# Show status
|
||||
echo ""
|
||||
echo "=== Deployment Status ==="
|
||||
kubectl -n gooseek get pods
|
||||
kubectl -n gooseek get pods -o wide
|
||||
echo ""
|
||||
kubectl -n gooseek get svc
|
||||
echo ""
|
||||
@@ -53,4 +102,5 @@ kubectl -n gooseek get ingress
|
||||
|
||||
echo ""
|
||||
echo "=== Done ==="
|
||||
echo "API Gateway: http://localhost:3015 (NodePort) or via Ingress"
|
||||
echo "API: https://api.gooseek.ru"
|
||||
echo "Web: https://gooseek.ru"
|
||||
|
||||
44
backend/deploy/k8s/gitea-deployment.yaml
Normal file
44
backend/deploy/k8s/gitea-deployment.yaml
Normal file
@@ -0,0 +1,44 @@
|
||||
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
|
||||
env:
|
||||
- name: GITEA__database__DB_TYPE
|
||||
value: sqlite3
|
||||
- name: GITEA__server__DOMAIN
|
||||
value: git.gooseek.ru
|
||||
- name: GITEA__server__ROOT_URL
|
||||
value: https://git.gooseek.ru/
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "100m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: gitea-data
|
||||
@@ -4,7 +4,7 @@ metadata:
|
||||
name: gooseek-ingress
|
||||
namespace: gooseek
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-buffering: "off"
|
||||
@@ -14,9 +14,20 @@ spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- gooseek.ru
|
||||
- api.gooseek.ru
|
||||
secretName: gooseek-tls
|
||||
rules:
|
||||
- host: gooseek.ru
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: webui
|
||||
port:
|
||||
number: 3000
|
||||
- host: api.gooseek.ru
|
||||
http:
|
||||
paths:
|
||||
@@ -27,25 +38,3 @@ spec:
|
||||
name: api-gateway
|
||||
port:
|
||||
number: 3015
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: gooseek-ingress-local
|
||||
namespace: gooseek
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: localhost
|
||||
http:
|
||||
paths:
|
||||
- path: /api
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: api-gateway
|
||||
port:
|
||||
number: 3015
|
||||
|
||||
@@ -9,6 +9,7 @@ resources:
|
||||
- postgres.yaml
|
||||
- redis.yaml
|
||||
- api-gateway.yaml
|
||||
- webui.yaml
|
||||
- chat-svc.yaml
|
||||
- agent-svc.yaml
|
||||
- search-svc.yaml
|
||||
@@ -18,6 +19,11 @@ resources:
|
||||
- collection-svc.yaml
|
||||
- file-svc.yaml
|
||||
- thread-svc.yaml
|
||||
- learning-svc.yaml
|
||||
- medicine-svc.yaml
|
||||
- travel-svc.yaml
|
||||
- sandbox-svc.yaml
|
||||
- opensandbox.yaml
|
||||
- ingress.yaml
|
||||
|
||||
commonLabels:
|
||||
@@ -26,4 +32,8 @@ commonLabels:
|
||||
|
||||
images:
|
||||
- name: gooseek/backend
|
||||
newName: localhost:5000/gooseek/backend
|
||||
newTag: latest
|
||||
- name: gooseek/webui
|
||||
newName: localhost:5000/gooseek/webui
|
||||
newTag: latest
|
||||
|
||||
68
backend/deploy/k8s/learning-svc.yaml
Normal file
68
backend/deploy/k8s/learning-svc.yaml
Normal file
@@ -0,0 +1,68 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: learning-svc
|
||||
namespace: gooseek
|
||||
labels:
|
||||
app: learning-svc
|
||||
app.kubernetes.io/name: learning-svc
|
||||
app.kubernetes.io/part-of: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: learning-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: learning-svc
|
||||
spec:
|
||||
containers:
|
||||
- name: learning-svc
|
||||
image: gooseek/backend:latest
|
||||
env:
|
||||
- name: SERVICE
|
||||
value: "learning-svc"
|
||||
- name: PORT
|
||||
value: "3034"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: gooseek-config
|
||||
- secretRef:
|
||||
name: gooseek-secrets
|
||||
ports:
|
||||
- containerPort: 3034
|
||||
name: http
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3034
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3034
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 15
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: learning-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: learning-svc
|
||||
ports:
|
||||
- port: 3034
|
||||
targetPort: 3034
|
||||
name: http
|
||||
70
backend/deploy/k8s/medicine-svc.yaml
Normal file
70
backend/deploy/k8s/medicine-svc.yaml
Normal file
@@ -0,0 +1,70 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: medicine-svc
|
||||
namespace: gooseek
|
||||
labels:
|
||||
app: medicine-svc
|
||||
app.kubernetes.io/name: medicine-svc
|
||||
app.kubernetes.io/part-of: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: medicine-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: medicine-svc
|
||||
spec:
|
||||
containers:
|
||||
- name: medicine-svc
|
||||
image: gooseek/backend:latest
|
||||
env:
|
||||
- name: SERVICE
|
||||
value: "medicine-svc"
|
||||
- name: PORT
|
||||
value: "3037"
|
||||
- name: LLM_PROVIDER
|
||||
value: "timeweb"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: gooseek-config
|
||||
- secretRef:
|
||||
name: gooseek-secrets
|
||||
ports:
|
||||
- containerPort: 3037
|
||||
name: http
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3037
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3037
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 15
|
||||
resources:
|
||||
requests:
|
||||
cpu: 150m
|
||||
memory: 192Mi
|
||||
limits:
|
||||
cpu: 700m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: medicine-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: medicine-svc
|
||||
ports:
|
||||
- port: 3037
|
||||
targetPort: 3037
|
||||
name: http
|
||||
165
backend/deploy/k8s/opensandbox.yaml
Normal file
165
backend/deploy/k8s/opensandbox.yaml
Normal file
@@ -0,0 +1,165 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: gooseek-sandbox
|
||||
labels:
|
||||
app.kubernetes.io/part-of: gooseek
|
||||
purpose: user-sandboxes
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: opensandbox-sa
|
||||
namespace: gooseek
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: opensandbox-role
|
||||
namespace: gooseek-sandbox
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods", "pods/exec", "pods/log"]
|
||||
verbs: ["create", "get", "list", "watch", "delete"]
|
||||
- apiGroups: ["batch"]
|
||||
resources: ["jobs"]
|
||||
verbs: ["create", "get", "list", "watch", "delete"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: opensandbox-binding
|
||||
namespace: gooseek-sandbox
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: opensandbox-sa
|
||||
namespace: gooseek
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: opensandbox-role
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: sandbox-quota
|
||||
namespace: gooseek-sandbox
|
||||
spec:
|
||||
hard:
|
||||
requests.cpu: "8"
|
||||
requests.memory: "16Gi"
|
||||
limits.cpu: "16"
|
||||
limits.memory: "32Gi"
|
||||
pods: "50"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: LimitRange
|
||||
metadata:
|
||||
name: sandbox-limits
|
||||
namespace: gooseek-sandbox
|
||||
spec:
|
||||
limits:
|
||||
- default:
|
||||
cpu: "500m"
|
||||
memory: "512Mi"
|
||||
defaultRequest:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
max:
|
||||
cpu: "2"
|
||||
memory: "2Gi"
|
||||
type: Container
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: opensandbox-server
|
||||
namespace: gooseek
|
||||
labels:
|
||||
app: opensandbox-server
|
||||
app.kubernetes.io/name: opensandbox-server
|
||||
app.kubernetes.io/part-of: gooseek
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: opensandbox-server
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: opensandbox-server
|
||||
spec:
|
||||
serviceAccountName: opensandbox-sa
|
||||
containers:
|
||||
- name: opensandbox
|
||||
image: registry.cn-hangzhou.aliyuncs.com/open_sandbox/server:v1.0.1
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
env:
|
||||
- name: SANDBOX_NAMESPACE
|
||||
value: "gooseek-sandbox"
|
||||
- name: SANDBOX_DEFAULT_TIMEOUT
|
||||
value: "30m"
|
||||
- name: SANDBOX_MAX_CONCURRENT
|
||||
value: "20"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 512Mi
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 30
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 15
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: opensandbox-server
|
||||
namespace: gooseek
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: opensandbox-server
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 8080
|
||||
name: http
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: sandbox-isolation
|
||||
namespace: gooseek-sandbox
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/part-of: gooseek
|
||||
egress:
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/part-of: gooseek
|
||||
- to: []
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 443
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
78
backend/deploy/k8s/registry-with-auth.yaml
Normal file
78
backend/deploy/k8s/registry-with-auth.yaml
Normal file
@@ -0,0 +1,78 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: registry-auth
|
||||
namespace: gooseek
|
||||
type: Opaque
|
||||
stringData:
|
||||
htpasswd: |
|
||||
admin:$2y$05$A6oxuQhSjFObdjDsbjiWee.FJ62XQrc6BhLfzCMofY.9A/qQ050v6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: registry-config
|
||||
namespace: gooseek
|
||||
data:
|
||||
config.yml: |
|
||||
version: 0.1
|
||||
log:
|
||||
level: info
|
||||
storage:
|
||||
filesystem:
|
||||
rootdirectory: /var/lib/registry
|
||||
delete:
|
||||
enabled: true
|
||||
http:
|
||||
addr: :5000
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
auth:
|
||||
htpasswd:
|
||||
realm: GooSeek Registry
|
||||
path: /auth/htpasswd
|
||||
---
|
||||
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
|
||||
- name: registry-config
|
||||
mountPath: /etc/docker/registry
|
||||
- name: registry-auth
|
||||
mountPath: /auth
|
||||
resources:
|
||||
requests:
|
||||
memory: "64Mi"
|
||||
cpu: "50m"
|
||||
limits:
|
||||
memory: "256Mi"
|
||||
cpu: "200m"
|
||||
volumes:
|
||||
- name: registry-data
|
||||
persistentVolumeClaim:
|
||||
claimName: registry-pvc
|
||||
- name: registry-config
|
||||
configMap:
|
||||
name: registry-config
|
||||
- name: registry-auth
|
||||
secret:
|
||||
secretName: registry-auth
|
||||
70
backend/deploy/k8s/sandbox-svc.yaml
Normal file
70
backend/deploy/k8s/sandbox-svc.yaml
Normal file
@@ -0,0 +1,70 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sandbox-svc
|
||||
namespace: gooseek
|
||||
labels:
|
||||
app: sandbox-svc
|
||||
app.kubernetes.io/name: sandbox-svc
|
||||
app.kubernetes.io/part-of: gooseek
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: sandbox-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: sandbox-svc
|
||||
spec:
|
||||
containers:
|
||||
- name: sandbox-svc
|
||||
image: gooseek/backend:latest
|
||||
env:
|
||||
- name: SERVICE
|
||||
value: "sandbox-svc"
|
||||
- name: PORT
|
||||
value: "3036"
|
||||
- name: OPENSANDBOX_URL
|
||||
value: "http://opensandbox-server:8080"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: gooseek-config
|
||||
- secretRef:
|
||||
name: gooseek-secrets
|
||||
ports:
|
||||
- containerPort: 3036
|
||||
name: http
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3036
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3036
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 15
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 256Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: sandbox-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: sandbox-svc
|
||||
ports:
|
||||
- port: 3036
|
||||
targetPort: 3036
|
||||
name: http
|
||||
68
backend/deploy/k8s/travel-svc.yaml
Normal file
68
backend/deploy/k8s/travel-svc.yaml
Normal file
@@ -0,0 +1,68 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: travel-svc
|
||||
namespace: gooseek
|
||||
labels:
|
||||
app: travel-svc
|
||||
app.kubernetes.io/name: travel-svc
|
||||
app.kubernetes.io/part-of: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: travel-svc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: travel-svc
|
||||
spec:
|
||||
containers:
|
||||
- name: travel-svc
|
||||
image: gooseek/backend:latest
|
||||
env:
|
||||
- name: SERVICE
|
||||
value: "travel-svc"
|
||||
- name: PORT
|
||||
value: "3035"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: gooseek-config
|
||||
- secretRef:
|
||||
name: gooseek-secrets
|
||||
ports:
|
||||
- containerPort: 3035
|
||||
name: http
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3035
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 3035
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 15
|
||||
resources:
|
||||
requests:
|
||||
cpu: 150m
|
||||
memory: 192Mi
|
||||
limits:
|
||||
cpu: 700m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: travel-svc
|
||||
namespace: gooseek
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: travel-svc
|
||||
ports:
|
||||
- port: 3035
|
||||
targetPort: 3035
|
||||
name: http
|
||||
63
backend/deploy/k8s/webui.yaml
Normal file
63
backend/deploy/k8s/webui.yaml
Normal file
@@ -0,0 +1,63 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: webui
|
||||
namespace: gooseek
|
||||
labels:
|
||||
app: webui
|
||||
app.kubernetes.io/name: webui
|
||||
app.kubernetes.io/part-of: gooseek
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: webui
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: webui
|
||||
spec:
|
||||
containers:
|
||||
- name: webui
|
||||
image: gooseek/webui:latest
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
name: http
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: gooseek-config
|
||||
- secretRef:
|
||||
name: gooseek-secrets
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 3000
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 3000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 512Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: webui
|
||||
namespace: gooseek
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: webui
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
name: http
|
||||
49
backend/deploy/scripts/README-nvidia-cuda.md
Normal file
49
backend/deploy/scripts/README-nvidia-cuda.md
Normal 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
|
||||
14
backend/deploy/scripts/gitea-runner.service
Normal file
14
backend/deploy/scripts/gitea-runner.service
Normal 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
|
||||
55
backend/deploy/scripts/install-cicd-stack.sh
Normal file
55
backend/deploy/scripts/install-cicd-stack.sh
Normal 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
|
||||
248
backend/deploy/scripts/install-gitea-manifest.sh
Normal file
248
backend/deploy/scripts/install-gitea-manifest.sh
Normal 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"
|
||||
130
backend/deploy/scripts/install-gitea-registry.sh
Normal file
130
backend/deploy/scripts/install-gitea-registry.sh
Normal 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"
|
||||
65
backend/deploy/scripts/setup-gitea-runner.sh
Normal file
65
backend/deploy/scripts/setup-gitea-runner.sh
Normal 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"
|
||||
60
backend/deploy/scripts/setup-k3s-cicd.sh
Normal file
60
backend/deploy/scripts/setup-k3s-cicd.sh
Normal 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
|
||||
73
backend/deploy/scripts/setup-nvidia-cuda-ubuntu24.sh
Normal file
73
backend/deploy/scripts/setup-nvidia-cuda-ubuntu24.sh
Normal 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"
|
||||
Reference in New Issue
Block a user