Agrega el credito "Laboratorio de investigacion en Software Libre Gugler - FCyT" en el encabezado y la seccion Licencia del README, y como pie en ambos documentos de docs/. Se documenta la exencion institucional en la politica de publicacion anonima: el nombre del laboratorio y git.gugler.com.ar son publicos por decision propia y no se anonimizan. El verificador recibe una lista blanca que separa autores institucionales de los que hay que revisar, y excluye el dominio del laboratorio del filtro de emails.
6.0 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:
- Entrar a
http://<IP-SERVIDOR>:81. - 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
- Domain Names:
- Pestaña SSL → Request a new SSL Certificate → Force SSL.
- 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 |
Autoría: Laboratorio de investigacion en Software Libre Gugler - FCyT.
Distribuido bajo GPL-3.0 (ver LICENSE).