feat: añadir soporte Docker para despliegues
- Crear Dockerfile multi-stage para optimizar tamaño - Crear docker-compose.yml para gestión fácil - Crear deploy-docker.sh script de despliegue - Crear .dockerignore para optimizar build - Crear GitHub Actions workflow para auto-deploy Docker - Crear DEPLOYMENT_DOCKER.md con documentación completa - Actualizar .gitignore para Docker - Puerto 8607 configurado en Docker - Health check incluido en contenedor - Multi-stage build para reducir tamaño de imagen final
This commit is contained in:
parent
8ba7ed9734
commit
6211f51f36
69
.dockerignore
Normal file
69
.dockerignore
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
# Dependencias
|
||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
# Build outputs
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Desarrollo
|
||||||
|
.env.local
|
||||||
|
.env.development
|
||||||
|
.env.test
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
.localized
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Backups y temporales
|
||||||
|
_BACKUP_MD
|
||||||
|
backup_*
|
||||||
|
deleted_*
|
||||||
|
imagenes-pendientes
|
||||||
|
MANUAL_TES_DIGITAL
|
||||||
|
|
||||||
|
# Documentación temporal
|
||||||
|
docs/backup
|
||||||
|
docs/archive
|
||||||
|
*.md.bak
|
||||||
|
|
||||||
|
# Scripts de desarrollo
|
||||||
|
*.py
|
||||||
|
*.sh
|
||||||
|
!deploy-docker.sh
|
||||||
|
|
||||||
|
# Configuraciones no necesarias en Docker
|
||||||
|
ecosystem.config.js
|
||||||
|
webhook-deploy.sh
|
||||||
|
.github
|
||||||
|
vercel.json
|
||||||
|
netlify.toml
|
||||||
|
nginx.conf.example
|
||||||
|
|
||||||
|
# Documentación (opcional, comentar si quieres incluirla)
|
||||||
|
# docs/
|
||||||
|
# *.md
|
||||||
17
Dockerfile
17
Dockerfile
|
|
@ -1,4 +1,6 @@
|
||||||
# Multi-stage build para EMERGES TES
|
# Dockerfile para EMERGES TES
|
||||||
|
# Multi-stage build para optimizar tamaño de imagen
|
||||||
|
|
||||||
# Stage 1: Build
|
# Stage 1: Build
|
||||||
FROM node:18-alpine AS builder
|
FROM node:18-alpine AS builder
|
||||||
|
|
||||||
|
|
@ -18,7 +20,6 @@ RUN npm run build
|
||||||
|
|
||||||
# Verificar que el build se completó
|
# Verificar que el build se completó
|
||||||
RUN test -d dist || (echo "Error: dist directory not found" && exit 1)
|
RUN test -d dist || (echo "Error: dist directory not found" && exit 1)
|
||||||
RUN test "$(ls -A dist)" || (echo "Error: dist directory is empty" && exit 1)
|
|
||||||
|
|
||||||
# Stage 2: Production
|
# Stage 2: Production
|
||||||
FROM node:18-alpine AS production
|
FROM node:18-alpine AS production
|
||||||
|
|
@ -26,21 +27,15 @@ FROM node:18-alpine AS production
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Instalar serve globalmente para servir archivos estáticos
|
# Instalar serve globalmente para servir archivos estáticos
|
||||||
RUN npm install -g serve@14.2.1
|
RUN npm install -g serve
|
||||||
|
|
||||||
# Copiar archivos construidos desde builder
|
# Copiar archivos build desde builder
|
||||||
COPY --from=builder /app/dist ./dist
|
COPY --from=builder /app/dist ./dist
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
# Copiar package.json para mantener metadata (opcional)
|
|
||||||
COPY --from=builder /app/package.json ./package.json
|
|
||||||
|
|
||||||
# Exponer puerto 8607
|
# Exponer puerto 8607
|
||||||
EXPOSE 8607
|
EXPOSE 8607
|
||||||
|
|
||||||
# Variables de entorno
|
|
||||||
ENV NODE_ENV=production
|
|
||||||
ENV PORT=8607
|
|
||||||
|
|
||||||
# Health check
|
# Health check
|
||||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
CMD node -e "require('http').get('http://localhost:8607', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
|
CMD node -e "require('http').get('http://localhost:8607', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
|
||||||
|
|
|
||||||
144
deploy-docker.sh
144
deploy-docker.sh
|
|
@ -1,8 +1,9 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Script de deploy con Docker para EMERGES TES
|
# Script de deploy con Docker para EMERGES TES
|
||||||
# Uso: ./deploy-docker.sh [--rebuild] [--stop] [--logs]
|
# Uso: ./deploy-docker.sh [--skip-git] [--rebuild]
|
||||||
# Requisitos: Docker, Docker Compose
|
# Requisitos: docker, docker-compose
|
||||||
|
# Puerto: 8607
|
||||||
|
|
||||||
set -e # Salir si hay error
|
set -e # Salir si hay error
|
||||||
|
|
||||||
|
|
@ -14,83 +15,55 @@ BLUE='\033[0;34m'
|
||||||
NC='\033[0m' # No Color
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
# Configuración
|
# Configuración
|
||||||
|
PORT=8607
|
||||||
CONTAINER_NAME="emerges-tes"
|
CONTAINER_NAME="emerges-tes"
|
||||||
IMAGE_NAME="emerges-tes"
|
IMAGE_NAME="emerges-tes"
|
||||||
PORT=8607
|
|
||||||
COMPOSE_FILE="docker-compose.yml"
|
COMPOSE_FILE="docker-compose.yml"
|
||||||
|
|
||||||
echo -e "${BLUE}════════════════════════════════════════${NC}"
|
echo -e "${BLUE}════════════════════════════════════════${NC}"
|
||||||
echo -e "${BLUE}🐳 Deploy Docker de EMERGES TES${NC}"
|
echo -e "${BLUE}🐳 Deploy Docker de EMERGES TES (Puerto $PORT)${NC}"
|
||||||
echo -e "${BLUE}════════════════════════════════════════${NC}"
|
echo -e "${BLUE}════════════════════════════════════════${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Verificar Docker
|
# Verificar Docker
|
||||||
if ! command -v docker &> /dev/null; then
|
if ! command -v docker &> /dev/null; then
|
||||||
echo -e "${RED}❌ Error: Docker no está instalado${NC}"
|
echo -e "${RED}❌ Error: Docker no está instalado${NC}"
|
||||||
|
echo -e "${YELLOW} Instala Docker: https://docs.docker.com/get-docker/${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
|
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
|
||||||
echo -e "${RED}❌ Error: Docker Compose no está instalado${NC}"
|
echo -e "${RED}❌ Error: docker-compose no está instalado${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Detectar comando de compose (docker-compose o docker compose)
|
# Detectar comando docker-compose
|
||||||
if command -v docker-compose &> /dev/null; then
|
if docker compose version &> /dev/null; then
|
||||||
COMPOSE_CMD="docker-compose"
|
DOCKER_COMPOSE="docker compose"
|
||||||
else
|
else
|
||||||
COMPOSE_CMD="docker compose"
|
DOCKER_COMPOSE="docker-compose"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${GREEN}✅ Docker detectado: $(docker --version)${NC}"
|
# Verificar si se debe saltar git pull
|
||||||
echo -e "${GREEN}✅ Docker Compose detectado${NC}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Procesar argumentos
|
|
||||||
REBUILD=false
|
|
||||||
STOP=false
|
|
||||||
LOGS=false
|
|
||||||
SKIP_GIT=false
|
SKIP_GIT=false
|
||||||
|
REBUILD=false
|
||||||
|
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
case $arg in
|
case $arg in
|
||||||
--rebuild)
|
|
||||||
REBUILD=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--stop)
|
|
||||||
STOP=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--logs)
|
|
||||||
LOGS=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--skip-git)
|
--skip-git)
|
||||||
SKIP_GIT=true
|
SKIP_GIT=true
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--rebuild)
|
||||||
|
REBUILD=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
# Argumento desconocido
|
shift
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# Si se solicita detener
|
|
||||||
if [ "$STOP" = true ]; then
|
|
||||||
echo -e "${YELLOW}🛑 Deteniendo contenedor...${NC}"
|
|
||||||
$COMPOSE_CMD down
|
|
||||||
echo -e "${GREEN}✅ Contenedor detenido${NC}"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Si se solicitan logs
|
|
||||||
if [ "$LOGS" = true ]; then
|
|
||||||
echo -e "${YELLOW}📋 Mostrando logs...${NC}"
|
|
||||||
$COMPOSE_CMD logs -f
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 1. Actualizar código desde git (si no se salta)
|
# 1. Actualizar código desde git (si no se salta)
|
||||||
if [ "$SKIP_GIT" = false ]; then
|
if [ "$SKIP_GIT" = false ]; then
|
||||||
echo -e "${YELLOW}📥 [1/4] Actualizando código desde git...${NC}"
|
echo -e "${YELLOW}📥 [1/4] Actualizando código desde git...${NC}"
|
||||||
|
|
@ -103,58 +76,57 @@ else
|
||||||
echo -e "${YELLOW}⏭️ [1/4] Saltando actualización de git (--skip-git)${NC}"
|
echo -e "${YELLOW}⏭️ [1/4] Saltando actualización de git (--skip-git)${NC}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2. Verificar que Dockerfile existe
|
# 2. Detener contenedor existente (si existe)
|
||||||
echo -e "${YELLOW}🔍 [2/4] Verificando Dockerfile...${NC}"
|
echo -e "${YELLOW}🛑 [2/4] Deteniendo contenedor existente...${NC}"
|
||||||
if [ ! -f "Dockerfile" ]; then
|
$DOCKER_COMPOSE down 2>/dev/null || true
|
||||||
echo -e "${RED}❌ Error: Dockerfile no encontrado${NC}"
|
docker stop "$CONTAINER_NAME" 2>/dev/null || true
|
||||||
exit 1
|
docker rm "$CONTAINER_NAME" 2>/dev/null || true
|
||||||
fi
|
echo -e "${GREEN}✅ Contenedor detenido${NC}"
|
||||||
if [ ! -f "$COMPOSE_FILE" ]; then
|
|
||||||
echo -e "${RED}❌ Error: $COMPOSE_FILE no encontrado${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo -e "${GREEN}✅ Archivos Docker encontrados${NC}"
|
|
||||||
|
|
||||||
# 3. Construir imagen (si es necesario)
|
# 3. Construir imagen Docker
|
||||||
|
echo -e "${YELLOW}🔨 [3/4] Construyendo imagen Docker...${NC}"
|
||||||
if [ "$REBUILD" = true ]; then
|
if [ "$REBUILD" = true ]; then
|
||||||
echo -e "${YELLOW}🔨 [3/4] Reconstruyendo imagen Docker...${NC}"
|
echo -e "${YELLOW} Forzando rebuild completo (--rebuild)${NC}"
|
||||||
$COMPOSE_CMD build --no-cache
|
$DOCKER_COMPOSE build --no-cache
|
||||||
echo -e "${GREEN}✅ Imagen reconstruida${NC}"
|
|
||||||
else
|
else
|
||||||
echo -e "${YELLOW}🔨 [3/4] Construyendo/actualizando imagen Docker...${NC}"
|
$DOCKER_COMPOSE build
|
||||||
$COMPOSE_CMD build
|
|
||||||
echo -e "${GREEN}✅ Imagen lista${NC}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 4. Iniciar/Reiniciar contenedor
|
if [ $? -eq 0 ]; then
|
||||||
echo -e "${YELLOW}🚀 [4/4] Iniciando contenedor...${NC}"
|
echo -e "${GREEN}✅ Imagen construida exitosamente${NC}"
|
||||||
$COMPOSE_CMD up -d
|
else
|
||||||
|
echo -e "${RED}❌ Error al construir imagen${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Esperar a que el contenedor esté listo
|
# 4. Iniciar contenedor
|
||||||
echo -e "${YELLOW}⏳ Esperando a que el contenedor esté listo...${NC}"
|
echo -e "${YELLOW}🚀 [4/4] Iniciando contenedor...${NC}"
|
||||||
|
$DOCKER_COMPOSE up -d
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}✅ Contenedor iniciado${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ Error al iniciar contenedor${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Esperar un momento para que el contenedor inicie
|
||||||
sleep 3
|
sleep 3
|
||||||
|
|
||||||
# Verificar estado
|
# Verificar estado
|
||||||
if docker ps | grep -q "$CONTAINER_NAME"; then
|
echo ""
|
||||||
echo -e "${GREEN}✅ Contenedor iniciado correctamente${NC}"
|
echo -e "${GREEN}✅ Deploy completado exitosamente${NC}"
|
||||||
else
|
echo -e "${BLUE}📊 Estado del contenedor:${NC}"
|
||||||
echo -e "${RED}❌ Error: El contenedor no está corriendo${NC}"
|
docker ps | grep "$CONTAINER_NAME" || docker ps -a | grep "$CONTAINER_NAME"
|
||||||
echo -e "${YELLOW}📋 Últimos logs:${NC}"
|
|
||||||
$COMPOSE_CMD logs --tail=50
|
echo ""
|
||||||
exit 1
|
echo -e "${GREEN}🌐 Aplicación disponible en: http://localhost:$PORT${NC}"
|
||||||
fi
|
echo -e "${GREEN}📝 Logs: docker logs $CONTAINER_NAME${NC}"
|
||||||
|
echo -e "${GREEN}📊 Logs en tiempo real: docker logs -f $CONTAINER_NAME${NC}"
|
||||||
|
echo -e "${GREEN}🛑 Detener: docker-compose down${NC}"
|
||||||
|
echo -e "${GREEN}🔄 Reiniciar: docker-compose restart${NC}"
|
||||||
|
|
||||||
# Mostrar información
|
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
||||||
echo -e "${GREEN}🎉 Deploy Docker completado!${NC}"
|
echo -e "${GREEN}🎉 Deploy Docker completado!${NC}"
|
||||||
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
||||||
echo ""
|
|
||||||
echo -e "${BLUE}📊 Estado del contenedor:${NC}"
|
|
||||||
docker ps | grep "$CONTAINER_NAME" || true
|
|
||||||
echo ""
|
|
||||||
echo -e "${GREEN}🌐 Aplicación disponible en: http://localhost:$PORT${NC}"
|
|
||||||
echo -e "${GREEN}📝 Logs: $COMPOSE_CMD logs -f${NC}"
|
|
||||||
echo -e "${GREEN}📊 Estado: docker ps | grep $CONTAINER_NAME${NC}"
|
|
||||||
echo -e "${GREEN}🛑 Detener: $COMPOSE_CMD down${NC}"
|
|
||||||
echo ""
|
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,14 @@ services:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
target: production
|
||||||
container_name: emerges-tes
|
container_name: emerges-tes
|
||||||
ports:
|
ports:
|
||||||
- "8607:8607"
|
- "8607:8607"
|
||||||
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- PORT=8607
|
- PORT=8607
|
||||||
restart: unless-stopped
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "node", "-e", "require('http').get('http://localhost:8607', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
|
test: ["CMD", "node", "-e", "require('http').get('http://localhost:8607', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
|
|
@ -19,8 +20,8 @@ services:
|
||||||
retries: 3
|
retries: 3
|
||||||
start_period: 5s
|
start_period: 5s
|
||||||
labels:
|
labels:
|
||||||
- "com.emerges.app=emerges-tes"
|
- "com.emerges-tes.description=EMERGES TES - Protocolo Rápido"
|
||||||
- "com.emerges.version=1.0"
|
- "com.emerges-tes.version=1.0"
|
||||||
networks:
|
networks:
|
||||||
- emerges-network
|
- emerges-network
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue