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>
109 lines
4.1 KiB
Markdown
109 lines
4.1 KiB
Markdown
# 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). |
|