pipeline { agent any parameters { string( name: 'BRANCH', defaultValue: 'main', description: 'Ветка для деплоя' ) string( name: 'PORT', defaultValue: '2998', description: 'Порт для запуска экземпляра' ) string( name: 'NETWORK', defaultValue: 'app-network-dev', description: 'Docker сеть для подключения' ) } stages { stage('Git pull') { steps { script { checkout([ $class: 'GitSCM', branches: [[name: params.BRANCH]], userRemoteConfigs: [[ url: 'https://code.3err0.ru/frontdev/no-copy-frontend.git', credentialsId: 'nx-jen' ]] ]) } } } stage('Stop old') { steps { script { withCredentials([ usernamePassword( credentialsId: 'server-root-password', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS' ) ]) { sh """ sshpass -p '$SSH_PASS' ssh $SSH_USER@92.242.61.23 " docker stop no-copy-frontend-${params.PORT} 2>/dev/null || true docker rm no-copy-frontend-${params.PORT} 2>/dev/null || true cd /opt/deployments/frontend/${params.BRANCH}-${params.PORT} 2>/dev/null || mkdir -p /opt/deployments/frontend/${params.BRANCH}-${params.PORT} if [ -f 'docker-compose.yaml' ]; then docker-compose -f docker-compose.yaml -p frontend-${params.PORT} down 2>/dev/null || true elif [ -f 'docker-compose.yml' ]; then docker-compose -f docker-compose.yml -p frontend-${params.PORT} down 2>/dev/null || true fi " """ } } } } stage('Copy to server') { steps { script { withCredentials([ usernamePassword( credentialsId: 'server-root-password', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS' ) ]) { sh """ sshpass -p '$SSH_PASS' ssh $SSH_USER@92.242.61.23 " rm -rf /opt/deployments/frontend/${params.BRANCH}-${params.PORT}/* mkdir -p /opt/deployments/frontend/${params.BRANCH}-${params.PORT} " sshpass -p '$SSH_PASS' scp -r ./* $SSH_USER@92.242.61.23:/opt/deployments/frontend/${params.BRANCH}-${params.PORT}/ """ } } } } stage('Build on server') { steps { script { def BUILD_TIME_FRONT = sh(script: "date '+%d-%m-%Y %H:%M:%S'", returnStdout: true).trim() withCredentials([ usernamePassword( credentialsId: 'server-root-password', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS' ) ]) { sh """ sshpass -p '$SSH_PASS' ssh $SSH_USER@92.242.61.23 " cd /opt/deployments/frontend/${params.BRANCH}-${params.PORT} # 1. СОЗДАЕМ JSON ФАЙЛ (ЭТО РАБОТАЕТ 100%) mkdir -p public echo '{\\"buildTime\\": \\"${BUILD_TIME_FRONT}\\"}' > public/build-info.json # 2. Меняем имя контейнера и порт sed -i 's/container_name: no-copy-frontend\$/container_name: no-copy-frontend-${params.PORT}/' docker-compose.yml sed -i 's/\\\"2998:2999\\\"/\\\"${params.PORT}:2999\\\"/' docker-compose.yml # 3. Собираем образ docker-compose -f docker-compose.yml -p frontend-${params.PORT} build " """ } } } } stage('Start on server') { steps { script { withCredentials([ usernamePassword( credentialsId: 'server-root-password', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS' ) ]) { sh """ sshpass -p '$SSH_PASS' ssh $SSH_USER@92.242.61.23 " cd /opt/deployments/frontend/${params.BRANCH}-${params.PORT} echo '=== Запускаем контейнер ===' docker-compose -f docker-compose.yml -p frontend-${params.PORT} up -d sleep 10 echo '=== Проверяем запуск ===' if docker ps --format '{{.Names}}' | grep -q 'no-copy-frontend-${params.PORT}'; then echo '✓ Контейнер запущен: no-copy-frontend-${params.PORT}' echo '✓ Порт: ${params.PORT}:2999' else echo '✗ Контейнер не запустился' echo 'Логи:' docker-compose -f docker-compose.yml -p frontend-${params.PORT} logs exit 1 fi " """ } } } } stage('Check status') { steps { script { withCredentials([ usernamePassword( credentialsId: 'server-root-password', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS' ) ]) { sh """ sshpass -p '$SSH_PASS' ssh $SSH_USER@92.242.61.23 " # Ищем контейнер с правильным именем (с портом) if docker ps --format '{{.Names}}' | grep -q 'no-copy-frontend-${params.PORT}'; then echo 'Container started: no-copy-frontend-${params.PORT}' sleep 5 HTTP_CODE=\$(curl -s -o /dev/null -w '%{http_code}' http://localhost:${params.PORT} || echo '000') echo 'HTTP code: \$HTTP_CODE' echo 'Frontend available on http://92.242.61.23:${params.PORT}' # Показываем все фронтенды echo '' echo 'All frontend containers:' docker ps --filter name=no-copy-frontend --format 'table {{.Names}}\\t{{.Ports}}\\t{{.Status}}' else echo 'Exception: container did not start' docker ps -a | grep frontend exit 1 fi " """ } } } } // stage('Connect to network') { // steps { // script { // withCredentials([ // usernamePassword( // credentialsId: 'server-root-password', // usernameVariable: 'SSH_USER', // passwordVariable: 'SSH_PASS' // ) // ]) { // sh """ // sshpass -p '$SSH_PASS' ssh $SSH_USER@92.242.61.23 " // echo 'Отключаем от всех сетей и подключаем к ${params.NETWORK}' // // # Отключаем от всех сетей (кроме bridge, host, none) // current_networks=\$(docker inspect no-copy-frontend-${params.PORT} --format='{{range \$net, \$v := .NetworkSettings.Networks}}{{\$net}}{{\"\\n\"}}{{end}}' | grep -v -E '^(bridge|host|none)\$' || true) // // for net in \$current_networks; do // echo \"Отключаем от сети: \$net\" // docker network disconnect \$net no-copy-frontend-${params.PORT} 2>/dev/null || true // done // // # Подключаем к нужной сети // docker network connect ${params.NETWORK} no-copy-frontend-${params.PORT} // // echo 'Готово! Контейнер теперь в сети:' // docker inspect no-copy-frontend-${params.PORT} --format='{{range \$net, \$v := .NetworkSettings.Networks}}{{\$net}}{{\"\\n\"}}{{end}}' // " // """ // } // } // } // } stage('Connect to network') { steps { script { withCredentials([ usernamePassword( credentialsId: 'server-root-password', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS' ) ]) { sh """ sshpass -p '$SSH_PASS' ssh $SSH_USER@92.242.61.23 " echo 'Подключаем контейнер к сети ${params.NETWORK}' if ! docker network ls --format '{{.Name}}' | grep -q '^${params.NETWORK}\$'; then docker network create ${params.NETWORK} fi if docker ps -a --format '{{.Names}}' | grep -q '^no-copy-frontend-${params.PORT}\$'; then docker network disconnect ${params.NETWORK} no-copy-frontend-${params.PORT} 2>/dev/null || true docker network connect ${params.NETWORK} no-copy-frontend-${params.PORT} echo 'Контейнер подключен к ${params.NETWORK}' fi " """ } } } } } post { success { echo "Front branch ${params.BRANCH} deployment completed" echo "Frontend available on http://92.242.61.23:${params.PORT}" echo "Container: no-copy-frontend-${params.PORT}" } failure { echo "Deployment failed" } } }