Files
chore/Jenkinsfile
2025-12-15 13:30:25 -05:00

115 lines
4.3 KiB
Groovy

pipeline {
agent any
environment {
// Tag images with the build number so they are unique
APP_FRONTEND_NAME = "chore-app-frontend"
APP_BACKEND_NAME = "chore-app-backend"
IMAGE_FRONTEND_NAME = "${APP_FRONTEND_NAME}:${env.BUILD_ID}"
IMAGE_BACKEND_NAME = "${APP_BACKEND_NAME}:${env.BUILD_ID}"
CONTAINER_FRONTEND_NAME = "${APP_FRONTEND_NAME}"
CONTAINER_BACKEND_NAME = "${APP_BACKEND_NAME}"
NETWORK_NAME = "chore-app-net"
}
stages {
stage('Checkout') {
steps {
// Pulls code from your configured Git repo
checkout scm
}
}
stage('Set Version') {
steps {
script {
// Extract BASE_VERSION from Python file using grep
env.BASE_VERSION = sh(
script: "grep '^BASE_VERSION' config/version.py | cut -d'\"' -f2",
returnStdout: true
).trim()
echo "BASE_VERSION set to: ${env.BASE_VERSION}"
}
}
}
stage('Build Frontend (Vue) App') {
steps {
dir('web/vue-app') {
sh """docker build --build-arg APP_BUILD=${BUILD_NUMBER} -t ${APP_FRONTEND_NAME}:${BASE_VERSION}-${BUILD_NUMBER} ."""
}
}
}
stage('Build Backend (Flask) App') {
steps {
dir('.') {
sh """docker build --build-arg APP_BUILD=${BUILD_NUMBER} -t ${APP_BACKEND_NAME}:${BASE_VERSION}-${BUILD_NUMBER} ."""
}
}
}
stage('Deploy') {
steps {
echo 'Stopping and removing old containers...'
sh "docker stop ${CONTAINER_FRONTEND_NAME} || true"
sh "docker rm ${CONTAINER_FRONTEND_NAME} || true"
sh "docker stop ${CONTAINER_BACKEND_NAME} || true"
sh "docker rm ${CONTAINER_BACKEND_NAME} || true"
echo 'Cleaning up and creating network...'
sh "docker network rm -f ${NETWORK_NAME} || true"
sh "docker network create ${NETWORK_NAME}"
echo "Starting new containers"
sh """
docker run -d \\
--name ${CONTAINER_FRONTEND_NAME} \\
--network ${NETWORK_NAME} \\
-p 443:443 \\
${APP_FRONTEND_NAME}:${BASE_VERSION}-${BUILD_NUMBER}
"""
sh """
docker run -d \\
--name ${CONTAINER_BACKEND_NAME} \\
--network ${NETWORK_NAME} \\
-e BUILD_NUMBER=${BUILD_NUMBER} \\
-v ${CONTAINER_BACKEND_NAME}_data:/app/data \\
${APP_BACKEND_NAME}:${BASE_VERSION}-${BUILD_NUMBER}
"""
echo 'Deployment complete!'
}
}
stage('Cleanup') {
steps {
echo 'Removing old/dangling Docker images...'
// Remove all images that are not associated with a container
// This targets the untagged images created by previous builds
sh 'docker system prune -a -f'
// OPTIONAL: Remove images older than a certain time (e.g., 24 hours)
// This is useful if you want to keep the most recent successful images
// for quick rollback, but remove others.
// sh 'docker image prune -a -f --filter "until=24h"'
echo 'Docker images pruned.'
// Optional: Stop old containers and run the new ones
// Note: In production, you would push to a registry (DockerHub) instead
sh "echo 'Build Complete. Images ready: ${IMAGE_FRONTEND_NAME} and ${IMAGE_BACKEND_NAME}'"
}
}
stage('Tag Latest') {
steps {
echo 'Tagging deployed images as latest...'
sh "docker tag ${APP_FRONTEND_NAME}:${BASE_VERSION}-${BUILD_NUMBER} ${APP_FRONTEND_NAME}:latest"
sh "docker tag ${APP_BACKEND_NAME}:${BASE_VERSION}-${BUILD_NUMBER} ${APP_BACKEND_NAME}:latest"
}
}
}
}