Initial commit: OAuth IAM Laravel application
Laravel-based OAuth/IAM service with Passport, Vue 3 frontend, and Docker Compose setup for local and production deployment. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
108
docs/despliegue.md
Normal file
108
docs/despliegue.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Despliegue en producción (Docker)
|
||||
|
||||
Stack: `app` (PHP-FPM 8.3) + `nginx` (estáticos y proxy) + `db` (PostgreSQL 16) + `redis`
|
||||
(cache/sesión/colas) + `queue` (worker) + `scheduler`.
|
||||
|
||||
## 1. Preparar el `.env`
|
||||
|
||||
```bash
|
||||
cp .env.production.example .env
|
||||
```
|
||||
|
||||
Editar `.env` y completar como mínimo:
|
||||
|
||||
- `APP_URL` — dominio real, con `https://`.
|
||||
- `DB_PASSWORD` — contraseña de PostgreSQL (usada también por el servicio `db`).
|
||||
- `SESSION_DOMAIN` — dominio (o `.tu-dominio.com` si hay subdominios).
|
||||
- `APP_KEY` — generar uno nuevo, no reutilizar el de desarrollo:
|
||||
|
||||
```bash
|
||||
docker run --rm -v "$PWD":/app -w /app composer:2 sh -c \
|
||||
"php -r \"echo 'base64:'.base64_encode(random_bytes(32)).PHP_EOL;\""
|
||||
```
|
||||
|
||||
Pegar el resultado en `APP_KEY=`.
|
||||
|
||||
## 2. Levantar el stack
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml up -d --build
|
||||
```
|
||||
|
||||
En el primer arranque, el contenedor `app` (ver `docker/php/entrypoint.sh`):
|
||||
|
||||
1. Genera las claves RSA de Passport (`storage/oauth-private.key` / `.pub`) si no existen —
|
||||
quedan persistidas en el volumen `app_storage`, **no se regeneran en cada deploy** (regenerarlas
|
||||
invalidaría todos los tokens ya emitidos).
|
||||
2. Corre `php artisan migrate --force`.
|
||||
3. Cachea config/rutas/vistas y regenera la documentación de Swagger.
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml logs -f app
|
||||
```
|
||||
|
||||
## 3. Crear el primer usuario admin
|
||||
|
||||
**Recomendado para producción:** no correr `db:seed` (ese seeder crea datos de demo con
|
||||
contraseñas conocidas). En su lugar, con la base de usuarios vacía, andá a `/register` y creá una
|
||||
cuenta — al ser la primera, el sistema la marca automáticamente como **admin**, aprobada y con la
|
||||
sesión iniciada (no hace falta que nadie la apruebe, porque todavía no existe ningún admin). Cualquier
|
||||
registro posterior vuelve a requerir aprobación manual desde el panel de usuarios.
|
||||
|
||||
Alternativa solo para entornos de prueba/demo, con datos de ejemplo (usuarios, clientes OAuth, historial
|
||||
de logins falso):
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml exec app php artisan db:seed --force
|
||||
```
|
||||
|
||||
Esto sí crea `admin@example.com` / `password` — **cambiar la contraseña de inmediato** si se usa
|
||||
fuera de un entorno descartable.
|
||||
|
||||
## 4. TLS
|
||||
|
||||
Por defecto `nginx` sirve solo HTTP en el puerto 80 (`docker/nginx/default.conf`). Para HTTPS:
|
||||
|
||||
1. Conseguir certificado (por ejemplo con `certbot --webroot` apuntando a
|
||||
`docker/nginx/certs`, o cualquier CA propia).
|
||||
2. Colocar `fullchain.pem` y `privkey.pem` en `docker/nginx/certs/`.
|
||||
3. Descomentar el bloque `server { listen 443 ... }` en `docker/nginx/default.conf` y el
|
||||
`location /` que redirige a HTTPS.
|
||||
4. Descomentar `"443:443"` en `docker-compose.prod.yml` (servicio `nginx`).
|
||||
5. `docker compose -f docker-compose.prod.yml up -d --build nginx`.
|
||||
|
||||
## 5. Desplegar una actualización
|
||||
|
||||
```bash
|
||||
git pull # o el mecanismo que uses para traer código nuevo
|
||||
docker compose -f docker-compose.prod.yml up -d --build
|
||||
```
|
||||
|
||||
Las claves de Passport, la base de datos y Redis viven en volúmenes con nombre
|
||||
(`app_storage`, `db_data`, `redis_data`) — sobreviven a los rebuilds. El código y los assets del
|
||||
frontend, en cambio, se hornean dentro de la imagen en cada build (no hay bind mounts de código en
|
||||
producción).
|
||||
|
||||
## 6. Backups
|
||||
|
||||
Mínimo indispensable a respaldar:
|
||||
|
||||
- Volumen `db_data` (o mejor, `pg_dump` periódico contra el servicio `db`).
|
||||
- Volumen `app_storage` — contiene, entre otras cosas, las claves de Passport. Perderlas invalida
|
||||
todos los tokens emitidos hasta ese momento.
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml exec db \
|
||||
pg_dump -U "$DB_USERNAME" "$DB_DATABASE" > backup-$(date +%F).sql
|
||||
```
|
||||
|
||||
## Servicios del compose
|
||||
|
||||
| Servicio | Rol |
|
||||
|-------------|-----|
|
||||
| `app` | PHP-FPM. Corre migraciones y cacheo al arrancar (`CONTAINER_ROLE=app`). |
|
||||
| `queue` | `php artisan queue:work redis` — misma imagen que `app`, sin el paso de migración. |
|
||||
| `scheduler` | `php artisan schedule:work` — reemplaza al cron del sistema. |
|
||||
| `nginx` | Sirve `public/build` y hace proxy de `*.php` a `app:9000`. |
|
||||
| `db` | PostgreSQL 16, datos en el volumen `db_data`. |
|
||||
| `redis` | Cache, sesiones y colas, datos en el volumen `redis_data` (AOF activado). |
|
||||
Reference in New Issue
Block a user