203 lines
9 KiB
Bash
203 lines
9 KiB
Bash
set -e -v
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||
BACKEND_DIR="$PROJECT_ROOT/mnemo_cards_backend"
|
||
|
||
cd $PROJECT_ROOT/mnemo_cards_common
|
||
git pull origin master
|
||
dart pub get
|
||
|
||
cd $PROJECT_ROOT/mnemo_cards_common_backend
|
||
git pull origin master
|
||
dart pub get
|
||
|
||
cd $BACKEND_DIR
|
||
dart pub get && dart compile exe --verbose lib/main.dart -o server_build.exe
|
||
|
||
sudo systemctl stop mnemo_cards_server && true
|
||
sleep 15
|
||
sudo chmod 777 mnemo_cards_server.service
|
||
sudo cp mnemo_cards_server.service /etc/systemd/system
|
||
sudo cp server_build.exe server.exe
|
||
rm server_build.exe
|
||
|
||
# Проверяем наличие Let's Encrypt сертификатов для HTTPS-only режима
|
||
# Используем общий multi-domain сертификат mnemo-cards.online
|
||
if [ -d "/etc/letsencrypt/live/mnemo-cards.online" ] && [ -f "/etc/letsencrypt/live/mnemo-cards.online/fullchain.pem" ]; then
|
||
echo "✅ Let's Encrypt multi-domain сертификаты найдены. Запускаем в HTTPS-only режиме"
|
||
# Обновляем systemd сервис для HTTPS-only режима
|
||
sudo sed -i 's|ExecStart=$BACKEND_DIR/server.exe.*|ExecStart=$BACKEND_DIR/server.exe --certs /etc/letsencrypt/live/mnemo-cards.online -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service
|
||
|
||
# Инициализируем переменные для отслеживания остановленных сервисов
|
||
NGINX_STOPPED=false
|
||
APACHE_STOPPED=false
|
||
HTTPD_STOPPED=false
|
||
else
|
||
echo "⚠️ Let's Encrypt сертификаты не найдены или повреждены. Пытаемся создать..."
|
||
|
||
# Проверяем, занят ли порт 80
|
||
if sudo ss -tulpn | grep :80 > /dev/null 2>&1 || sudo lsof -i :80 > /dev/null 2>&1; then
|
||
echo "🔍 Порт 80 занят другим процессом."
|
||
|
||
# ВНИМАНИЕ: В ПРОДАКШЕНЕ НЕ ОСТАНАВЛИВАЕМ NGINX!
|
||
# Используем webroot режим вместо standalone
|
||
echo "💡 Используем webroot режим для получения сертификатов (nginx продолжает работать)"
|
||
|
||
# Убеждаемся, что nginx запущен
|
||
if ! sudo systemctl is-active --quiet nginx; then
|
||
echo "🚀 Запускаем nginx для webroot режима..."
|
||
sudo systemctl start nginx
|
||
sleep 2
|
||
if ! sudo systemctl is-active --quiet nginx; then
|
||
echo "❌ Критическая ошибка: не удалось запустить nginx!"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
# Создаем директорию для webroot challenge
|
||
sudo mkdir -p /var/www/html/.well-known/acme-challenge
|
||
sudo chown -R www-data:www-data /var/www/html
|
||
|
||
# Проверяем, есть ли конфигурация для /.well-known
|
||
if ! grep -q "\.well-known" /etc/nginx/sites-enabled/* 2>/dev/null; then
|
||
echo "📝 Добавляем поддержку ACME challenge в nginx..."
|
||
sudo printf 'server {\n listen 80;\n server_name _;\n location /.well-known/acme-challenge/ {\n root /var/www/html;\n try_files $uri =404;\n }\n location / {\n return 404;\n }\n}\n' > /etc/nginx/sites-available/acme-challenge
|
||
sudo ln -sf /etc/nginx/sites-available/acme-challenge /etc/nginx/sites-enabled/acme-challenge
|
||
sudo nginx -t && sudo systemctl reload nginx
|
||
fi
|
||
|
||
# Изменяем команду certbot на webroot режим
|
||
CERTBOT_WEBROOT=true
|
||
else
|
||
echo "✅ Порт 80 свободен"
|
||
CERTBOT_WEBROOT=false
|
||
fi
|
||
|
||
# Останавливаем наш сервер временно для получения сертификата
|
||
sudo systemctl stop mnemo_cards_server 2>/dev/null || true
|
||
sleep 3
|
||
|
||
# Пытаемся получить Let's Encrypt multi-domain сертификат
|
||
echo "🔐 Получаем Let's Encrypt multi-domain сертификат..."
|
||
CERTBOT_SUCCESS=false
|
||
if sudo certbot certonly --standalone \
|
||
-d mnemo-cards.online \
|
||
-d api.mnemo-cards.online \
|
||
-d code.mnemo-cards.online \
|
||
-d vscode.mnemo-cards.online \
|
||
--cert-name mnemo-cards.online \
|
||
--non-interactive --agree-tos --email admin@mnemo-cards.online; then
|
||
echo "✅ Let's Encrypt multi-domain сертификат успешно создан!"
|
||
CERTBOT_SUCCESS=true
|
||
echo "🚀 Запускаем в HTTPS-only режиме"
|
||
# Обновляем systemd сервис для HTTPS-only режима (используем общий сертификат)
|
||
sudo sed -i 's|ExecStart=$BACKEND_DIR/server.exe.*|ExecStart=$BACKEND_DIR/server.exe --certs /etc/letsencrypt/live/mnemo-cards.online -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service
|
||
else
|
||
echo "❌ Не удалось создать Let's Encrypt сертификат. Запускаем в HTTP режиме"
|
||
echo "💡 Возможные причины и решения:"
|
||
echo " - Домен mnemo-cards.online не указывает на этот сервер"
|
||
echo " - Порт 80 недоступен извне (firewall, порт forwarding)"
|
||
echo " - Сертификат уже был получен ранее - проверьте /etc/letsencrypt/live/"
|
||
echo " - Используйте webroot режим если есть веб-сервер: certbot certonly --webroot -w /var/www/html -d mnemo-cards.online"
|
||
# Возвращаем обычный режим
|
||
sudo sed -i 's|ExecStart=$BACKEND_DIR/server.exe.*|ExecStart=$BACKEND_DIR/server.exe -a 0.0.0.0 -p 8081|' /etc/systemd/system/mnemo_cards_server.service
|
||
fi
|
||
|
||
fi
|
||
|
||
# Переменные для отслеживания состояния (теперь не используются)
|
||
# NGINX_STOPPED=false
|
||
# APACHE_STOPPED=false
|
||
# HTTPD_STOPPED=false
|
||
|
||
# Создаем новую nginx конфигурацию для HTTPS-only режима API
|
||
# Используем общий multi-domain сертификат mnemo-cards.online
|
||
cat > /tmp/api-https-only << 'EOF'
|
||
server {
|
||
listen 80;
|
||
server_name api.mnemo-cards.online;
|
||
|
||
# Serve ACME challenge for Let's Encrypt
|
||
location /.well-known/acme-challenge/ {
|
||
root /var/www/html;
|
||
try_files $uri =404;
|
||
}
|
||
|
||
# Redirect all other HTTP traffic to HTTPS
|
||
location / {
|
||
return 301 https://$server_name$request_uri;
|
||
}
|
||
}
|
||
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name api.mnemo-cards.online;
|
||
|
||
# SSL configuration - Let's Encrypt (multi-domain certificate)
|
||
ssl_certificate /etc/letsencrypt/live/mnemo-cards.online/fullchain.pem;
|
||
ssl_certificate_key /etc/letsencrypt/live/mnemo-cards.online/privkey.pem;
|
||
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 HTTP backend (SSL termination in nginx)
|
||
location / {
|
||
proxy_pass http://127.0.0.1:8081;
|
||
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;
|
||
|
||
# Timeout settings
|
||
proxy_connect_timeout 60s;
|
||
proxy_send_timeout 60s;
|
||
proxy_read_timeout 60s;
|
||
}
|
||
}
|
||
EOF
|
||
|
||
# Заменяем старую конфигурацию API на новую
|
||
sudo cp /tmp/api-https-only /etc/nginx/sites-available/api
|
||
|
||
# Проверяем конфигурацию nginx
|
||
echo "🔍 Проверяем конфигурацию nginx..."
|
||
if sudo nginx -t; then
|
||
echo "✅ Конфигурация nginx валидна"
|
||
else
|
||
echo "❌ Ошибка в конфигурации nginx!"
|
||
exit 1
|
||
fi
|
||
|
||
# Гарантируем запуск nginx (используем restart вместо reload для надежности)
|
||
echo "🔄 Запускаем/перезапускаем nginx..."
|
||
if sudo systemctl is-active --quiet nginx; then
|
||
echo "🔄 Перезагружаем nginx..."
|
||
sudo systemctl reload nginx
|
||
else
|
||
echo "🚀 Запускаем nginx..."
|
||
sudo systemctl start nginx
|
||
fi
|
||
|
||
# Проверяем, что nginx запущен
|
||
sleep 2
|
||
if sudo systemctl is-active --quiet nginx; then
|
||
echo "✅ nginx успешно запущен"
|
||
else
|
||
echo "❌ Ошибка: nginx не запущен!"
|
||
sudo systemctl status nginx --no-pager || true
|
||
exit 1
|
||
fi
|
||
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl start mnemo_cards_server
|
||
journalctl -u mnemo_cards_server --since "1min ago"
|
||
|
||
|