- 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
246 lines
5.8 KiB
Markdown
246 lines
5.8 KiB
Markdown
# 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`](http-https.md).
|
|
|
|
---
|
|
|
|
## 1. Configuración inicial del host
|
|
|
|
### 1.1 Estructura base y red Docker
|
|
|
|
```bash
|
|
mkdir -p ~/srv/core ~/srv/projects
|
|
docker network create proxy_network
|
|
```
|
|
|
|
Permisos para usar Docker sin `sudo`:
|
|
|
|
```bash
|
|
sudo usermod -aG docker "$USER"
|
|
newgrp docker
|
|
```
|
|
|
|
### 1.2 Habilitar el script generador
|
|
|
|
```bash
|
|
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`:
|
|
|
|
```yaml
|
|
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`:
|
|
|
|
```yaml
|
|
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:
|
|
|
|
```bash
|
|
mkdir -p ~/srv/core/data
|
|
touch ~/srv/core/data/acme.json
|
|
chmod 600 ~/srv/core/data/acme.json
|
|
```
|
|
|
|
Arranque:
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
~/srv/init_project.sh api-ventas api.midominio.com 80
|
|
```
|
|
|
|
Genera:
|
|
|
|
```text
|
|
~/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
|
|
|
|
```bash
|
|
# 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
|
|
```yaml
|
|
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
|
|
|
|
```bash
|
|
cd ~/srv/projects/api-ventas
|
|
docker compose up -d
|
|
```
|
|
|
|
### Paso 5 — Post-instalación (opcional, apps Laravel)
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```yaml
|
|
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](#opción-b--nginx-proxy-manager-panel-web).
|
|
|
|
---
|
|
|
|
## 5. Copias de seguridad
|
|
|
|
Los respaldos se guardan **fuera** de los repositorios Git:
|
|
|
|
```bash
|
|
# 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):
|
|
|
|
```cron
|
|
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` |
|