TrafficServerLocal/init_project.sh
merios 33c368936e feat: infraestructura base de Traefik + generador de proyectos
- core/: reverse proxy Traefik v3 (HTTP 80 / HTTPS 443)
  - traefik.yml con provider Docker (exposedByDefault: false) y provider file
  - dynamic_tls.yml sanitizado con certificados .local comentados
  - certs/README.md con procedimiento de certificados auto-firmados
- init_project.sh: generador de proyectos base (SRV_DIR configurable)
  - plantilla compose con redireccion HTTP->HTTPS + Let's Encrypt
  - bloque alternativo comentado para dominios .local
- README.md: documentacion integral (puesta en marcha, HTTP/HTTPS,
  troubleshooting y seguridad)
- docs/arquitectura.md: guia de instalacion y gestion de URLs
- docs/http-https.md: referencia de etiquetas Traefik, TLS y certresolver
- .gitignore: excluye .env, acme.json, certificados, datos y respaldos
2026-10-15 11:34:39 -03:00

188 lines
7.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# ==============================================================================
# Script de aprovisionamiento de proyectos Docker (Estructura Limpia)
# ==============================================================================
# Uso: ./init_project.sh <nombre-del-proyecto> <dominio-o-url> [puerto-interno]
#
# Genera en $SRV_DIR/projects/<proyecto> la estructura base:
# app/ -> código fuente, repo o Dockerfile
# data/{db,storage}/ -> volúmenes persistentes
# .env -> variables de entorno (chmod 600)
# docker-compose.yml -> plantilla conectada a proxy_network + etiquetas Traefik
#
# La plantilla incluye HTTP con redirección a HTTPS y HTTPS con Let's Encrypt,
# más un bloque comentado alternativo para dominios .local con certificado
# auto-firmado (ver docs/http-https.md).
# ==============================================================================
set -euo pipefail
# Directorio base de los proyectos. Configurable con SRV_DIR.
BASE_DIR="${SRV_DIR:-$HOME/srv}"
PROJECTS_DIR="$BASE_DIR/projects"
NETWORK_NAME="proxy_network"
# Colores para salida de terminal
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
# Validar argumentos
if [ $# -lt 2 ]; then
echo -e "${RED}Uso:${NC} $0 <nombre-del-proyecto> <dominio-o-url> [puerto-interno]"
echo -e "Ejemplo: $0 api-ventas api.midominio.com 80"
exit 1
fi
PROJECT_NAME="$1"
PROJECT_DOMAIN="$2"
INTERNAL_PORT="${3:-80}"
TARGET_DIR="$PROJECTS_DIR/$PROJECT_NAME"
echo -e "${BLUE}==>${NC} Inicializando entorno para: ${GREEN}$PROJECT_NAME${NC}"
# 1. Asegurar red compartida externa
if ! docker network ls --format '{{.Name}}' | grep -wq "$NETWORK_NAME"; then
echo -e "${YELLOW}Creando red externa $NETWORK_NAME...${NC}"
docker network create "$NETWORK_NAME"
fi
# 2. Comprobar que no exista el proyecto
if [ -d "$TARGET_DIR" ]; then
echo -e "${RED}Error:${NC} El directorio $TARGET_DIR ya existe."
exit 1
fi
# 3. Crear árbol de carpetas limpias
# - app/: Destino para clonar repositorios o poner tu código fuente / Dockerfile
# - data/: Para persistencia de volúmenes de base de datos o archivos
mkdir -p "$PROJECTS_DIR"
mkdir -p "$TARGET_DIR/app"
mkdir -p "$TARGET_DIR/data/db"
mkdir -p "$TARGET_DIR/data/storage"
# Asignar permisos restrictivos al directorio raíz del proyecto
chmod 700 "$TARGET_DIR"
# 4. Crear archivo .env base personalizable
cat <<EOF > "$TARGET_DIR/.env"
# ==============================================================================
# Variables de entorno - $PROJECT_NAME
# ==============================================================================
APP_NAME=$PROJECT_NAME
APP_DOMAIN=$PROJECT_DOMAIN
PORT=$INTERNAL_PORT
# Agrega aquí las variables y secretos de tu proyecto.
# Este archivo tiene permisos 600 y NO debe subirse a Git.
EOF
chmod 600 "$TARGET_DIR/.env"
# 5. Crear plantilla docker-compose.yml lista para tu propia imagen o build local
cat <<EOF > "$TARGET_DIR/docker-compose.yml"
services:
# Servicio principal conectado al Proxy Reverso
web:
# Opción A: Construir tu propio Dockerfile dentro de app/
build:
context: ./app
dockerfile: Dockerfile
# Opción B: Usar una imagen existente de tu registro o Docker Hub
# (comentá el bloque build: de arriba y descomentá la línea image:)
image: ${PROJECT_NAME}:latest
container_name: ${PROJECT_NAME}-web
restart: unless-stopped
env_file:
- .env
volumes:
- ./app:/app
- ./data/storage:/app/storage
networks:
- default
- ${NETWORK_NAME}
labels:
- "traefik.enable=true"
- "traefik.docker.network=${NETWORK_NAME}"
# ======================================================================
# MODO A — Dominio público con Let's Encrypt
# ======================================================================
# 1. Middleware de redirección HTTP -> HTTPS
- "traefik.http.middlewares.${PROJECT_NAME}-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.${PROJECT_NAME}-redirect.redirectscheme.permanent=true"
# 2. Router HTTP (puerto 80): redirige al HTTPS
- "traefik.http.routers.${PROJECT_NAME}-http.rule=Host(\`${PROJECT_DOMAIN}\`)"
- "traefik.http.routers.${PROJECT_NAME}-http.entrypoints=web"
- "traefik.http.routers.${PROJECT_NAME}-http.middlewares=${PROJECT_NAME}-redirect"
# 3. Router HTTPS (puerto 443): atiende el tráfico seguro
- "traefik.http.routers.${PROJECT_NAME}-https.rule=Host(\`${PROJECT_DOMAIN}\`)"
- "traefik.http.routers.${PROJECT_NAME}-https.entrypoints=websecure"
- "traefik.http.routers.${PROJECT_NAME}-https.tls=true"
- "traefik.http.routers.${PROJECT_NAME}-https.tls.certresolver=letsencrypt"
- "traefik.http.routers.${PROJECT_NAME}-https.service=${PROJECT_NAME}-svc"
# 4. Servicio: puerto interno del contenedor
- "traefik.http.services.${PROJECT_NAME}-svc.loadbalancer.server.port=${INTERNAL_PORT}"
# ======================================================================
# MODO B — Dominio .local con certificado auto-firmado
# ======================================================================
# Reemplazá los routers de arriba por estos, agregá el certificado en
# ~/srv/core/data/dynamic_tls.yml y quitá el certresolver (el certificado
# lo aporta el provider "file"). Ver docs/http-https.md
#
# - "traefik.http.routers.${PROJECT_NAME}.rule=Host(\`${PROJECT_DOMAIN}\`)"
# - "traefik.http.routers.${PROJECT_NAME}.entrypoints=websecure"
# - "traefik.http.routers.${PROJECT_NAME}.tls=true"
# - "traefik.http.services.${PROJECT_NAME}.loadbalancer.server.port=${INTERNAL_PORT}"
# ==============================================================================
# Servicios internos (base de datos, colas, etc.)
# ==============================================================================
# IMPORTANTE: conectalos solo a la red "default" para que queden aislados
# del proxy inverso y no sean accesibles desde internet.
#
# db:
# image: postgres:14
# container_name: ${PROJECT_NAME}-pg
# restart: unless-stopped
# networks:
# - default
# environment:
# POSTGRES_USER: \${POSTGRES_USER}
# POSTGRES_PASSWORD: \${POSTGRES_PASSWORD}
# POSTGRES_DB: \${POSTGRES_DB}
# volumes:
# - ./data/db:/var/lib/postgresql
# # Exponer solo en localhost, nunca público:
# ports:
# - "127.0.0.1:5432:5432"
# Redes: default (aislada para servicios internos) y proxy_network (para el reverse proxy)
networks:
default:
driver: bridge
${NETWORK_NAME}:
external: true
EOF
echo -e "${GREEN}✓${NC} Estructura limpia creada en: ${BLUE}$TARGET_DIR${NC}"
echo -e " ├── ${BLUE}app/${NC} <- Pega aquí tu código, Dockerfile o clona tu repo"
echo -e " ├── ${BLUE}data/${NC} <- Directorio para volúmenes persistentes"
echo -e " ├── ${YELLOW}.env${NC} <- Variables de entorno"
echo -e " └── ${YELLOW}docker-compose.yml${NC}<- Orquestación enlazada al proxy"
echo ""
echo -e "${YELLOW}Próximos pasos:${NC}"
echo -e " 1. Copia tus archivos en: ${BLUE}$TARGET_DIR/app/${NC}"
echo -e " 2. Ajusta ${YELLOW}$TARGET_DIR/docker-compose.yml${NC} según tu imagen o build"
echo -e " 3. Levanta el proxy si aún no está: ${GREEN}cd $HOME/srv/core && docker compose up -d${NC}"
echo -e " 4. Inicia el proyecto: ${GREEN}cd $TARGET_DIR && docker compose up -d${NC}"