Compare commits
17 Commits
19d13711d2
...
1f0c10b458
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f0c10b458 | |||
| b15630c7ea | |||
| bc044a10c9 | |||
| 558a3198f4 | |||
| 8901941e9f | |||
| c6780b53fc | |||
| d49e756c21 | |||
| 12817a7e82 | |||
| a9baf6da95 | |||
| a2f21e1286 | |||
| 7de0f434c3 | |||
| c74cc19d1b | |||
| 1191ef9f1f | |||
| 26128feb7e | |||
| 48dd10ea05 | |||
| 93fdce1d6e | |||
| b5ace86a03 |
7
.env.example
Normal file
7
.env.example
Normal file
@@ -0,0 +1,7 @@
|
||||
BACKEND_TAG=latest
|
||||
FRONTEND_TAG=latest
|
||||
VITE_API_BASE=/taller/api
|
||||
JENKINS_BASE_URL=http://host.docker.internal:8080
|
||||
JENKINS_JOB_NAME=TallerCiCd
|
||||
JENKINS_USER=
|
||||
JENKINS_TOKEN=
|
||||
@@ -2,13 +2,36 @@ pipeline {
|
||||
agent none
|
||||
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
timestamps()
|
||||
}
|
||||
|
||||
parameters {
|
||||
string(
|
||||
name: 'JENKINS_BASE_URL',
|
||||
defaultValue: 'https://openbokeron.org/jenkins',
|
||||
description: 'Base URL del Jenkins objetivo'
|
||||
)
|
||||
string(
|
||||
name: 'JENKINS_JOB_NAME',
|
||||
defaultValue: 'CD',
|
||||
description: 'Nombre del job que se consulta en Jenkins'
|
||||
)
|
||||
string(
|
||||
name: 'VITE_API_BASE',
|
||||
defaultValue: '/taller/api',
|
||||
description: 'Base path/API para el frontend (build time)'
|
||||
)
|
||||
}
|
||||
|
||||
environment {
|
||||
NODE_OPTIONS = '--max_old_space_size=2048'
|
||||
APP_VERSION = "1.0.${BUILD_NUMBER}"
|
||||
DOCKER_BUILDKIT = '1'
|
||||
JENKINS_BASE_URL = "${params.JENKINS_BASE_URL}"
|
||||
JENKINS_JOB_NAME = "${params.JENKINS_JOB_NAME}"
|
||||
VITE_API_BASE = "${params.VITE_API_BASE}"
|
||||
PYTHONDONTWRITEBYTECODE = 1
|
||||
}
|
||||
|
||||
stages {
|
||||
@@ -18,9 +41,6 @@ pipeline {
|
||||
========================= */
|
||||
|
||||
stage('Backend: test (main)') {
|
||||
when {
|
||||
branch 'main'
|
||||
}
|
||||
agent {
|
||||
docker {
|
||||
image 'python:3.11-slim'
|
||||
@@ -47,9 +67,6 @@ pipeline {
|
||||
========================= */
|
||||
|
||||
stage('Docker: build images') {
|
||||
when {
|
||||
branch 'main'
|
||||
}
|
||||
agent any
|
||||
|
||||
steps {
|
||||
@@ -72,13 +89,12 @@ pipeline {
|
||||
--build-arg GIT_COMMIT=${COMMIT_SHORT} \
|
||||
--build-arg COMMIT_AUTHOR="${COMMIT_AUTHOR}" \
|
||||
--build-arg BUILD_NUMBER=${BUILD_NUMBER} \
|
||||
-t cafeteria-backend:${BUILD_NUMBER} \
|
||||
-t cafeteria-backend:latest \
|
||||
-t cafeteria-backend:${APP_VERSION} \
|
||||
./backend
|
||||
|
||||
docker build \
|
||||
-t cafeteria-frontend:${BUILD_NUMBER} \
|
||||
-t cafeteria-frontend:latest \
|
||||
--build-arg VITE_API_BASE=${VITE_API_BASE} \
|
||||
-t cafeteria-frontend:${APP_VERSION} \
|
||||
./frontend
|
||||
'''
|
||||
}
|
||||
@@ -89,14 +105,7 @@ pipeline {
|
||||
========================= */
|
||||
|
||||
stage('Deploy (docker compose)') {
|
||||
when {
|
||||
branch 'main'
|
||||
}
|
||||
agent any
|
||||
environment {
|
||||
JENKINS_BASE_URL = 'http://jenkins:8080'
|
||||
JENKINS_JOB_NAME = 'Espetos'
|
||||
}
|
||||
steps {
|
||||
withCredentials([
|
||||
usernamePassword(
|
||||
@@ -108,17 +117,16 @@ pipeline {
|
||||
sh '''
|
||||
set -e
|
||||
|
||||
echo "Deploying backend ${BUILD_NUMBER}"
|
||||
echo "Deploying ${APP_VERSION}"
|
||||
|
||||
echo "BACKEND_TAG=${BUILD_NUMBER}" > .env
|
||||
echo "FRONTEND_TAG=${BUILD_NUMBER}" >> .env
|
||||
|
||||
docker-compose up -d
|
||||
BACKEND_TAG=${APP_VERSION} FRONTEND_TAG=${APP_VERSION} docker compose up -d
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
stage('Cleanup') {
|
||||
agent any
|
||||
steps {
|
||||
|
||||
@@ -41,6 +41,11 @@ pipeline {
|
||||
args '-u root'
|
||||
}
|
||||
}
|
||||
|
||||
environment {
|
||||
PYTHONDONTWRITEBYTECODE = 1
|
||||
}
|
||||
|
||||
steps {
|
||||
dir('backend') {
|
||||
sh '''
|
||||
|
||||
11
README.md
11
README.md
@@ -7,6 +7,16 @@
|
||||
- Python 3.11+ y `pip`
|
||||
- Node 18+ y `npm`
|
||||
|
||||
## Configuracion de entorno (local/prod)
|
||||
Variables que usa `docker-compose` y el frontend:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
Notas:
|
||||
- `VITE_API_BASE` por defecto apunta a `/taller/api` y el frontend proxya a la API.
|
||||
- Para Jenkins local en contenedor: `JENKINS_BASE_URL=http://jenkins:8080`. Se hace necesario que back y jenkins estén en la misma red de Docker si se quiere probar en local.
|
||||
- Para VPS: `JENKINS_BASE_URL=https://openbokeron.org/jenkins`.
|
||||
|
||||
## Backend (FastAPI)
|
||||
```bash
|
||||
cd backend
|
||||
@@ -42,6 +52,7 @@ cd frontend
|
||||
npm install
|
||||
npm run dev -- --host --port 5173
|
||||
```
|
||||
Abrir `http://localhost:5173/taller/`.
|
||||
Tests, lint/check:
|
||||
```bash
|
||||
cd frontend
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM python:3.11-slim AS builder
|
||||
FROM docker.io/library/python:3.11-slim AS builder
|
||||
WORKDIR /build
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
@@ -9,7 +9,7 @@ COPY requirements.txt .
|
||||
RUN pip wheel --no-cache-dir --no-deps -r requirements.txt -w /build/wheels
|
||||
|
||||
|
||||
FROM python:3.11-slim
|
||||
FROM docker.io/library/python:3.11-slim
|
||||
WORKDIR /app
|
||||
|
||||
# ---- Build args (desde Jenkins) ----
|
||||
|
||||
@@ -24,7 +24,10 @@ class RuntimeConfig:
|
||||
git_commit: str = os.getenv("GIT_COMMIT", "local")
|
||||
build_number: str = os.getenv("BUILD_NUMBER", "-")
|
||||
commit_author: str = os.getenv("COMMIT_AUTHOR", "local")
|
||||
jenkins_base_url: str = os.getenv("JENKINS_BASE_URL", "localhost:8080")
|
||||
jenkins_base_url: str = os.getenv(
|
||||
"JENKINS_BASE_URL",
|
||||
"http://localhost:8080"
|
||||
).rstrip("/")
|
||||
jenkins_job_name: str = os.getenv("JENKINS_JOB_NAME", "")
|
||||
jenkins_user: str = os.getenv("JENKINS_USER", "")
|
||||
jenkins_token: str = os.getenv("JENKINS_TOKEN", "")
|
||||
|
||||
@@ -2,14 +2,16 @@ services:
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
image: cafeteria-backend:${BACKEND_TAG}
|
||||
image: cafeteria-backend:${BACKEND_TAG:-latest}
|
||||
networks:
|
||||
- cafeteria
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
JENKINS_BASE_URL: ${JENKINS_BASE_URL}
|
||||
JENKINS_JOB_NAME: ${JENKINS_JOB_NAME}
|
||||
JENKINS_USER: ${JENKINS_USER}
|
||||
JENKINS_TOKEN: ${JENKINS_TOKEN}
|
||||
JENKINS_BASE_URL: ${JENKINS_BASE_URL:-http://jenkins:8080}
|
||||
JENKINS_JOB_NAME: ${JENKINS_JOB_NAME:-TallerCiCd}
|
||||
JENKINS_USER: ${JENKINS_USER:-}
|
||||
JENKINS_TOKEN: ${JENKINS_TOKEN:-}
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test:
|
||||
@@ -26,10 +28,21 @@ services:
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
image: cafeteria-frontend:${FRONTEND_TAG}
|
||||
args:
|
||||
VITE_API_BASE: ${VITE_API_BASE:-/taller/api}
|
||||
image: cafeteria-frontend:${FRONTEND_TAG:-latest}
|
||||
networks:
|
||||
- cafeteria
|
||||
ports:
|
||||
- "80:80"
|
||||
- "8081:8081"
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
cafeteria:
|
||||
enable_ipv6: true
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 2001:db8::/64
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
FROM node:20-slim AS build
|
||||
FROM docker.io/library/node:20-slim AS build
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
ARG VITE_API_BASE
|
||||
ENV VITE_API_BASE=$VITE_API_BASE
|
||||
RUN npm install --no-progress
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:1.27-alpine AS final
|
||||
FROM docker.io/library/nginx:1.27-alpine AS final
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
COPY --from=build /app/dist /usr/share/nginx/html/taller
|
||||
EXPOSE 8081
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen 8081;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri /index.html;
|
||||
location = /taller {
|
||||
return 301 /taller/;
|
||||
}
|
||||
|
||||
location /taller/api/ {
|
||||
proxy_pass http://backend:8000/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /taller/ {
|
||||
try_files $uri $uri/ /taller/index.html;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
if (!ENABLE_POLLING) return;
|
||||
|
||||
const pricesInterval = setInterval(fetchPrices, 8000);
|
||||
const ciInterval = setInterval(fetchCiStatus, 10000);
|
||||
const pricesInterval = setInterval(fetchPrices, 180000);
|
||||
const ciInterval = setInterval(fetchCiStatus, 300000);
|
||||
|
||||
return () => {
|
||||
clearInterval(pricesInterval);
|
||||
@@ -467,7 +467,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
<div class="openbokeron-logo">
|
||||
<div class="logo-bubble">
|
||||
<img
|
||||
src="/open-bokeron-logo.png"
|
||||
src={`${import.meta.env.BASE_URL}/open-bokeron-logo.png`}
|
||||
alt="Logo de Open Bokeron"
|
||||
loading="lazy"
|
||||
/>
|
||||
|
||||
@@ -16,5 +16,9 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export const API_BASE = import.meta.env.VITE_API_BASE || 'http://localhost:8000';
|
||||
const baseUrl = import.meta.env.BASE_URL || '/';
|
||||
const defaultApiBase = `${baseUrl.replace(/\/$/, '')}/api`;
|
||||
const rawApiBase = import.meta.env.VITE_API_BASE || defaultApiBase;
|
||||
|
||||
export const API_BASE = rawApiBase.replace(/\/$/, '');
|
||||
export const ENABLE_POLLING = import.meta.env.MODE !== 'test';
|
||||
|
||||
@@ -1,13 +1,34 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [svelte()],
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
globals: true,
|
||||
},
|
||||
server: {
|
||||
port: 5173,
|
||||
},
|
||||
export default defineConfig(({ mode }) => {
|
||||
const env = loadEnv(mode, process.cwd(), 'VITE_');
|
||||
const basePath = '/taller/';
|
||||
const defaultApiBase = `${basePath.replace(/\/$/, '')}/api`;
|
||||
const apiBase = (env.VITE_API_BASE || defaultApiBase).replace(/\/$/, '');
|
||||
const apiProxyPath = apiBase.startsWith('http') ? null : apiBase;
|
||||
|
||||
return {
|
||||
base: basePath,
|
||||
plugins: [svelte()],
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
globals: true,
|
||||
},
|
||||
server: {
|
||||
port: 5173,
|
||||
proxy: apiProxyPath
|
||||
? {
|
||||
[apiProxyPath]: {
|
||||
target: 'http://localhost:8000',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) =>
|
||||
path.startsWith(apiProxyPath)
|
||||
? path.slice(apiProxyPath.length) || '/'
|
||||
: path,
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -3,10 +3,15 @@ FROM jenkins/jenkins:lts
|
||||
USER root
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y docker.io curl \
|
||||
&& curl -L https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64 \
|
||||
-o /usr/local/bin/docker-compose \
|
||||
&& chmod +x /usr/local/bin/docker-compose \
|
||||
&& apt-get install -y ca-certificates curl gnupg \
|
||||
&& install -m 0755 -d /etc/apt/keyrings \
|
||||
&& curl -fsSL https://download.docker.com/linux/debian/gpg \
|
||||
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
|
||||
&& chmod a+r /etc/apt/keyrings/docker.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" \
|
||||
> /etc/apt/sources.list.d/docker.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y docker-ce-cli docker-compose-plugin \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
USER jenkins
|
||||
|
||||
Reference in New Issue
Block a user