mnemo_cards/tools/deploy/backend-build_app.sh
2025-11-23 00:34:29 +03:00

203 lines
9 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"