Files
no-copy/infrastructure/jenkins/deploy-backend.groovy
T

243 lines
11 KiB
Groovy
Raw Normal View History

pipeline {
agent any
parameters {
string(
name: 'BRANCH',
defaultValue: 'dev',
description: 'Ветка для деплоя'
)
string(
name: 'PORT',
2026-03-04 21:16:21 +07:00
defaultValue: '3001',
description: 'Порт для запуска экземпляра'
)
2026-03-04 21:16:21 +07:00
string(
name: 'PORT_DB',
defaultValue: '',
description: 'Порт для запуска БД'
)
string(
name: 'SERVER',
defaultValue: '92.242.61.23',
description: 'Сервер для деплоя'
)
2026-03-04 21:16:21 +07:00
string(
name: 'NETWORK',
defaultValue: 'app-network-dev',
description: 'Имя сети (будет создана если не существует)'
)
2026-03-06 23:52:06 +07:00
choice(
name: 'SPRING_PROFILE',
choices: ['dev', 'prod'],
description: 'Профиль Spring для запуска'
)
}
stages {
stage('Git pull') {
steps {
cleanWs()
script {
checkout([
$class: 'GitSCM',
branches: [[name: params.BRANCH]],
userRemoteConfigs: [[
url: 'https://code.3err0.ru/backdev/no-copy.git',
credentialsId: 'nx-jen'
]]
])
}
}
}
2026-03-04 21:16:21 +07:00
stage('Copy to server') {
steps {
script {
withCredentials([
usernamePassword(
credentialsId: 'server-root-password',
usernameVariable: 'SSH_USER',
passwordVariable: 'SSH_PASS'
)
]) {
sh """
sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${SSH_USER}@${params.SERVER} "
rm -rf /opt/deployments/${params.BRANCH}-${params.PORT}/*
mkdir -p /opt/deployments/${params.BRANCH}-${params.PORT}
"
sshpass -p '${SSH_PASS}' scp -r ./* ${SSH_USER}@${params.SERVER}:/opt/deployments/${params.BRANCH}-${params.PORT}/
"""
}
}
}
}
stage('Deploy with docker-compose') {
steps {
script {
2026-02-13 21:40:15 +07:00
def buildTime = sh(script: "TZ='Asia/Novosibirsk' date '+%d-%m-%Y %H:%M:%S'", returnStdout: true).trim()
2026-03-07 02:18:56 +07:00
def springProfile = params.SPRING_PROFILE
withCredentials([
usernamePassword(
credentialsId: 'server-root-password',
usernameVariable: 'SSH_USER',
passwordVariable: 'SSH_PASS'
),
string(credentialsId: 'DB_USER', variable: 'DB_USER'),
2026-04-14 18:26:23 +07:00
string(credentialsId: 'DB_PASSWORD', variable: 'DB_PASSWORD'),
string(credentialsId: 'MONGO_USER', variable: 'MONGO_USER'),
string(credentialsId: 'MONGO_PASSWORD', variable: 'MONGO_PASSWORD')
]) {
sh """
2026-01-30 19:27:01 +07:00
echo "Testing SSH connection..."
if sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${SSH_USER}@${params.SERVER} 'echo "SSH connection successful"'; then
echo "SSH connection OK"
else
echo "SSH connection failed"
exit 1
fi
sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${SSH_USER}@${params.SERVER} "
2026-03-04 21:16:21 +07:00
mkdir -p /opt/deployments/${params.BRANCH}-${params.PORT}
cd /opt/deployments/${params.BRANCH}-${params.PORT}
2026-03-04 21:16:21 +07:00
echo '1. Проверяем/создаем сеть ${params.NETWORK}...'
if ! docker network ls --format '{{.Name}}' | grep -q '^${params.NETWORK}\$'; then
docker network create ${params.NETWORK}
echo 'Сеть ${params.NETWORK} создана'
else
echo 'Сеть ${params.NETWORK} уже существует'
fi
2026-01-30 19:27:01 +07:00
echo '2. Останавливаем старые контейнеры порта ${params.PORT}...'
docker stop app-backend-${params.PORT} 2>/dev/null || echo 'Контейнер не найден'
docker rm app-backend-${params.PORT} 2>/dev/null || echo 'Контейнер не найден'
docker stop postgres-${params.PORT} 2>/dev/null || echo 'Контейнер БД не найден'
docker rm postgres-${params.PORT} 2>/dev/null || echo 'Контейнер БД не найден'
docker stop file-storage-${params.PORT} 2>/dev/null || echo 'Контейнер storage не найден'
docker rm file-storage-${params.PORT} 2>/dev/null || echo 'Контейнер storage не найден'
2026-04-14 18:26:23 +07:00
docker stop mongodb-${params.PORT} 2>/dev/null || echo 'Контейнер MongoDB не найден'
docker rm mongodb-${params.PORT} 2>/dev/null || echo 'Контейнер MongoDB не найден'
2026-01-30 19:27:01 +07:00
echo '3. Запускаем БД...'
docker run -d \\
--name postgres-${params.PORT} \\
2026-03-04 21:16:21 +07:00
--network ${params.NETWORK} \\
2026-01-30 19:27:01 +07:00
--network-alias no_copy_${params.PORT} \\
--network-alias database-${params.PORT} \\
2026-01-30 19:27:01 +07:00
--network-alias db-${params.PORT} \\
-p ${params.PORT}0:5432 \\
2026-03-04 21:16:21 +07:00
-e POSTGRES_DB=no_copy${params.PORT_DB} \\
-e POSTGRES_USER=${DB_USER} \\
-e POSTGRES_PASSWORD=${DB_PASSWORD} \\
-v pgdata_${params.PORT}:/var/lib/postgresql/data \\
2026-02-11 19:15:16 +07:00
-e BUILD_TIME_BACK='${buildTime}' \\
postgres:17.7
2026-04-14 18:26:23 +07:00
echo '4. Запускаем MongoDB...'
docker run -d \\
--name mongodb-${params.PORT} \\
--network ${params.NETWORK} \\
--network-alias mongodb-${params.PORT} \\
-p ${params.PORT}1:27017 \\
-e MONGO_INITDB_ROOT_USERNAME=${MONGO_USER} \\
-e MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD} \\
-v mongodb_data_${params.PORT}:/data/db \\
mongo:7.0
echo '5. Запускаем storage...'
docker run -d \\
--name file-storage-${params.PORT} \\
2026-03-04 21:16:21 +07:00
--network ${params.NETWORK} \\
-v uploads_data_${params.PORT}:/storage:rw \\
alpine:latest tail -f /dev/null
2026-04-14 18:26:23 +07:00
echo '6. Ждем БД...'
sleep 15
2026-05-08 14:35:15 +07:00
echo '6.5. Удаляем старый образ и чистим кэш...'
docker rmi app-backend-${params.PORT}:latest 2>/dev/null || echo 'Образ не найден'
docker builder prune -f
rm -rf .gradle build
2026-04-14 18:26:23 +07:00
echo '7. Собираем приложение...'
docker build --no-cache -t app-backend-${params.PORT}:latest .
2026-04-14 18:26:23 +07:00
echo '8. Запускаем приложение...'
docker run -d \\
--name app-backend-${params.PORT} \\
2026-03-04 21:16:21 +07:00
--network ${params.NETWORK} \\
--network-alias app \\
--network-alias app-${params.PORT} \\
-p ${params.PORT}:8080 \\
-v uploads_data_${params.PORT}:/data/uploads:rw \\
2026-03-04 21:16:21 +07:00
-e POSTGRES_DB=no_copy${params.PORT_DB} \\
-e POSTGRES_USER=${DB_USER} \\
-e POSTGRES_PASSWORD=${DB_PASSWORD} \\
-e POSTGRES_PORT=5432 \\
2026-01-30 19:27:01 +07:00
-e POSTGRES_HOST=no_copy_${params.PORT} \\
2026-03-07 02:35:01 +07:00
-e FILE_STORAGE_PATH=/data/uploads \\
2026-03-07 02:18:56 +07:00
-e SPRING_PROFILES_ACTIVE=${springProfile} \\
2026-04-14 18:26:23 +07:00
-e MONGO_URI=mongodb://${MONGO_USER}:${MONGO_PASSWORD}@mongodb-${params.PORT}:27017 \\
-e MONGO_DATABASE=no_copy \\
app-backend-${params.PORT}:latest
2026-04-14 18:26:23 +07:00
echo '9. Проверка...'
sleep 10
if curl -s -f http://localhost:${params.PORT}/health > /dev/null 2>&1; then
2026-01-30 19:27:01 +07:00
echo 'Приложение работает на порту ${params.PORT}'
else
2026-01-30 19:27:01 +07:00
echo 'Проверка health не удалась'
docker logs app-backend-${params.PORT} --tail=20
fi
2026-01-30 19:27:01 +07:00
"
"""
}
}
}
}
2026-03-04 21:16:21 +07:00
stage('Verify network') {
steps {
script {
withCredentials([
usernamePassword(
credentialsId: 'server-root-password',
usernameVariable: 'SSH_USER',
passwordVariable: 'SSH_PASS'
)
]) {
sh """
sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${SSH_USER}@${params.SERVER} "
echo 'Проверяем подключение к сети ${params.NETWORK}'
docker network inspect ${params.NETWORK} --format='{{.Name}}: {{range .Containers}}{{.Name}} {{end}}'
echo 'Проверяем алиас app для контейнера app-backend-${params.PORT}'
docker inspect app-backend-${params.PORT} | grep -A 5 'Aliases'
"
"""
}
}
}
}
}
post {
success {
2026-03-07 02:43:35 +07:00
script {
def appUrl = params.SPRING_PROFILE == 'prod' ? 'https://workspace.not-copy.com' : 'https://dev-workspace.not-copy.com'
echo "Deployment successful"
echo "Application URL: ${appUrl}"
}
}
failure {
echo "Deployment failed for branch ${params.BRANCH} on port ${params.PORT}"
}
always {
echo "Deployment process finished"
}
}
}