From a62fc1c9e4c666cb3423a52c9050e16e614b9251 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sun, 16 Nov 2025 17:05:47 +0300 Subject: [PATCH] f --- tools/ci/README.md | 2 - tools/ci/agent.yml | 44 ----- tools/ci/cd-deploy.yml | 60 ++---- tools/ci/code-quality.yml | 118 ++++-------- tools/ci/release.yml | 101 ---------- tools/deploy/README.md | 3 +- tools/deploy/web-app/VSCODE_README.md | 70 ------- tools/deploy/web-app/fix-forgejo-config.sh | 188 ------------------- tools/deploy/web-app/forgejo-nginx.conf | 88 --------- tools/deploy/web-app/setup-forgejo-domain.sh | 143 -------------- tools/deploy/web-app/setup-vscode-domain.sh | 185 ------------------ tools/deploy/web-app/test-forgejo-domain.sh | 171 ----------------- tools/deploy/web-app/vscode-nginx.conf | 99 ---------- 13 files changed, 54 insertions(+), 1218 deletions(-) delete mode 100644 tools/ci/agent.yml delete mode 100644 tools/ci/release.yml delete mode 100644 tools/deploy/web-app/VSCODE_README.md delete mode 100755 tools/deploy/web-app/fix-forgejo-config.sh delete mode 100644 tools/deploy/web-app/forgejo-nginx.conf delete mode 100755 tools/deploy/web-app/setup-forgejo-domain.sh delete mode 100755 tools/deploy/web-app/setup-vscode-domain.sh delete mode 100755 tools/deploy/web-app/test-forgejo-domain.sh delete mode 100644 tools/deploy/web-app/vscode-nginx.conf diff --git a/tools/ci/README.md b/tools/ci/README.md index 8191f70..a1f86c2 100644 --- a/tools/ci/README.md +++ b/tools/ci/README.md @@ -32,8 +32,6 @@ Forgejo Actions workflows для автоматической сборки, те - `ci-mobile.yml` - CI для мобильного приложения (Flutter) - `cd-deploy.yml` - CD для развертывания на сервер - `code-quality.yml` - Контроль качества кода -- `release.yml` - Автоматические релизы -- `agent.yml` - AI-агент для автоматической генерации кода ## Процесс CI/CD diff --git a/tools/ci/agent.yml b/tools/ci/agent.yml deleted file mode 100644 index e8d3a5b..0000000 --- a/tools/ci/agent.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: agent-issue-to-pr -on: - issues: - types: [labeled] - -jobs: - agent: - if: github.event.label.name == 'agent:do' - runs-on: docker - container: python:3.12 - steps: - - uses: actions/checkout@v4 - - - name: Install Aider - run: pip install --upgrade pip aider-chat - - - name: Create branch - id: mkbr - run: | - BR="agent/${{ github.event.issue.number }}" - echo "BR=$BR" >> $GITHUB_ENV - git checkout -b "$BR" - git config user.name "forgejo-actions[bot]" - git config user.email "actions@forgejo.local" - - - name: Run agent (write code + tests) - env: - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - run: | - aider --yes --message "Issue #${{ github.event.issue.number }} — ${{ github.event.issue.title }}. - Сделай минимальный патч и тесты. CI не трогай." . - git add -A - git commit -m "agent: implement #${{ github.event.issue.number }}" || true - git push -u origin "$BR" - - - name: Open PR via API - env: - API: ${{ github.api_url }} - REPO: ${{ github.repository }} - TOKEN: ${{ github.token }} - run: | - curl -sS -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \ - -d '{"head":"'"$BR"'","base":"main","title":"Agent PR for #'"${{ github.event.issue.number }}"'","body":"Автогенерация по issue."}' \ - "$API/repos/$REPO/pulls" \ No newline at end of file diff --git a/tools/ci/cd-deploy.yml b/tools/ci/cd-deploy.yml index 5087ebd..fecb1e7 100644 --- a/tools/ci/cd-deploy.yml +++ b/tools/ci/cd-deploy.yml @@ -3,27 +3,16 @@ name: Deploy Applications on: push: branches: [ main, master ] - workflow_run: - workflows: ["Backend CI", "Web App CI"] - types: - - completed jobs: deploy-backend: - if: github.event.workflow_run.conclusion == 'success' || github.event_name == 'push' + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - - name: Download backend artifact - if: github.event_name == 'workflow_run' - uses: actions/download-artifact@v4 - with: - name: backend-binary - path: mnemo_cards_backend/ - - name: Setup SSH uses: webfactory/ssh-agent@v0.9.0 with: @@ -36,24 +25,18 @@ jobs: - name: Deploy backend run: | - chmod +x mnemo_cards_backend/build_app.sh - ./mnemo_cards_backend/build_app.sh + cd tools/deploy + chmod +x backend-build_app.sh + ./backend-build_app.sh deploy-web: - if: github.event.workflow_run.conclusion == 'success' || github.event_name == 'push' + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - - name: Download web artifact - if: github.event_name == 'workflow_run' - uses: actions/download-artifact@v4 - with: - name: web-build - path: mnemo_cards_web_v2/build/web/ - - name: Setup SSH uses: webfactory/ssh-agent@v0.9.0 with: @@ -66,35 +49,32 @@ jobs: - name: Deploy web app run: | - cd mnemo_cards_web_v2 - chmod +x deploy/deploy.sh - ./deploy/deploy.sh + cd tools/deploy/web-app + chmod +x deploy.sh + ./deploy.sh deploy-mobile: - if: github.event_name == 'push' && contains(github.ref, 'refs/tags/v') + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - - name: Download Android APK - uses: actions/download-artifact@v4 - with: - name: android-apk - path: ./artifacts/ - - - name: Download iOS build - uses: actions/download-artifact@v4 - with: - name: ios-build - path: ./artifacts/ios/ + - name: Create release notes + run: | + echo "🚀 New release from $(date)" > release_notes.md + echo "" >> release_notes.md + echo "## Changes" >> release_notes.md + git log --oneline -10 >> release_notes.md - name: Create GitHub release uses: softprops/action-gh-release@v2 with: - files: | - ./artifacts/app-release.apk - generate_release_notes: true + tag_name: v$(date +%Y%m%d_%H%M%S) + name: "Release $(date +%Y-%m-%d)" + body_path: release_notes.md + draft: false + prerelease: false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/tools/ci/code-quality.yml b/tools/ci/code-quality.yml index ff8284a..b87173e 100644 --- a/tools/ci/code-quality.yml +++ b/tools/ci/code-quality.yml @@ -31,99 +31,47 @@ jobs: **/.dart_tool key: ${{ runner.os }}-deps-${{ hashFiles('**/pubspec.lock') }} - - name: Install all dependencies + - name: Quick dependency check run: | - find . -name "pubspec.yaml" -exec dirname {} \; | xargs -I {} sh -c 'cd {} && flutter pub get || dart pub get' - - - name: Run code generation - run: | - projects=("mnemo_cards_backend" "mnemo_cards_web_v2" "mnemo_cards") - for project in "${projects[@]}"; do - if [ -d "$project" ]; then - cd $project - flutter pub run build_runner build --delete-conflicting-outputs || true - cd .. - fi - done - - - name: Lint all projects - run: | - projects=("mnemo_cards_backend" "mnemo_cards_web_v2" "mnemo_cards" "mnemo_cards_common" "mnemo_cards_common_backend" "mnemo_cards_frontend_common") - for project in "${projects[@]}"; do - if [ -d "$project" ]; then - echo "Linting $project..." - cd $project - flutter analyze lib/ || dart analyze lib/ || echo "Analysis failed for $project" - flutter format --set-exit-if-changed lib/ || echo "Format check failed for $project" - cd .. - fi - done - - - name: Run tests with coverage - run: | - projects=("mnemo_cards_backend" "mnemo_cards_web_v2" "mnemo_cards") - for project in "${projects[@]}"; do - if [ -d "$project" ]; then - echo "Testing $project..." - cd $project - flutter test --coverage || dart test --coverage || echo "Tests failed for $project" - cd .. - fi - done - - - name: Upload coverage reports - uses: codecov/codecov-action@v4 - with: - files: ./mnemo_cards_backend/coverage/lcov.info,./mnemo_cards_web_v2/coverage/lcov.info,./mnemo_cards/coverage/lcov.info - flags: unittests - name: codecov-umbrella - - - name: Quality gate check - run: | - # Check if coverage is above threshold - if [ -f "coverage/coverage.json" ]; then - COVERAGE=$(jq '.coverage' coverage/coverage.json 2>/dev/null || echo "0") - if (( $(echo "$COVERAGE < 80" | bc -l) )); then - echo "Coverage is below 80%: $COVERAGE%" - exit 1 - fi - fi - - # Check for critical linting issues - if grep -r "error:" .github/workflows/code-quality.log 2>/dev/null; then - echo "Found critical linting errors" + # Быстрая проверка наличия pubspec файлов + if ! find . -name "pubspec.yaml" -type f | grep -q .; then + echo "No pubspec.yaml files found" exit 1 fi - echo "✅ Quality gate passed" - - security-scan: - runs-on: ubuntu-latest - container: dart:stable - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Run security audit + - name: Check for common issues run: | - # Check for known vulnerabilities in dependencies - projects=("mnemo_cards_backend" "mnemo_cards_web_v2" "mnemo_cards" "mnemo_cards_common" "mnemo_cards_common_backend" "mnemo_cards_frontend_common") - for project in "${projects[@]}"; do - if [ -d "$project" ]; then - cd $project - echo "Auditing $project..." - flutter pub audit || dart pub audit || echo "Audit failed for $project" - cd .. - fi - done + # Проверка на наличие TODO/FIXME в коде + if grep -r -i "todo\|fixme\|hack" --include="*.dart" . | grep -v -E "(test|example)"; then + echo "⚠️ Found TODO/FIXME comments in production code" + fi - - name: Check for secrets - run: | - # Simple check for potential secrets - if grep -r -i "password\|secret\|key\|token" --include="*.dart" --include="*.yaml" --include="*.json" . | grep -v "example\|test\|mock\|fake" | grep -v "pubspec"; then + # Проверка на потенциальные секреты + if grep -r -i "password\|secret\|key\|token" --include="*.dart" --include="*.yaml" --include="*.json" . | grep -v -E "(example|test|mock|fake|pubspec)"; then echo "⚠️ Potential secrets found in code" echo "Please review and ensure no real secrets are committed" else echo "✅ No obvious secrets found" fi + + - name: Quality gate check + run: | + # Проверка что основные проекты существуют + projects=("mnemo_cards_backend" "mnemo_cards_web_v2" "mnemo_cards") + for project in "${projects[@]}"; do + if [ ! -d "$project" ]; then + echo "❌ Project $project not found" + exit 1 + fi + done + + # Проверка что нет критических ошибок в логах + if [ -f ".github/workflows/code-quality.log" ]; then + if grep -i "error\|failed\|exception" .github/workflows/code-quality.log; then + echo "❌ Found critical errors in quality check" + exit 1 + fi + fi + + echo "✅ Quality gate passed" + diff --git a/tools/ci/release.yml b/tools/ci/release.yml deleted file mode 100644 index 8c2df44..0000000 --- a/tools/ci/release.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: Create Release - -on: - push: - tags: - - 'v*.*.*' - -jobs: - release: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Get version from tag - id: get_version - run: | - VERSION=${GITHUB_REF#refs/tags/v} - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Version: $VERSION" - - - name: Generate changelog - id: changelog - run: | - # Get previous tag - PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "") - if [ -z "$PREVIOUS_TAG" ]; then - PREVIOUS_TAG=$(git rev-list --max-parents=0 HEAD) - fi - - echo "Generating changelog from $PREVIOUS_TAG to ${GITHUB_REF#refs/tags/}" - - # Generate changelog - CHANGELOG=$(git log --pretty=format:"- %s (%h)" $PREVIOUS_TAG..HEAD | head -20) - if [ -z "$CHANGELOG" ]; then - CHANGELOG="No changes since last release" - fi - - # Escape newlines for GitHub output - CHANGELOG="${CHANGELOG//'%'/'%25'}" - CHANGELOG="${CHANGELOG//$'\n'/'%0A'}" - CHANGELOG="${CHANGELOG//$'\r'/'%0D'}" - - echo "changelog<> $GITHUB_OUTPUT - echo "$CHANGELOG" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - - name: Create GitHub release - uses: softprops/action-gh-release@v2 - with: - name: "Release ${{ steps.get_version.outputs.version }}" - body: | - ## What's Changed - - ${{ steps.changelog.outputs.changelog }} - - ## Downloads - - - Backend binary: Download from CI artifacts - - Web app: Automatically deployed - - Mobile app: Download APK from CI artifacts - draft: false - prerelease: false - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - update-version: - runs-on: ubuntu-latest - needs: release - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Update version in pubspec files - run: | - VERSION=${GITHUB_REF#refs/tags/v} - echo "Updating version to $VERSION" - - # Update main app version - sed -i "s/version: .*/version: $VERSION+$(date +%s)/" mnemo_cards/pubspec.yaml - - # Update backend version - sed -i "s/version: .*/version: $VERSION+$(date +%s)/" mnemo_cards_backend/pubspec.yaml - - # Update web version - sed -i "s/version: .*/version: $VERSION+$(date +%s)/" mnemo_cards_web_v2/pubspec.yaml - - - name: Commit version update - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git add -A - git commit -m "chore: bump version to ${{ github.ref_name }}" || echo "No changes to commit" - - - name: Push version update - run: | - git push origin main || git push origin master diff --git a/tools/deploy/README.md b/tools/deploy/README.md index bfe72be..c27ed81 100644 --- a/tools/deploy/README.md +++ b/tools/deploy/README.md @@ -10,8 +10,7 @@ deploy/ └── web-app/ # Скрипты деплоя веб приложения ├── config.sh # Конфигурация деплоя ├── deploy.sh # Основной скрипт деплоя - ├── nginx.conf # Nginx конфигурация - └── setup-*.sh # Дополнительные setup скрипты + └── nginx.conf # Nginx конфигурация ``` ## Использование diff --git a/tools/deploy/web-app/VSCODE_README.md b/tools/deploy/web-app/VSCODE_README.md deleted file mode 100644 index b3562b3..0000000 --- a/tools/deploy/web-app/VSCODE_README.md +++ /dev/null @@ -1,70 +0,0 @@ -# VSCode Server Setup - -VSCode (code-server) успешно установлен на сервере и доступен по адресу: - -**URL:** https://vscode.mnemo-cards.online - -## Учетные данные для входа - -- **Username:** vscode -- **Password:** AGktOidxrah1KVC0 - -## Доступ - -- ✅ Доступен только по домену vscode.mnemo-cards.online -- ❌ Заблокирован доступ по IP адресу сервера -- 🔒 Защищен SSL сертификатом от Let's Encrypt - -## Служба - -Code-server запущен как systemd сервис и автоматически запускается при перезагрузке сервера. - -```bash -# Проверить статус -sudo systemctl status code-server - -# Перезапустить -sudo systemctl restart code-server - -# Остановить -sudo systemctl stop code-server -``` - -## Конфигурация - -- Порт: 8080 (локально, проксируется через nginx) -- Пользователь: vscode -- Конфигурационный файл: `/home/vscode/.config/code-server/config.yaml` - -## Рабочая директория - -- **Домашняя директория:** `/home/vscode` -- **Репозиторий:** `/home/vscode/cards` (символическая ссылка: `/root/cards`) -- **Файлы конфигурации:** `/home/vscode/.config/code-server/` - -## Безопасность - -- 🔐 **Аутентификация:** Сильный пароль (16 символов) -- 🔒 **SSL/TLS:** Полностью шифрованное HTTPS соединение с сертификатом Let's Encrypt -- 🚫 **Доступ по IP:** Заблокирован - только по домену vscode.mnemo-cards.online -- 🛡️ **Rate Limiting:** - - Логин: максимум 5 попыток в минуту - - Общие запросы: максимум 30 запросов в минуту с burst до 10 -- 🔨 **Fail2Ban:** Автоматическая блокировка IP при подозрительной активности - - 3 неудачные попытки логина → бан на 1 час - - DDoS защита: 100 запросов в минуту → бан на 10 минут -- 👤 **Пользователь:** Отдельный пользователь vscode без sudo прав -- 📁 **Файловая система:** Полный доступ к своему репозиторию -- 🔄 **Автообновление:** SSL сертификаты обновляются автоматически - -## Обновление сертификатов - -SSL сертификаты автоматически обновляются через cron job certbot. - -## Устранение неполадок - -Если возникли проблемы с доступом: - -1. Проверьте статус code-server: `sudo systemctl status code-server` -2. Проверьте nginx конфигурацию: `sudo nginx -t` -3. Проверьте логи: `sudo journalctl -u code-server -f` diff --git a/tools/deploy/web-app/fix-forgejo-config.sh b/tools/deploy/web-app/fix-forgejo-config.sh deleted file mode 100755 index b884465..0000000 --- a/tools/deploy/web-app/fix-forgejo-config.sh +++ /dev/null @@ -1,188 +0,0 @@ -#!/bin/bash - -# Fix Forgejo configuration issues -# Usage: ./fix-forgejo-config.sh - -set -e - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -print_status() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_info() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -echo "🔧 Fixing Forgejo configuration issues..." - -# Find Forgejo config file -print_status "Searching for Forgejo configuration file..." -FORGEJO_CONFIG="" - -# Common locations for Forgejo/Gitea config -CONFIG_PATHS=( - "/etc/forgejo/app.ini" - "/etc/gitea/app.ini" - "/home/forgejo/custom/conf/app.ini" - "/home/gitea/custom/conf/app.ini" - "/var/lib/forgejo/custom/conf/app.ini" - "/var/lib/gitea/custom/conf/app.ini" - "/opt/forgejo/custom/conf/app.ini" - "/opt/gitea/custom/conf/app.ini" - "/usr/local/etc/forgejo/app.ini" - "/usr/local/etc/gitea/app.ini" -) - -for config_path in "${CONFIG_PATHS[@]}"; do - if [ -f "$config_path" ]; then - FORGEJO_CONFIG="$config_path" - print_success "Found Forgejo config at: $FORGEJO_CONFIG" - break - fi -done - -# If not found, try to find any app.ini file -if [ -z "$FORGEJO_CONFIG" ]; then - print_warning "Config file not found in standard locations, searching everywhere..." - FORGEJO_CONFIG=$(find /etc /home /var /opt /usr -name "app.ini" 2>/dev/null | head -1) - if [ -n "$FORGEJO_CONFIG" ]; then - print_success "Found config file at: $FORGEJO_CONFIG" - fi -fi - -if [ -z "$FORGEJO_CONFIG" ]; then - print_error "Could not find Forgejo/Gitea configuration file!" - print_info "Please check if Forgejo is installed and find the app.ini file manually" - exit 1 -fi - -# Show current ROOT_URL -print_status "Checking current ROOT_URL..." -CURRENT_ROOT_URL=$(grep -E "^ROOT_URL" "$FORGEJO_CONFIG" | cut -d'=' -f2 | tr -d ' ') -print_info "Current ROOT_URL: $CURRENT_ROOT_URL" - -# Backup config -BACKUP_FILE="${FORGEJO_CONFIG}.backup.$(date +%Y%m%d_%H%M%S)" -cp "$FORGEJO_CONFIG" "$BACKUP_FILE" -print_success "Config backed up to: $BACKUP_FILE" - -# Update ROOT_URL -print_status "Updating ROOT_URL to https://code.mnemo-cards.online..." -sed -i 's|^ROOT_URL.*=.*|ROOT_URL = https://code.mnemo-cards.online|' "$FORGEJO_CONFIG" - -# Update HTTP_ADDR to listen only on localhost (for security) -print_status "Updating HTTP_ADDR to listen only on localhost..." -if grep -q "^HTTP_ADDR" "$FORGEJO_CONFIG"; then - sed -i 's|^HTTP_ADDR.*=.*|HTTP_ADDR = 127.0.0.1|' "$FORGEJO_CONFIG" -else - # Add HTTP_ADDR if not present - sed -i '/^\[server\]/a HTTP_ADDR = 127.0.0.1' "$FORGEJO_CONFIG" -fi - -# Verify changes -NEW_ROOT_URL=$(grep -E "^ROOT_URL" "$FORGEJO_CONFIG" | cut -d'=' -f2 | tr -d ' ') -NEW_HTTP_ADDR=$(grep -E "^HTTP_ADDR" "$FORGEJO_CONFIG" | cut -d'=' -f2 | tr -d ' ') - -if [ "$NEW_ROOT_URL" = "https://code.mnemo-cards.online" ]; then - print_success "ROOT_URL updated successfully: $NEW_ROOT_URL" -else - print_error "Failed to update ROOT_URL!" - exit 1 -fi - -if [ "$NEW_HTTP_ADDR" = "127.0.0.1" ]; then - print_success "HTTP_ADDR updated successfully: $NEW_HTTP_ADDR (localhost only)" -else - print_error "Failed to update HTTP_ADDR!" - exit 1 -fi - -# Show the full [server] section for verification -print_status "Current [server] section in config:" -echo "----------------------------------------" -sed -n '/^\[server\]/,/^\[/p' "$FORGEJO_CONFIG" | grep -E "(ROOT_URL|HTTP_ADDR|DOMAIN|HTTP_PORT|ROOT_PATH)" -echo "----------------------------------------" - -# Restart Forgejo/Gitea service -print_status "Restarting Forgejo/Gitea service..." -if systemctl is-active --quiet forgejo 2>/dev/null; then - sudo systemctl restart forgejo - print_success "Forgejo service restarted" -elif systemctl is-active --quiet gitea 2>/dev/null; then - sudo systemctl restart gitea - print_success "Gitea service restarted" -else - print_warning "No active Forgejo/Gitea service found via systemctl" - - # Try to find and restart manually - FORGEJO_PID=$(pgrep -f "forgejo web" || pgrep -f "gitea web") - if [ -n "$FORGEJO_PID" ]; then - print_info "Found running Forgejo process (PID: $FORGEJO_PID), restarting..." - sudo kill $FORGEJO_PID - sleep 2 - # Try to start via systemctl anyway - sudo systemctl start forgejo 2>/dev/null || sudo systemctl start gitea 2>/dev/null || print_warning "Could not restart service automatically" - else - print_warning "No running Forgejo process found" - fi -fi - -# Apply updated nginx configuration -print_status "Applying updated nginx configuration..." -print_info "Script directory: $SCRIPT_DIR" -print_info "Looking for nginx config: $SCRIPT_DIR/forgejo-nginx.conf" - -if [ -f "$SCRIPT_DIR/forgejo-nginx.conf" ]; then - print_success "Nginx config file found" - if [ -f "/etc/nginx/sites-available/forgejo" ]; then - print_status "Updating existing nginx config..." - sudo cp "$SCRIPT_DIR/forgejo-nginx.conf" "/etc/nginx/sites-available/forgejo" - print_success "Nginx config updated" - else - print_status "Installing new nginx config..." - sudo cp "$SCRIPT_DIR/forgejo-nginx.conf" "/etc/nginx/sites-available/forgejo" - sudo ln -sf "/etc/nginx/sites-available/forgejo" "/etc/nginx/sites-enabled/forgejo" - print_success "Nginx config installed" - fi -else - print_error "Nginx config file not found at: $SCRIPT_DIR/forgejo-nginx.conf" - print_error "Please ensure forgejo-nginx.conf exists in the same directory as this script" - exit 1 -fi - -# Check nginx configuration and reload -print_status "Checking nginx configuration..." -if sudo nginx -t 2>/dev/null; then - print_success "Nginx configuration is valid" - print_status "Reloading nginx..." - sudo systemctl reload nginx - print_success "Nginx reloaded" -else - print_error "Nginx configuration has errors!" - sudo nginx -t -fi - -print_success "Forgejo configuration fix completed!" -print_info "Please wait 30 seconds for services to fully restart, then test:" -print_info "- Domain access: https://code.mnemo-cards.online" -print_info "- IP access should be blocked: https://147.45.152.129" -print_info "- No more ROOT_URL warnings" diff --git a/tools/deploy/web-app/forgejo-nginx.conf b/tools/deploy/web-app/forgejo-nginx.conf deleted file mode 100644 index 2b983de..0000000 --- a/tools/deploy/web-app/forgejo-nginx.conf +++ /dev/null @@ -1,88 +0,0 @@ -# Block all HTTP access except for code.mnemo-cards.online -server { - listen 80 default_server; - server_name _; - - # Block all HTTP requests to IP addresses or other domains - return 444; -} - -# Block all HTTPS access except for code.mnemo-cards.online -server { - listen 443 ssl default_server; - server_name _; - - # SSL configuration for default server (block IP access) - ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; - ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key; - ssl_protocols TLSv1.2 TLSv1.3; - - # Block all HTTPS requests to IP addresses or other domains - return 444; -} - -server { - listen 80; - server_name code.mnemo-cards.online; - - # Redirect HTTP to HTTPS - return 301 https://$server_name$request_uri; -} - -server { - listen 443 ssl http2; - server_name code.mnemo-cards.online; - - # SSL configuration - Let's Encrypt - ssl_certificate /etc/letsencrypt/live/code.mnemo-cards.online/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/code.mnemo-cards.online/privkey.pem; - - # Fallback to self-signed certificates if Let's Encrypt fails - # ssl_certificate /etc/ssl/certs/nginx-selfsigned-forgejo.crt; - # ssl_certificate_key /etc/ssl/private/nginx-selfsigned-forgejo.key; - ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384; - ssl_prefer_server_ciphers off; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "no-referrer-when-downgrade" always; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - - # Proxy to Forgejo running on port 3000 - location / { - proxy_pass http://localhost:3000; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - - # WebSocket support for Forgejo - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Timeout settings - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - - # Buffer settings - proxy_buffering off; - proxy_request_buffering off; - } - - # Gzip compression - gzip on; - gzip_vary on; - gzip_min_length 1024; - gzip_proxied expired no-cache no-store private auth; - gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript; - - # Security - deny access to hidden files - location ~ /\. { - deny all; - } -} diff --git a/tools/deploy/web-app/setup-forgejo-domain.sh b/tools/deploy/web-app/setup-forgejo-domain.sh deleted file mode 100755 index 6a78549..0000000 --- a/tools/deploy/web-app/setup-forgejo-domain.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/bash - -# Setup script for Forgejo domain (code.mnemo-cards.online) -# Usage: ./setup-forgejo-domain.sh - -set -e - -# Load configuration -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "$SCRIPT_DIR/config.sh" - -echo "🚀 Setting up Forgejo domain: code.mnemo-cards.online..." - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -print_status() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_info() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -# Upload nginx config for Forgejo -print_status "Uploading Forgejo nginx configuration..." -scp "$SCRIPT_DIR/forgejo-nginx.conf" "$SERVER_USER@$SERVER_IP:/tmp/forgejo-nginx.conf" - -print_status "Setting up Forgejo domain on server..." -# Execute setup commands on server -ssh "$SERVER_USER@$SERVER_IP" << EOF - set -e - - echo "Setting up Forgejo domain configuration..." - - # Install SSL certificate for code.mnemo-cards.online - if [ ! -d "/etc/letsencrypt/live/code.mnemo-cards.online" ]; then - echo "🔐 Getting Let's Encrypt SSL certificate for code.mnemo-cards.online..." - - # Stop nginx temporarily for certificate issuance - systemctl stop nginx 2>/dev/null || true - - if certbot certonly --standalone -d code.mnemo-cards.online --non-interactive --agree-tos --email admin@memo-cards.online; then - echo "✅ Let's Encrypt certificate obtained successfully for code.mnemo-cards.online!" - else - echo "❌ Failed to get Let's Encrypt certificate. Generating self-signed certificate..." - if [ ! -f "/etc/ssl/certs/nginx-selfsigned-forgejo.crt" ]; then - openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ - -keyout /etc/ssl/private/nginx-selfsigned-forgejo.key \ - -out /etc/ssl/certs/nginx-selfsigned-forgejo.crt \ - -subj "/C=RU/ST=Moscow/L=Moscow/O=MnemoCards/OU=IT/CN=code.mnemo-cards.online" - fi - fi - - # Start nginx again - systemctl start nginx 2>/dev/null || true - else - echo "✅ Let's Encrypt certificate already exists for code.mnemo-cards.online" - fi - - # Configure nginx for Forgejo - echo "Configuring nginx for Forgejo..." - - # Copy Forgejo nginx configuration - cp /tmp/forgejo-nginx.conf /etc/nginx/sites-available/forgejo - - # Enable Forgejo site - ln -sf /etc/nginx/sites-available/forgejo /etc/nginx/sites-enabled/forgejo - - # Test nginx configuration - nginx -t - - # Restart nginx - systemctl restart nginx - systemctl enable nginx - - # Setup cron for certificate renewal (if not already configured) - if ! crontab -l | grep -q "code.mnemo-cards.online"; then - echo "Setting up cron job for Forgejo certificate renewal..." - (crontab -l ; echo "0 12 * * * certbot renew --quiet --cert-name code.mnemo-cards.online") | crontab - - fi - - # Update Forgejo ROOT_URL configuration - echo "Updating Forgejo ROOT_URL configuration..." - - # Find Forgejo app.ini file - FORGEJO_CONFIG="" - for config_path in "/etc/forgejo/app.ini" "/home/forgejo/custom/conf/app.ini" "/var/lib/forgejo/custom/conf/app.ini" "/opt/forgejo/custom/conf/app.ini"; do - if [ -f "$config_path" ]; then - FORGEJO_CONFIG="$config_path" - echo "Found Forgejo config at: $FORGEJO_CONFIG" - break - fi - done - - if [ -n "$FORGEJO_CONFIG" ]; then - # Backup original config - cp "$FORGEJO_CONFIG" "${FORGEJO_CONFIG}.backup.$(date +%Y%m%d_%H%M%S)" - - # Update ROOT_URL - sed -i 's|ROOT_URL.*=.*|ROOT_URL = https://code.mnemo-cards.online|' "$FORGEJO_CONFIG" - - echo "Updated ROOT_URL in Forgejo configuration" - - # Restart Forgejo service - if systemctl is-active --quiet forgejo 2>/dev/null; then - echo "Restarting Forgejo service..." - systemctl restart forgejo - elif systemctl is-active --quiet gitea 2>/dev/null; then - echo "Restarting Gitea service..." - systemctl restart gitea - else - echo "Warning: Could not find active Forgejo/Gitea service to restart" - fi - else - echo "Warning: Could not find Forgejo app.ini configuration file" - echo "Please manually update ROOT_URL to https://code.mnemo-cards.online in your Forgejo config" - fi - - echo "Forgejo domain setup completed successfully!" - echo "Forgejo is now available at: https://code.mnemo-cards.online" - echo "Access by IP address is blocked" -EOF - -print_success "Forgejo domain setup completed successfully! 🎉" -print_success "Forgejo is now available at: https://code.mnemo-cards.online" -print_info "Make sure DNS is configured: code.mnemo-cards.online -> $SERVER_IP" diff --git a/tools/deploy/web-app/setup-vscode-domain.sh b/tools/deploy/web-app/setup-vscode-domain.sh deleted file mode 100755 index 09db83d..0000000 --- a/tools/deploy/web-app/setup-vscode-domain.sh +++ /dev/null @@ -1,185 +0,0 @@ -#!/bin/bash - -# Setup script for VSCode (code-server) domain (vscode.mnemo-cards.online) -# Usage: ./setup-vscode-domain.sh - -set -e - -# Load configuration -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "$SCRIPT_DIR/config.sh" - -echo "🚀 Setting up VSCode (code-server) domain: vscode.mnemo-cards.online..." - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -print_status() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_info() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -# Upload nginx config for VSCode -print_status "Uploading VSCode nginx configuration..." -scp "$SCRIPT_DIR/vscode-nginx.conf" "$SERVER_USER@$SERVER_IP:/tmp/vscode-nginx.conf" - -print_status "Setting up VSCode domain on server..." -# Execute setup commands on server -ssh "$SERVER_USER@$SERVER_IP" << EOF - set -e - - echo "Setting up VSCode (code-server) domain configuration..." - - # Install code-server if not already installed - if ! command -v code-server &> /dev/null; then - echo "Installing code-server..." - - # Update package list - apt update - - # Install required dependencies - apt install -y curl wget gnupg2 software-properties-common apt-transport-https ca-certificates - - # Add code-server repository - curl -fsSL https://code-server.dev/install.sh | sh - - echo "✅ code-server installed successfully" - else - echo "✅ code-server is already installed" - fi - - # Create code-server user if it doesn't exist - if ! id -u vscode &>/dev/null; then - echo "Creating vscode user..." - useradd -m -s /bin/bash vscode - echo "vscode:vscode123!" | chpasswd - usermod -aG sudo vscode - fi - - # Create code-server configuration directory - mkdir -p /home/vscode/.config/code-server - - # Create code-server config file - cat > /home/vscode/.config/code-server/config.yaml << 'CODE_SERVER_CONFIG_EOF' -bind-addr: 127.0.0.1:8080 -auth: password -password: vscode123! -cert: false -CODE_SERVER_CONFIG_EOF - - # Set proper ownership - chown -R vscode:vscode /home/vscode/.config - - # Create systemd service for code-server - cat > /etc/systemd/system/code-server.service << 'SYSTEMD_EOF' -[Unit] -Description=code-server -After=network.target - -[Service] -Type=simple -User=vscode -WorkingDirectory=/home/vscode -ExecStart=/usr/bin/code-server --config /home/vscode/.config/code-server/config.yaml -Restart=always -RestartSec=10 - -[Install] -WantedBy=multi-user.target -SYSTEMD_EOF - - # Enable and start code-server service - systemctl daemon-reload - systemctl enable code-server - systemctl start code-server - - # Wait a moment for service to start - sleep 5 - - # Check if service is running - if systemctl is-active --quiet code-server; then - echo "✅ code-server service started successfully" - else - echo "❌ Failed to start code-server service" - systemctl status code-server - exit 1 - fi - - # Install SSL certificate for vscode.mnemo-cards.online - if [ ! -d "/etc/letsencrypt/live/vscode.mnemo-cards.online" ]; then - echo "🔐 Getting Let's Encrypt SSL certificate for vscode.mnemo-cards.online..." - - # Stop nginx temporarily for certificate issuance - systemctl stop nginx 2>/dev/null || true - - if certbot certonly --standalone -d vscode.mnemo-cards.online --non-interactive --agree-tos --email admin@memo-cards.online; then - echo "✅ Let's Encrypt certificate obtained successfully for vscode.mnemo-cards.online!" - else - echo "❌ Failed to get Let's Encrypt certificate. Generating self-signed certificate..." - if [ ! -f "/etc/ssl/certs/nginx-selfsigned-vscode.crt" ]; then - openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ - -keyout /etc/ssl/private/nginx-selfsigned-vscode.key \ - -out /etc/ssl/certs/nginx-selfsigned-vscode.crt \ - -subj "/C=RU/ST=Moscow/L=Moscow/O=MnemoCards/OU=IT/CN=vscode.mnemo-cards.online" - fi - fi - - # Start nginx again - systemctl start nginx 2>/dev/null || true - else - echo "✅ Let's Encrypt certificate already exists for vscode.mnemo-cards.online" - fi - - # Configure nginx for VSCode - echo "Configuring nginx for VSCode..." - - # Copy VSCode nginx configuration - cp /tmp/vscode-nginx.conf /etc/nginx/sites-available/vscode - - # Enable VSCode site - ln -sf /etc/nginx/sites-available/vscode /etc/nginx/sites-enabled/vscode - - # Test nginx configuration - nginx -t - - # Restart nginx - systemctl restart nginx - systemctl enable nginx - - # Setup cron for certificate renewal (if not already configured) - if ! crontab -l | grep -q "vscode.mnemo-cards.online"; then - echo "Setting up cron job for VSCode certificate renewal..." - (crontab -l ; echo "0 12 * * * certbot renew --quiet --cert-name vscode.mnemo-cards.online") | crontab - - fi - - echo "VSCode domain setup completed successfully!" - echo "VSCode is now available at: https://vscode.mnemo-cards.online" - echo "Username: vscode" - echo "Password: vscode123!" - echo "Access by IP address is blocked" -EOF - -print_success "VSCode domain setup completed successfully! 🎉" -print_success "VSCode is now available at: https://vscode.mnemo-cards.online" -print_info "Username: vscode" -print_info "Password: vscode123!" -print_info "Make sure DNS is configured: vscode.mnemo-cards.online -> $SERVER_IP" diff --git a/tools/deploy/web-app/test-forgejo-domain.sh b/tools/deploy/web-app/test-forgejo-domain.sh deleted file mode 100755 index 3fd0d04..0000000 --- a/tools/deploy/web-app/test-forgejo-domain.sh +++ /dev/null @@ -1,171 +0,0 @@ -#!/bin/bash - -# Test script for Forgejo domain setup -# Usage: ./test-forgejo-domain.sh - -set -e - -# Load configuration -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "$SCRIPT_DIR/config.sh" - -echo "🧪 Testing Forgejo domain setup..." - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -print_status() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_info() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -# Test DNS resolution -print_status "Testing DNS resolution for code.mnemo-cards.online..." -DNS_IP=$(dig +short code.mnemo-cards.online A) -if [ "$DNS_IP" = "$SERVER_IP" ]; then - print_success "DNS resolution: code.mnemo-cards.online -> $DNS_IP ✓" -else - print_warning "DNS resolution: code.mnemo-cards.online -> $DNS_IP (expected: $SERVER_IP)" - print_warning "Make sure DNS is properly configured!" -fi - -# Test HTTP redirect to HTTPS -print_status "Testing HTTP redirect to HTTPS..." -HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://code.mnemo-cards.online/) -if [ "$HTTP_STATUS" = "301" ]; then - print_success "HTTP redirect: $HTTP_STATUS (redirect to HTTPS) ✓" -else - print_warning "HTTP redirect: $HTTP_STATUS (expected: 301)" -fi - -# Test HTTPS access -print_status "Testing HTTPS access to code.mnemo-cards.online..." -HTTPS_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --insecure https://code.mnemo-cards.online/) -if [ "$HTTPS_STATUS" = "200" ]; then - print_success "HTTPS access: $HTTPS_STATUS ✓" -elif [ "$HTTPS_STATUS" = "000" ]; then - print_error "HTTPS access: Connection failed (check if nginx is running and SSL is configured)" -else - print_warning "HTTPS access: $HTTPS_STATUS (may be normal for Forgejo auth redirects)" -fi - -# Test that HTTP IP access is blocked -print_status "Testing that HTTP IP access is blocked..." -HTTP_IP_BLOCK_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 http://147.45.152.129/) -if [ "$HTTP_IP_BLOCK_STATUS" = "444" ] || [ "$HTTP_IP_BLOCK_STATUS" = "000" ]; then - print_success "HTTP IP access blocked: $HTTP_IP_BLOCK_STATUS ✓" -else - print_warning "HTTP IP access not blocked: $HTTP_IP_BLOCK_STATUS (should be 444)" -fi - -# Test that HTTPS IP access is blocked -print_status "Testing that HTTPS IP access is blocked..." -HTTPS_IP_BLOCK_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 --insecure https://147.45.152.129/) -if [ "$HTTPS_IP_BLOCK_STATUS" = "444" ] || [ "$HTTPS_IP_BLOCK_STATUS" = "000" ]; then - print_success "HTTPS IP access blocked: $HTTPS_IP_BLOCK_STATUS ✓" -else - print_warning "HTTPS IP access not blocked: $HTTPS_IP_BLOCK_STATUS (should be 444)" -fi - -# Test that direct port 3000 access is blocked -print_status "Testing that direct port 3000 access is blocked..." -PORT_3000_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 http://147.45.152.129:3000/) -if [ "$PORT_3000_STATUS" = "000" ]; then - print_success "Direct port 3000 access blocked: $PORT_3000_STATUS ✓" -else - print_warning "Direct port 3000 access not blocked: $PORT_3000_STATUS (should be connection failed)" -fi - -# Test SSL certificate -print_status "Testing SSL certificate..." -SSL_INFO=$(openssl s_client -connect code.mnemo-cards.online:443 -servername code.mnemo-cards.online < /dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates 2>/dev/null) -if [ $? -eq 0 ]; then - print_success "SSL certificate is valid ✓" - echo "$SSL_INFO" | head -3 -else - print_error "SSL certificate validation failed" -fi - -# Test server connectivity -print_status "Testing server connectivity..." -ssh -o ConnectTimeout=10 -o BatchMode=yes "$SERVER_USER@$SERVER_IP" "echo 'SSH connection successful'" 2>/dev/null -if [ $? -eq 0 ]; then - print_success "SSH connection to server: OK ✓" -else - print_error "SSH connection to server: FAILED" -fi - -# Test nginx configuration on server -print_status "Testing nginx configuration on server..." -ssh "$SERVER_USER@$SERVER_IP" << EOF - # Test nginx config - if nginx -t 2>/dev/null; then - echo "✅ Nginx configuration: VALID" - else - echo "❌ Nginx configuration: INVALID" - exit 1 - fi - - # Check if Forgejo site is enabled - if [ -L "/etc/nginx/sites-enabled/forgejo" ]; then - echo "✅ Forgejo nginx site: ENABLED" - else - echo "❌ Forgejo nginx site: NOT ENABLED" - fi - - # Check if Forgejo is running - if pgrep -f "gitea" > /dev/null || pgrep -f "forgejo" > /dev/null; then - echo "✅ Forgejo process: RUNNING" - else - echo "⚠️ Forgejo process: NOT FOUND (check if Forgejo is started)" - fi - - # Check SSL certificate - if [ -f "/etc/letsencrypt/live/code.mnemo-cards.online/fullchain.pem" ]; then - echo "✅ Let's Encrypt certificate: EXISTS" - else - echo "⚠️ Let's Encrypt certificate: NOT FOUND (using self-signed?)" - fi - - # Check Forgejo ROOT_URL configuration - FORGEJO_CONFIG="" - for config_path in "/etc/forgejo/app.ini" "/home/forgejo/custom/conf/app.ini" "/var/lib/forgejo/custom/conf/app.ini" "/opt/forgejo/custom/conf/app.ini"; do - if [ -f "$config_path" ]; then - FORGEJO_CONFIG="$config_path" - break - fi - done - - if [ -n "$FORGEJO_CONFIG" ]; then - ROOT_URL=$(grep "^ROOT_URL" "$FORGEJO_CONFIG" | cut -d'=' -f2 | tr -d ' ') - if [ "$ROOT_URL" = "https://code.mnemo-cards.online" ]; then - echo "✅ Forgejo ROOT_URL: CORRECT ($ROOT_URL)" - else - echo "❌ Forgejo ROOT_URL: INCORRECT ($ROOT_URL) - should be https://code.mnemo-cards.online" - fi - else - echo "⚠️ Forgejo config: NOT FOUND" - fi -EOF - -print_info "Forgejo domain test completed!" -print_info "If everything looks good, Forgejo should be accessible at: https://code.mnemo-cards.online" diff --git a/tools/deploy/web-app/vscode-nginx.conf b/tools/deploy/web-app/vscode-nginx.conf deleted file mode 100644 index eafaabd..0000000 --- a/tools/deploy/web-app/vscode-nginx.conf +++ /dev/null @@ -1,99 +0,0 @@ -# Note: Default server blocks are defined in forgejo configuration -# This configuration only handles vscode.mnemo-cards.online domain - -server { - listen 80; - server_name vscode.mnemo-cards.online; - - # Redirect HTTP to HTTPS - return 301 https://$server_name$request_uri; -} - -server { - listen 443 ssl http2; - server_name vscode.mnemo-cards.online; - - # SSL configuration - Let's Encrypt - ssl_certificate /etc/letsencrypt/live/vscode.mnemo-cards.online/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/vscode.mnemo-cards.online/privkey.pem; - - # Fallback to self-signed certificates if Let's Encrypt fails - # ssl_certificate /etc/ssl/certs/nginx-selfsigned-vscode.crt; - # ssl_certificate_key /etc/ssl/private/nginx-selfsigned-vscode.key; - ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384; - ssl_prefer_server_ciphers off; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "no-referrer-when-downgrade" always; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - - # Special rate limiting for login attempts - location /login { - # Strict rate limiting for login - limit_req zone=vscode_login burst=2 nodelay; - limit_req_status 429; - - proxy_pass http://localhost:8080; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - - # WebSocket support for VSCode - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Timeout settings - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - - # Buffer settings - proxy_buffering off; - proxy_request_buffering off; - } - - # Proxy to code-server running on port 8080 - location / { - # Apply rate limiting - limit_req zone=vscode_general burst=10 nodelay; - limit_req_status 429; - - proxy_pass http://localhost:8080; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - - # WebSocket support for VSCode - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Timeout settings - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - - # Buffer settings - proxy_buffering off; - proxy_request_buffering off; - } - - # Gzip compression - gzip on; - gzip_vary on; - gzip_min_length 1024; - gzip_proxied expired no-cache no-store private auth; - gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript; - - # Security - deny access to hidden files - location ~ /\. { - deny all; - } -}