From 8e0488298327f377f6cd7b78aa24ae54f5fd10d7 Mon Sep 17 00:00:00 2001 From: Pablo de la Torre Jamardo Date: Sat, 21 Feb 2026 09:26:25 +0100 Subject: [PATCH] ci: implements jenkins deploy --- Dockerfile | 14 +++++++++ Jenkinsfile | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 33 +++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 Dockerfile create mode 100644 Jenkinsfile create mode 100644 Makefile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..87059b4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +# Stage 1: build +FROM node:20-alpine AS build +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +RUN npm run build # Esto genera /dist + +# Stage 2: serve con Nginx +FROM nginx:alpine +COPY --from=build /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..1e3478b --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,83 @@ +pipeline { + agent any + + environment { + APP_NAME = "pablotj-portfolio-web" + REGISTRY_URL = "registry.pablotj.com" + NAMESPACE = "andromeda" + USER = "andromeda" + PASS = credentials('docker-registry-password') + TAG = "latest" + HOST_PORT = "8080" + CONTAINER_PORT = "3000" + } + + stages { + + stage('Preparar') { + steps { + echo "Limpiando workspace..." + deleteDir() + } + } + + stage('Checkout') { + steps { + echo "Clonando repo..." + checkout scm + } + } + + stage('Deploy Docker') { + steps { + echo "Usando archivo .env secreto de Jenkins" + + // Se copia el secret file a un archivo .env temporal en el workspace + withCredentials([file(credentialsId: 'pablotj-portfolio-website-env', variable: 'SECRET_ENV')]) { + sh 'cp $SECRET_ENV .env' + + // Ejecuta el Makefile deploy + sh "${MAKE_CMD} deploy" + } + } + } + + stage('Build') { + steps { + echo "Construyendo imagen..." + sh "make build" + } + } + + stage('Tag') { + steps { + echo "Tagging imagen..." + sh "make tag" + } + } + + stage('Login & Push') { + steps { + echo "Subiendo imagen al registry..." + sh "docker login ${REGISTRY_URL} -u ${USER} -p ${PASS}" + sh "make push" + } + } + + stage('Deploy') { + steps { + echo "Deteniendo y levantando contenedor..." + sh "make deploy" + } + } + } + + post { + success { + echo "Despliegue completado correctamente" + } + failure { + echo "Ha fallado el pipeline" + } + } +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0bb245c --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +APP_NAME=pablotj-portfolio-web +IMAGE_NAME=$(APP_NAME) + +REGISTRY_URL=registry.pablotj.com +NAMESPACE=andromeda +TAG?=latest + +HOST_PORT=8080 +CONTAINER_PORT=3000 + +IMAGE_FULL=$(REGISTRY_URL)/$(NAMESPACE)/$(IMAGE_NAME):$(TAG) + +build: + docker build -t $(IMAGE_NAME):$(TAG) . + +tag: + docker tag $(IMAGE_NAME):$(TAG) $(IMAGE_FULL) + +push: + docker push $(IMAGE_FULL) + +run: + docker run -d \ + --name $(APP_NAME) \ + -p $(HOST_PORT):$(CONTAINER_PORT) \ + --env-file .env \ + $(IMAGE_FULL) + +stop: + docker stop $(APP_NAME) || true + docker rm $(APP_NAME) || true + +deploy: build tag push stop run \ No newline at end of file