# Deploy en Produccion (Docker + CI/CD) - Direccion de Admision 2026
Todo el proyecto se dockeriza y se despliega mediante **GitHub Actions**. Las imagenes se construyen en GitHub y se suben a GitHub Container Registry (GHCR). El VPS solo descarga y ejecuta.
## Resumen rapido — ¿Que hago yo?
### Setup inicial (solo una vez, ~25 min)
| Paso | Que haces | Donde | Tiempo |
|---|---|---|---|
| 1 | Pegar 6 secrets en GitHub | Navegador (GitHub Settings) | 5 min |
| 2 | Conectar al VPS, clonar repo, crear `.env.prod` y editar valores | Terminal SSH | 10 min |
| 3 | Copiar/pegar 2 comandos para MySQL + importar dump | Terminal SSH | 2 min |
| 4 | Clic en "Run workflow" en GitHub Actions y esperar | Navegador (GitHub Actions) | 3 min |
| 5 | Copiar/pegar 2 comandos (storage link + seeders) | Terminal SSH | 1 min |
| 6 | Copiar/pegar server block de nginx + correr certbot | Terminal SSH | 5 min |
### Deploys del dia a dia
| Tu haces | Que pasa |
|---|---|
| `git push` a main | Nada (hasta que tu decidas) |
| Clic en **"Run workflow"** en GitHub Actions | Build + Push al registry + Deploy al VPS (~3 min) |
**No tocas terminal, no compilas, no haces SSH. Solo un clic desde el navegador.**
---
## Arquitectura de deploy
```
Tu PC GitHub GHCR VPS
| | | |
| git push | | |
| ──────────► [main branch] | |
| | | |
| [GitHub Actions] | |
| (trigger manual) | |
| | | |
| Build backend ──────► ghcr.io/.../backend |
| Build frontend ──────► ghcr.io/.../frontend |
| | | |
| SSH al VPS ────────────────────────────► |
| | | docker pull |
| | | docker up |
| | | App lista |
```
## Arquitectura de contenedores
```
Puerto 80/443
|
[nginx del host] ← SSL/Certbot
|
proxy_pass
|
127.0.0.1:8080
|
[nginx container] (reverse proxy)
/ \
/api/* / \ /*
/ \
[backend] [frontend]
PHP-FPM nginx+SPA
:9000 :80
|
[mysql]
:3306
```
---
## De donde sale cada credencial
Hay 3 lugares donde se ponen credenciales. Esta tabla explica cada una y como obtenerla:
### A. Archivo `.env.prod` (en el VPS)
| Credencial | Como la obtienes |
|---|---|
| `APP_KEY` | Ejecutas `php -r "echo 'base64:'.base64_encode(random_bytes(32)).PHP_EOL;"` en tu PC y copias el resultado |
| `DB_PASSWORD` | La inventas tu. Para generar una segura: `openssl rand -base64 32` |
| `APP_URL` | Tu dominio (ej: `https://admision.tu-universidad.edu.pe`) |
| `SESSION_DOMAIN` | Tu dominio sin https (ej: `admision.tu-universidad.edu.pe`) |
| `SANCTUM_STATEFUL_DOMAINS` | Igual que SESSION_DOMAIN |
| `GITHUB_REPO` | Tu usuario/repo de GitHub (ej: `juanperez/direccion_de_admision_2026`) |
| `MAIL_PASSWORD` | Te lo da tu proveedor SMTP (Gmail, Mailgun, etc.) |
### B. GitHub Secrets (en el navegador)
| Secret | Como lo obtienes |
|---|---|
| `VPS_HOST` | La IP de tu droplet, la ves en el panel de DigitalOcean |
| `VPS_USER` | Normalmente `root` |
| `VPS_SSH_KEY` | El contenido de la clave privada SSH (ver paso 1 abajo) |
| `VPS_PORT` | Normalmente `22` |
| `VPS_PROJECT_PATH` | La ruta donde clonas el repo (ej: `/root/direccion_de_admision_2026`) |
| `CR_PAT` | Token que generas en GitHub > Settings > Developer settings > Tokens |
### C. Se generan automaticamente (no los tocas)
| Credencial | Descripcion |
|---|---|
| `GITHUB_TOKEN` | GitHub Actions lo crea solo en cada ejecucion |
| `MYSQL_ROOT_PASSWORD` | Docker lo lee de `DB_PASSWORD` del `.env.prod` |
---
## Setup inicial (solo la primera vez)
### 1. Crear clave SSH en el VPS y configurar secrets en GitHub
GitHub Actions necesita conectarse al VPS por SSH. Si actualmente entras con contraseña, necesitas crear una clave SSH.
**En el VPS** (conectate con tu contraseña como siempre):
# Mostrar la clave PRIVADA (la que copias a GitHub)
cat ~/.ssh/github_actions
```
> Copia TODO el contenido que muestra el ultimo comando (desde `-----BEGIN` hasta `-----END`). Esa es la clave que pegas en GitHub como secret `VPS_SSH_KEY`.
**En GitHub** (navegador):
1. Ir a tu repo > **Settings** > **Secrets and variables** > **Actions**
2. Clic en **"New repository secret"** y agregar uno por uno:
| Secret | Que pegar |
|---|---|
| `VPS_HOST` | La IP de tu droplet (ej: `164.92.xxx.xxx`) |
| `VPS_USER` | `root` |
| `VPS_SSH_KEY` | El contenido completo de `~/.ssh/github_actions` (clave privada) |
La base de datos MySQL se crea automaticamente con estos valores (definidos en `.env.prod`):
| Variable | Valor | Descripcion |
|---|---|---|
| `DB_HOST` | `mysql` | Nombre del contenedor Docker (no cambiar) |
| `DB_PORT` | `3306` | Puerto interno de MySQL (no cambiar) |
| `DB_DATABASE` | `admision_2026` | Nombre de la base de datos |
| `DB_USERNAME` | `root` | Usuario de MySQL |
| `DB_PASSWORD` | Lo que pongas en `.env.prod` | La misma password para todo: MySQL root y conexion Laravel |
> **Importante:** La password que pongas en `DB_PASSWORD` es la que usa Docker para crear el usuario root de MySQL **y** la que usa Laravel para conectarse. Debe ser la misma en ambos casos porque es una sola variable. Esta misma password es la que usas en los comandos de importacion donde dice `TU_PASSWORD`.
---
### 3. Levantar MySQL e importar la base de datos
```bash
docker compose --env-file .env.prod -f docker-compose.prod.yml up -d mysql