Cifo_Administrador commited on
Commit ·
c918afd
1
Parent(s): e5f4dd4
chore: prepare Docker deployment for HF Spaces
Browse files- Dockerfile +8 -4
- README.md +10 -0
- backend/src/app.js +6 -3
- backend/src/config.js +3 -1
- entrypoint.sh +9 -0
Dockerfile
CHANGED
|
@@ -16,16 +16,16 @@
|
|
| 16 |
# Build local: docker build -t polysignal .
|
| 17 |
# Run local: docker run -p 7860:7860 --env-file .env polysignal
|
| 18 |
|
| 19 |
-
FROM node:
|
| 20 |
WORKDIR /app
|
| 21 |
|
| 22 |
# Instalar dependencias del backend
|
| 23 |
COPY backend/package*.json ./backend/
|
| 24 |
-
RUN cd backend && npm
|
| 25 |
|
| 26 |
# Instalar dependencias del frontend y construir
|
| 27 |
COPY frontend/package*.json ./frontend/
|
| 28 |
-
RUN cd frontend && npm
|
| 29 |
COPY frontend/ ./frontend/
|
| 30 |
RUN cd frontend && npm run build
|
| 31 |
|
|
@@ -35,7 +35,11 @@ COPY backend/ ./backend/
|
|
| 35 |
# Generar cliente Prisma
|
| 36 |
RUN cd backend && npx prisma generate
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
# Puerto obligatorio de HuggingFace Spaces
|
| 39 |
EXPOSE 7860
|
| 40 |
|
| 41 |
-
CMD ["
|
|
|
|
| 16 |
# Build local: docker build -t polysignal .
|
| 17 |
# Run local: docker run -p 7860:7860 --env-file .env polysignal
|
| 18 |
|
| 19 |
+
FROM node:24-slim
|
| 20 |
WORKDIR /app
|
| 21 |
|
| 22 |
# Instalar dependencias del backend
|
| 23 |
COPY backend/package*.json ./backend/
|
| 24 |
+
RUN cd backend && npm install --only=production
|
| 25 |
|
| 26 |
# Instalar dependencias del frontend y construir
|
| 27 |
COPY frontend/package*.json ./frontend/
|
| 28 |
+
RUN cd frontend && npm install
|
| 29 |
COPY frontend/ ./frontend/
|
| 30 |
RUN cd frontend && npm run build
|
| 31 |
|
|
|
|
| 35 |
# Generar cliente Prisma
|
| 36 |
RUN cd backend && npx prisma generate
|
| 37 |
|
| 38 |
+
# Copiar entrypoint
|
| 39 |
+
COPY entrypoint.sh ./entrypoint.sh
|
| 40 |
+
RUN chmod +x ./entrypoint.sh
|
| 41 |
+
|
| 42 |
# Puerto obligatorio de HuggingFace Spaces
|
| 43 |
EXPOSE 7860
|
| 44 |
|
| 45 |
+
CMD ["./entrypoint.sh"]
|
README.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
# PolySignal
|
| 2 |
|
| 3 |
Dashboard web de inteligencia de mercados de prediccion en tiempo real.
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: PolySignal Hackaton
|
| 3 |
+
emoji: 📊
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: green
|
| 6 |
+
sdk: docker
|
| 7 |
+
app_port: 7860
|
| 8 |
+
pinned: false
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
# PolySignal
|
| 12 |
|
| 13 |
Dashboard web de inteligencia de mercados de prediccion en tiempo real.
|
backend/src/app.js
CHANGED
|
@@ -37,6 +37,7 @@ import statsRoutes from './stats/stats.routes.js';
|
|
| 37 |
import preferencesRoutes from './preferences/preferences.routes.js';
|
| 38 |
import { notFound } from './middlewares/notFound.js';
|
| 39 |
import { errorHandler } from './middlewares/errorHandler.js';
|
|
|
|
| 40 |
|
| 41 |
const app = express();
|
| 42 |
|
|
@@ -66,11 +67,13 @@ app.use('/api/v1/alerts', alertsRoutes);
|
|
| 66 |
app.use('/api/v1/stats', statsRoutes);
|
| 67 |
app.use('/api/v1/preferences', preferencesRoutes);
|
| 68 |
|
| 69 |
-
// Servir frontend estático en producción (HuggingFace Spaces)
|
|
|
|
|
|
|
| 70 |
if (config.NODE_ENV === 'production') {
|
| 71 |
-
app.use(express.static(
|
| 72 |
app.get('/{*path}', (_req, res) => {
|
| 73 |
-
res.sendFile('index.html', { root:
|
| 74 |
});
|
| 75 |
}
|
| 76 |
|
|
|
|
| 37 |
import preferencesRoutes from './preferences/preferences.routes.js';
|
| 38 |
import { notFound } from './middlewares/notFound.js';
|
| 39 |
import { errorHandler } from './middlewares/errorHandler.js';
|
| 40 |
+
import { existsSync } from 'node:fs';
|
| 41 |
|
| 42 |
const app = express();
|
| 43 |
|
|
|
|
| 67 |
app.use('/api/v1/stats', statsRoutes);
|
| 68 |
app.use('/api/v1/preferences', preferencesRoutes);
|
| 69 |
|
| 70 |
+
// Servir frontend estático en producción (HuggingFace Spaces / Docker)
|
| 71 |
+
// Detecta si estamos en la raíz del proyecto o dentro de backend/
|
| 72 |
+
const frontendDist = existsSync('../frontend/dist') ? '../frontend/dist' : 'frontend/dist';
|
| 73 |
if (config.NODE_ENV === 'production') {
|
| 74 |
+
app.use(express.static(frontendDist));
|
| 75 |
app.get('/{*path}', (_req, res) => {
|
| 76 |
+
res.sendFile('index.html', { root: frontendDist });
|
| 77 |
});
|
| 78 |
}
|
| 79 |
|
backend/src/config.js
CHANGED
|
@@ -26,7 +26,9 @@ const schema = z.object({
|
|
| 26 |
JWT_SECRET: z.string().min(32, 'JWT_SECRET must be at least 32 chars'),
|
| 27 |
JWT_EXPIRES_IN: z.string().default('1h'),
|
| 28 |
BCRYPT_ROUNDS: z.coerce.number().int().min(4).max(15).default(10),
|
| 29 |
-
CORS_ORIGIN: z.string().default(
|
|
|
|
|
|
|
| 30 |
LOG_LEVEL: z.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']).default('info'),
|
| 31 |
HF_TOKEN: z.string().optional(),
|
| 32 |
HF_SPACE_MODERNFINBERT_URL: z.string().optional(),
|
|
|
|
| 26 |
JWT_SECRET: z.string().min(32, 'JWT_SECRET must be at least 32 chars'),
|
| 27 |
JWT_EXPIRES_IN: z.string().default('1h'),
|
| 28 |
BCRYPT_ROUNDS: z.coerce.number().int().min(4).max(15).default(10),
|
| 29 |
+
CORS_ORIGIN: z.string().default(
|
| 30 |
+
process.env.NODE_ENV === 'production' ? '*' : 'http://localhost:5173'
|
| 31 |
+
),
|
| 32 |
LOG_LEVEL: z.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']).default('info'),
|
| 33 |
HF_TOKEN: z.string().optional(),
|
| 34 |
HF_SPACE_MODERNFINBERT_URL: z.string().optional(),
|
entrypoint.sh
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
set -e
|
| 3 |
+
|
| 4 |
+
echo "[entrypoint] Running Prisma migrate deploy..."
|
| 5 |
+
cd backend
|
| 6 |
+
npx prisma migrate deploy
|
| 7 |
+
|
| 8 |
+
echo "[entrypoint] Starting PolySignal server..."
|
| 9 |
+
exec node src/index.js
|