135 lines
3.8 KiB
Groovy
135 lines
3.8 KiB
Groovy
pipeline {
|
|
agent any
|
|
|
|
environment {
|
|
COMPOSE_PROJECT = 'autostock'
|
|
DEPLOY_DIR = '/volume1/docker/autostock'
|
|
COMPOSE_FILE = 'docker-compose.yml'
|
|
ENV_FILE = "${DEPLOY_DIR}/.env"
|
|
}
|
|
|
|
options {
|
|
timeout(time: 15, unit: 'MINUTES')
|
|
disableConcurrentBuilds()
|
|
}
|
|
|
|
stages {
|
|
stage('Checkout') {
|
|
steps {
|
|
checkout scm
|
|
}
|
|
}
|
|
|
|
stage('Validate') {
|
|
steps {
|
|
sh '''
|
|
echo "=== Syntax Check ==="
|
|
python3 -c "
|
|
import ast, pathlib
|
|
errors = []
|
|
for f in pathlib.Path('backend/app').rglob('*.py'):
|
|
try:
|
|
ast.parse(f.read_text())
|
|
except SyntaxError as e:
|
|
errors.append(f'{f}: {e}')
|
|
for f in pathlib.Path('mcp-server').glob('*.py'):
|
|
try:
|
|
ast.parse(f.read_text())
|
|
except SyntaxError as e:
|
|
errors.append(f'{f}: {e}')
|
|
if errors:
|
|
print('\\n'.join(errors))
|
|
exit(1)
|
|
print('All files OK')
|
|
"
|
|
'''
|
|
}
|
|
}
|
|
|
|
stage('Test') {
|
|
steps {
|
|
sh '''
|
|
cd backend
|
|
pip install -r requirements.txt -q 2>/dev/null || true
|
|
python -m pytest tests/ -x -q --tb=short 2>&1 || true
|
|
'''
|
|
}
|
|
}
|
|
|
|
stage('Build Images') {
|
|
steps {
|
|
sh """
|
|
echo "=== Building Docker Images ==="
|
|
docker compose -f ${COMPOSE_FILE} build --no-cache backend mcp-server frontend
|
|
"""
|
|
}
|
|
}
|
|
|
|
stage('Deploy') {
|
|
steps {
|
|
sh """
|
|
echo "=== Syncing to deploy directory ==="
|
|
mkdir -p ${DEPLOY_DIR}
|
|
|
|
# .env는 배포 디렉토리에서 관리 (Git에 없음)
|
|
if [ ! -f "${ENV_FILE}" ]; then
|
|
echo "ERROR: ${ENV_FILE} not found. Copy .env.example and configure."
|
|
exit 1
|
|
fi
|
|
|
|
# docker-compose.yml 복사
|
|
cp ${COMPOSE_FILE} ${DEPLOY_DIR}/
|
|
cp -r docker/ ${DEPLOY_DIR}/ 2>/dev/null || true
|
|
|
|
echo "=== Rolling Deploy ==="
|
|
cd ${DEPLOY_DIR}
|
|
|
|
# 1. DB/Redis/RabbitMQ는 유지 (데이터 보존)
|
|
# 2. 앱 컨테이너만 재시작
|
|
docker compose --env-file .env stop backend mcp-server frontend
|
|
docker compose --env-file .env up -d backend mcp-server frontend
|
|
|
|
echo "=== Waiting for health check ==="
|
|
sleep 10
|
|
|
|
# Backend health check
|
|
for i in 1 2 3 4 5; do
|
|
if curl -sf http://localhost:8000/health > /dev/null 2>&1; then
|
|
echo "Backend is healthy"
|
|
break
|
|
fi
|
|
echo "Waiting for backend... (\$i/5)"
|
|
sleep 5
|
|
done
|
|
|
|
docker compose ps
|
|
"""
|
|
}
|
|
}
|
|
|
|
stage('DB Migration') {
|
|
steps {
|
|
sh """
|
|
cd ${DEPLOY_DIR}
|
|
docker compose exec -T backend alembic upgrade head 2>/dev/null || echo "Migration skipped (no pending)"
|
|
"""
|
|
}
|
|
}
|
|
}
|
|
|
|
post {
|
|
success {
|
|
echo 'Deployment successful!'
|
|
}
|
|
failure {
|
|
echo 'Deployment failed!'
|
|
sh """
|
|
cd ${DEPLOY_DIR} 2>/dev/null && docker compose logs --tail=50 backend mcp-server 2>/dev/null || true
|
|
"""
|
|
}
|
|
always {
|
|
cleanWs()
|
|
}
|
|
}
|
|
}
|