diff --git a/.agente/proyecto_estructura.md b/.agente/proyecto_estructura.md index c52a420..978039a 100644 --- a/.agente/proyecto_estructura.md +++ b/.agente/proyecto_estructura.md @@ -41,6 +41,9 @@ app_compartir/ │ └── viewer.html # Visor universal (imágenes, video, audio, PDF, código) ├── .env.example ├── .gitignore +├── desplegar.sh # Script de compilación y despliegue (máquina dev) +├── init.sh # Script ejecutor local en el servidor +├── servers.conf.example # Plantilla de credenciales SSH para despliegue ├── go.mod ├── go.sum ├── main.go # Punto de entrada y servidor HTTP Go diff --git a/.gitignore b/.gitignore index 6e8f18f..eff7c89 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,9 @@ uploads/ *.db-wal *.db-shm -# Variables de entorno +# Variables de entorno y credenciales de despliegue .env +servers.conf # Sistema operativo .DS_Store diff --git a/README.md b/README.md index 9ae7c30..19bcf52 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,30 @@ go test -v ./... --- +## 🚢 Despliegue a Producción (`drop.sigmac.app`) + +El proyecto sigue la convención estándar del ecosistema Telcotronics basada en dos scripts: + +1. **Configurar destino:** + ```bash + cp servers.conf.example servers.conf + # Ajustar HOST (192.168.10.160), SSH_USER y REMOTE_DIR si es necesario + ``` + +2. **Lanzar despliegue desde tu máquina:** + ```bash + ./desplegar.sh + # O por parámetro directo: ./desplegar.sh todo + ``` + El script compila localmente el binario release para Linux amd64 (`CGO_ENABLED=0`), transfiere el binario y las plantillas a `server-webapps` CT 132 (`192.168.10.160`) y ejecuta `init.sh` para arrancar el servidor en el puerto `2006` en segundo plano. + +3. **Ver logs en el servidor:** + ```bash + ./desplegar.sh estado + ``` + +--- + ## 📂 Estructura del Código ```text diff --git a/desplegar.sh b/desplegar.sh new file mode 100755 index 0000000..2debd78 --- /dev/null +++ b/desplegar.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env bash +# desplegar.sh — Corre desde la máquina de desarrollo +# Compila localmente + sube binario/plantillas vía scp/rsync + ejecuta init.sh en el servidor + +set -Eeuo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +CONF_FILE="${DROP_SERVERS_CONF:-$SCRIPT_DIR/servers.conf}" + +cargar_conf() { + if [[ ! -f "$CONF_FILE" ]]; then + echo "❌ Error: Falta $CONF_FILE" >&2 + echo "👉 Crea uno copiando la plantilla: cp servers.conf.example servers.conf" >&2 + exit 1 + fi + + # Cargar configuración + # shellcheck disable=SC1090 + source "$CONF_FILE" + + : "${HOST:?servers.conf debe definir HOST (ej: 192.168.10.160)}" + : "${SSH_USER:?servers.conf debe definir SSH_USER (ej: user_apps)}" + : "${REMOTE_DIR:?servers.conf debe definir REMOTE_DIR (ej: /home/user_apps/apps/drop_sigmac_app)}" + SSH_PORT="${SSH_PORT:-22}" + SERVIDOR="${SSH_USER}@${HOST}" + + if [[ -n "${DEPLOY_SSH_PASSWORD:-}" ]]; then + command -v sshpass >/dev/null 2>&1 || { echo "DEPLOY_SSH_PASSWORD requiere sshpass instalado." >&2; exit 1; } + SSH=(sshpass -e ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=15 -p "$SSH_PORT") + SCP=(sshpass -e scp -o StrictHostKeyChecking=accept-new -o ConnectTimeout=15 -P "$SSH_PORT") + else + SSH=(ssh -o BatchMode=yes -o ConnectTimeout=15 -p "$SSH_PORT") + SCP=(scp -o BatchMode=yes -o ConnectTimeout=15 -P "$SSH_PORT") + fi +} + +remote() { "${SSH[@]}" "$SERVIDOR" "$@"; } +copy() { "${SCP[@]}" "$@"; } + +# 1. Compilar +compilar() { + echo "" + echo "==================================================" + echo "🔨 Compilando binario Go autónomo (Linux amd64)..." + echo "==================================================" + cd "$SCRIPT_DIR" + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o app_compartir main.go + echo "✅ Compilación exitosa: $SCRIPT_DIR/app_compartir" + ls -lh "$SCRIPT_DIR/app_compartir" +} + +# 2. Preparar directorios remotos +preparar_remoto() { + echo "" + echo "📂 Preparando estructura de directorios en $SERVIDOR:$REMOTE_DIR..." + remote "mkdir -p '$REMOTE_DIR/web/templates' '$REMOTE_DIR/data/uploads'" + echo "✅ Directorios listos" +} + +# 3. Subir archivos +subir() { + compilar + preparar_remoto + + echo "" + echo "🚀 Subiendo binario, plantillas y scripts al servidor..." + copy "$SCRIPT_DIR/app_compartir" "$SCRIPT_DIR/init.sh" "$SCRIPT_DIR/.env.example" "$SERVIDOR:$REMOTE_DIR/" + copy "$SCRIPT_DIR/web/templates/"*.html "$SERVIDOR:$REMOTE_DIR/web/templates/" + remote "chmod 0755 '$REMOTE_DIR/app_compartir' '$REMOTE_DIR/init.sh'" + echo "✅ Archivos sincronizados en $REMOTE_DIR" +} + +# 4. Reiniciar servicio en el servidor +reiniciar() { + echo "" + echo "🔄 Ejecutando init.sh en $SERVIDOR..." + remote "bash '$REMOTE_DIR/init.sh'" +} + +# 5. Despliegue completo +todo() { + subir + reiniciar + echo "" + echo "==================================================" + echo "🎉 ¡Despliegue completado con éxito!" + echo "🌐 Dominio público: https://drop.sigmac.app" + echo "🎯 Destino interno: http://$HOST:2006" + echo "==================================================" +} + +# 6. Ver estado y logs +estado() { + echo "" + echo "📊 Estado del servidor en $SERVIDOR:" + remote " + if tmux has-session -t drop-sigmac-app 2>/dev/null; then + echo '==> Sesión tmux drop-sigmac-app activa:' + tmux capture-pane -pt drop-sigmac-app | tail -n 25 + elif systemctl is-active --quiet drop-sigmac-app.service 2>/dev/null; then + echo '==> Servicio systemd drop-sigmac-app activo:' + systemctl status drop-sigmac-app.service --no-pager + else + echo '⚠️ No se detectó proceso activo en tmux ni systemd.' + fi + " +} + +# Menú interactivo o por argumentos +ACCION="${1:-menu}" + +case "$ACCION" in + compilar|build) compilar; exit 0 ;; + subir|sync) cargar_conf; subir; exit 0 ;; + reiniciar|restart) cargar_conf; reiniciar; exit 0 ;; + todo|all) cargar_conf; todo; exit 0 ;; + estado|status|logs) cargar_conf; estado; exit 0 ;; +esac + +cargar_conf + +while true; do + echo "" + echo "==================================================" + echo "🚀 Despliegue de drop.sigmac.app ($SERVIDOR)" + echo "==================================================" + echo "1) Todo (Compilar + Subir + Reiniciar servidor)" + echo "2) Solo compilar binario Go" + echo "3) Solo subir binario y plantillas" + echo "4) Solo reiniciar servidor remoto (init.sh)" + echo "5) Ver estado y últimos logs en el servidor" + echo "6) Salir" + echo "==================================================" + read -rp "Selecciona una opción [1-6]: " OPCION + + case "$OPCION" in + 1) todo; break ;; + 2) compilar ;; + 3) subir ;; + 4) reiniciar ;; + 5) estado ;; + 6|q|exit) echo "Operación cancelada."; exit 0 ;; + *) echo "Opción inválida." ;; + esac +done diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..8f866d9 --- /dev/null +++ b/init.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# init.sh — Ejecutor en el servidor de producción (192.168.10.160) +# Solo arranca lo que ya está instalado. No compila, no sube código. + +set -euo pipefail + +SESSION="drop-sigmac-app" +SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" +cd "$SCRIPT_DIR" + +# 1. Asegurar existencia de .env +if [[ ! -f "$SCRIPT_DIR/.env" ]]; then + if [[ -f "$SCRIPT_DIR/.env.example" ]]; then + echo "==> Creando .env inicial desde .env.example..." + cp "$SCRIPT_DIR/.env.example" "$SCRIPT_DIR/.env" + # Configurar puerto de producción 2006 y URL por defecto + sed -i 's/^PORT=.*/PORT=2006/' "$SCRIPT_DIR/.env" + sed -i 's|^BASE_URL=.*|BASE_URL=https://drop.sigmac.app|' "$SCRIPT_DIR/.env" + else + echo "⚠️ Advertencia: No se encontró .env ni .env.example." + fi +fi + +# 2. Asegurar directorios de datos y uploads +mkdir -p "$SCRIPT_DIR/data/uploads" + +# 3. Permisos de ejecución al binario +chmod +x "$SCRIPT_DIR/app_compartir" + +# 4. Modo de arranque: Si existe servicio systemd, usarlo; de lo contrario, sesión tmux +if systemctl is-active --quiet drop-sigmac-app.service 2>/dev/null || [ -f /etc/systemd/system/drop-sigmac-app.service ]; then + echo "==> Reiniciando servicio systemd 'drop-sigmac-app.service'..." + sudo systemctl restart drop-sigmac-app.service + sudo systemctl status drop-sigmac-app.service --no-pager + exit 0 +fi + +# 5. Arranque en tmux (si no hay systemd) +echo "==> Deteniendo sesión tmux anterior si existe..." +tmux kill-session -t "$SESSION" 2>/dev/null || true + +echo "==> Iniciando drop.sigmac.app en sesión tmux '$SESSION'..." +tmux new-session -d -s "$SESSION" "cd '$SCRIPT_DIR' && ./app_compartir" + +sleep 1 +if tmux has-session -t "$SESSION" 2>/dev/null; then + echo "✅ Servidor drop.sigmac.app iniciado con éxito en sesión tmux '$SESSION'." + echo " Puerto: $(grep '^PORT=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d= -f2 || echo '2006')" + echo " Para ver logs en vivo: tmux attach -t $SESSION" + echo " Para salir del log sin matar el proceso: Ctrl+B, luego D" +else + echo "❌ Error al iniciar la sesión tmux." + exit 1 +fi diff --git a/servers.conf.example b/servers.conf.example new file mode 100644 index 0000000..d58a191 --- /dev/null +++ b/servers.conf.example @@ -0,0 +1,8 @@ +# servers.conf.example — Configuración de despliegue para drop.sigmac.app +# Copiar este archivo como 'servers.conf' y completar con los valores de acceso. +# ⚠️ servers.conf NUNCA debe commitearse en Git. + +HOST="192.168.10.160" +SSH_USER="user_apps" +SSH_PORT="22" +REMOTE_DIR="/home/user_apps/apps/drop_sigmac_app"