TrafficServerLocal/docs/arquitectura.md
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

5.8 KiB

Arquitectura del servidor y gestión de URLs

Guía de instalación del entorno base en el host (~/srv), despliegue de la infraestructura común y alta de proyectos Docker enlazados al proxy inverso.

Documento de referencia. Para el detalle fino de etiquetas TLS ver http-https.md.


1. Configuración inicial del host

1.1 Estructura base y red Docker

mkdir -p ~/srv/core ~/srv/projects
docker network create proxy_network

Permisos para usar Docker sin sudo:

sudo usermod -aG docker "$USER"
newgrp docker

1.2 Habilitar el script generador

chmod +x ~/srv/init_project.sh

2. Puesta en marcha del reverse proxy (~/srv/core)

Opción A — Traefik (detección automática por etiquetas)

~/srv/core/docker-compose.yml:

services:
  traefik:
    image: traefik:v3.0
    container_name: core-proxy
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
    networks:
      - proxy_network

networks:
  proxy_network:
    external: true

Configuración estática ~/srv/core/data/traefik.yml:

api:
  dashboard: true
  insecure: true

entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    network: "proxy_network"
    exposedByDefault: false
  file:
    filename: "/etc/traefik/dynamic_tls.yml"
    watch: true

Inicialización del almacenamiento de certificados:

mkdir -p ~/srv/core/data
touch ~/srv/core/data/acme.json
chmod 600 ~/srv/core/data/acme.json

Arranque:

cd ~/srv/core && docker compose up -d

Opción B — Nginx Proxy Manager (panel web)

Misma idea, pero la configuración se hace desde la interfaz:

  1. Entrar a http://<IP-SERVIDOR>:81.
  2. Hosts → Proxy Hosts → Add Proxy Host.
    • Domain Names: api.midominio.com
    • Scheme: http
    • Forward Hostname / IP: nombre del contenedor en proxy_network
    • Forward Port: puerto interno del contenedor
    • Block Common Exploits: activado
  3. Pestaña SSL → Request a new SSL Certificate → Force SSL.
  4. Save.

3. Alta de proyectos

Paso 1 — Crear la estructura limpia

~/srv/init_project.sh api-ventas api.midominio.com 80

Genera:

~/srv/projects/api-ventas/
├── app/                  # Código, repo o Dockerfile
├── data/
│   ├── db/
│   └── storage/
├── .env                  # Variables de entorno (chmod 600)
└── docker-compose.yml    # Plantilla conectada a proxy_network

Paso 2 — Colocar el proyecto

# Clonando un repositorio
git clone https://github.com/tu-usuario/api-ventas.git ~/srv/projects/api-ventas/app/

# O copiando archivos locales
cp -r /ruta/a/tus/archivos/* ~/srv/projects/api-ventas/app/

Paso 3 — Ajustar docker-compose.yml

  • Build local: descomentar
    build:
      context: ./app
      dockerfile: Dockerfile
    
  • Imagen ya publicada: reemplazar image: <proyecto>:latest
  • Servicios adicionales (Postgres, Redis): agregarlos en el mismo archivo usando la red default, así quedan aislados del proxy.

Paso 4 — Levantar

cd ~/srv/projects/api-ventas
docker compose up -d

Paso 5 — Post-instalación (opcional, apps Laravel)

docker exec -it <proyecto>-web composer install --no-interaction --prefer-dist
docker exec -it <proyecto>-web php artisan key:generate --force
docker exec -it <proyecto>-web php artisan migrate --force
docker exec -it <proyecto>-web php artisan optimize:clear

Verificar permisos si el usuario www-data no puede escribir:

docker exec -it <proyecto>-web chown -R www-data:www-data /var/www/<app>/storage
docker exec -it <proyecto>-web chmod -R 775 /var/www/<app>/storage /var/www/<app>/bootstrap/cache

4. Dónde y cómo se registran las URLs

Traefik (automático)

El registro se hace con etiquetas en el docker-compose.yml del proyecto:

labels:
  - "traefik.enable=true"
  - "traefik.docker.network=proxy_network"
  - "traefik.http.routers.api-ventas.rule=Host(`api.midominio.com`)"
  - "traefik.http.routers.api-ventas.entrypoints=websecure"
  - "traefik.http.routers.api-ventas.tls=true"
  - "traefik.http.routers.api-ventas.tls.certresolver=letsencrypt"
  - "traefik.http.services.api-ventas.loadbalancer.server.port=80"

Traefik lee el socket de Docker, detecta el contenedor, genera el enrutamiento y solicita el certificado SSL automáticamente.

Nginx Proxy Manager (panel web)

Ver Opción B.


5. Copias de seguridad

Los respaldos se guardan fuera de los repositorios Git:

# PostgreSQL
docker exec <cont-pg> pg_dump -U <user> <db> > ~/srv/backups/<proyecto>-$(date +%F).sql

# MySQL
docker exec <cont-mysql> mysqldump -u<user> -p <db> > ~/srv/backups/<proyecto>-$(date +%F).sql

# Archivos
tar czf ~/srv/backups/<proyecto>-files-$(date +%F).tar.gz ~/srv/projects/<proyecto>/data

Sugerencia de rotación (crontab diario a las 3:00):

0 3 * * * /usr/local/bin/backup-proyectos.sh >> ~/srv/backups/backup.log 2>&1

6. Resumen de convenciones

Elemento Convención
Carpeta de proyecto ~/srv/projects/<nombre>/
Nombre del contenedor <nombre>-web
Red del proxy proxy_network (externa)
Red interna default (bridge, aislada)
Secretos ~/srv/projects/<nombre>/.env con chmod 600
Dominios locales <proyecto>.local
Certificados .local ~/srv/core/data/certs/ + dynamic_tls.yml
Certificados públicos Let's Encrypt vía acme.json