magicserve 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.es.md +123 -0
- package/README.md +122 -0
- package/package.json +30 -0
- package/run.sh +473 -0
package/README.es.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Magicserve 🪄
|
|
2
|
+
|
|
3
|
+
*[Read in English](README.md)*
|
|
4
|
+
|
|
5
|
+
Magicserve es una herramienta CLI para gestionar entornos de desarrollo web locales. Su objetivo es iniciar, detener y manejar el estado de múltiples servidores locales (`node` y `php`) al mismo tiempo, y automáticamente levantar un Reverse Proxy (Nginx) y generar certificados SSL vía `mkcert` para asignarle un dominio dinámico (ej. `tu-proyecto.test`).
|
|
6
|
+
|
|
7
|
+
## Requisitos
|
|
8
|
+
|
|
9
|
+
Antes de utilizar `magicserve`, es necesario tener instalado en la computadora de desarrollo:
|
|
10
|
+
- [Node.js y npm](https://nodejs.org/)
|
|
11
|
+
- [jq](https://jqlang.github.io/jq/) (`brew install jq`)
|
|
12
|
+
- [mkcert](https://github.com/FiloSottile/mkcert) (`brew install mkcert`)
|
|
13
|
+
- Nginx (`brew install nginx`)
|
|
14
|
+
- PHP (si tu proyecto requiere servicios backend en php)
|
|
15
|
+
|
|
16
|
+
## Instalación global
|
|
17
|
+
|
|
18
|
+
Si tienes los requisitos instalados, puedes instalar la utilidad de manera global usando npm:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -g davidlomas/magicserve
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> **Nota:** También puedes publicarlo en npm publico y usar `npm install -g magicserve` directamente.
|
|
25
|
+
|
|
26
|
+
## Actualización
|
|
27
|
+
|
|
28
|
+
Si ya tienes `magicserve` instalado y quieres actualizarlo a la última versión, ejecuta el mismo comando de instalación:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g davidlomas/magicserve
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Esto sobreescribirá la versión anterior con la más reciente directamente desde GitHub. Tus archivos `magicserve.json` en tus proyectos **no se verán afectados**.
|
|
35
|
+
|
|
36
|
+
> 💡 Puedes verificar la versión instalada ejecutando cualquier comando de `magicserve`, aparecerá al inicio.
|
|
37
|
+
|
|
38
|
+
## ¿Cómo se usa?
|
|
39
|
+
|
|
40
|
+
Una vez instalado de manera global, dirígete a cualquier carpeta en tu computadora que servirá como "nodo central" o "espacio de trabajo" de tus proyectos, y ejecuta:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
magicserve init
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Este comando creará automáticamente un archivo base llamado **`magicserve.json`** en el directorio actual.
|
|
47
|
+
|
|
48
|
+
### Archivo de configuración: `magicserve.json`
|
|
49
|
+
|
|
50
|
+
Tu directorio central gestiona y levanta las aplicaciones referenciadas dentro del **`magicserve.json`**. Su estructura es así de sencilla:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
[
|
|
54
|
+
{
|
|
55
|
+
"path": "../tu-proyecto-frontal",
|
|
56
|
+
"domain": "tu-proyecto.test",
|
|
57
|
+
"type": "node",
|
|
58
|
+
"port": 3000
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"path": "../tu-api-backend",
|
|
62
|
+
"domain": "api.tu-proyecto.test",
|
|
63
|
+
"type": "php",
|
|
64
|
+
"port": 3001,
|
|
65
|
+
"tunnel": "mi-super-api-dev"
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Propiedades:**
|
|
71
|
+
- **`path`**: Ruta relativa o absoluta hacia el directorio del proyecto donde se deberá correr el servidor.
|
|
72
|
+
- **`domain`**: El dominio de desarrollo local que se enlazará automáticamente (eg. `*.test`).
|
|
73
|
+
- **`type`**: `node` (Correrá usando `npm run dev`) o `php` (Correrá el built-in server usando `php -S`).
|
|
74
|
+
- **`port`**: El puerto interno que el servicio ocupará.
|
|
75
|
+
- **`tunnel`**: *(Opcional)* Subdominio para enlazar puerto interno y exponerlo a internet público a través de `localtunnel` (Ej. webhooks de Mercado Libre o pruebas móviles).
|
|
76
|
+
|
|
77
|
+
Una vez configurado o modificado a tu gusto, utiliza los comandos de control.
|
|
78
|
+
|
|
79
|
+
## Comandos disponibles
|
|
80
|
+
|
|
81
|
+
## Arquitectura: ¿Cómo funciona bajo la manga?
|
|
82
|
+
|
|
83
|
+
Magicserve orquesta en segundos varias herramientas subyacentes para que tú solo te preocupes por el código de tu proyecto.
|
|
84
|
+
|
|
85
|
+
```mermaid
|
|
86
|
+
flowchart TD
|
|
87
|
+
Dev([👨💻 Desarrollador])
|
|
88
|
+
World([🌐 Webhooks Externos])
|
|
89
|
+
|
|
90
|
+
subgraph Tu Computadora Local
|
|
91
|
+
Nginx(Nginx Proxy Inverso SSL)
|
|
92
|
+
LT(LocalTunnel Túnel Reverso)
|
|
93
|
+
Node((Servidor Node\nEj. 3000))
|
|
94
|
+
PHP((Servidor PHP\nEj. 3001))
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
Dev -- "https://tu-proyecto.test" --> Nginx
|
|
98
|
+
World -- "https://mi-api.loca.lt" --> LT
|
|
99
|
+
|
|
100
|
+
Nginx -- "localhost:3000" --> Node
|
|
101
|
+
Nginx -- "localhost:3001" --> PHP
|
|
102
|
+
LT -- "Túnel" --> PHP
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
Dentro del directorio donde está tu `magicserve.json`, dispones de los siguientes comandos mágicos:
|
|
107
|
+
|
|
108
|
+
- **`magicserve start`**: Inicia todos los servicios del `magicserve.json` en los puertos definidos, genera certificados SSL dinámicos de ser necesario y configura Nginx.
|
|
109
|
+
- **`magicserve stop`**: Detiene ordenadamente los servicios activos mencionados de tu `magicserve.json`.
|
|
110
|
+
- **`magicserve status`**: Te muestra en terminal cuáles de tus proyectos están activos actualmente y cuál es su PID.
|
|
111
|
+
- **`magicserve stopall`**: Comando de emergencia. Busca y destruye TODOS los demonios, configuraciones temporales nginx relacionadas, certificados, puertos y purga todas las entradas de localhost customizadas en todo el sistema, restaurando tu computadora.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
### Novedades en v1.2.0 🚇
|
|
116
|
+
|
|
117
|
+
- **Localtunnel Integrado**: Expón de forma permanente y automática puertos de tu API al internet vía la nueva propiedad `tunnel` en el config json para recibir **Webhooks** de terceros (Mercado Libre, Stripe, etc).
|
|
118
|
+
|
|
119
|
+
### Novedades en v1.1.0 🚀
|
|
120
|
+
|
|
121
|
+
- **Visualización de Versión**: Ahora puedes ver la versión de Magicserve directamente en la terminal al ejecutar cualquier comando.
|
|
122
|
+
- **Soporte para Archivos Grandes**: Nginx y PHP se configuran automáticamente para soportar payloads de hasta **100MB** (uploads y JSON), solucionando el error "413 Request Entity Too Large".
|
|
123
|
+
- **SSL Automático**: Soporte nativo para HTTPS vía `mkcert`.
|
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Magicserve 🪄
|
|
2
|
+
|
|
3
|
+
*[Leer en Español](README.es.md)*
|
|
4
|
+
|
|
5
|
+
Magicserve is a CLI tool for managing local web development environments. Its goal is to start, stop, and manage the state of multiple local servers (`node` and `php`) simultaneously, automatically set up a Reverse Proxy (Nginx), and generate SSL certificates via `mkcert` to assign them a dynamic local domain (e.g. `your-project.test`).
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
Before using `magicserve`, you must have the following installed on your development machine:
|
|
10
|
+
- [Node.js and npm](https://nodejs.org/)
|
|
11
|
+
- [jq](https://jqlang.github.io/jq/) (`brew install jq`)
|
|
12
|
+
- [mkcert](https://github.com/FiloSottile/mkcert) (`brew install mkcert`)
|
|
13
|
+
- Nginx (`brew install nginx`)
|
|
14
|
+
- PHP (if your project requires a PHP backend service)
|
|
15
|
+
|
|
16
|
+
## Global Installation
|
|
17
|
+
|
|
18
|
+
If you have the requirements installed, you can globally install the utility using npm directly from GitHub:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -g davidlomas/magicserve
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> **Note:** You can also publish it to the public npm registry and use `npm install -g magicserve`.
|
|
25
|
+
|
|
26
|
+
## Updating
|
|
27
|
+
|
|
28
|
+
If you already have `magicserve` installed and want to update to the latest version, simply run the same install command again:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g davidlomas/magicserve
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This will overwrite the previous version with the latest one directly from GitHub. Your `magicserve.json` files in your projects **will not be affected**.
|
|
35
|
+
|
|
36
|
+
> 💡 You can verify the installed version by running any `magicserve` command — it will be displayed at the top.
|
|
37
|
+
|
|
38
|
+
## How to Use
|
|
39
|
+
|
|
40
|
+
Once installed globally, navigate to any folder on your computer that will serve as a "central hub" or "workspace" for your projects, and run:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
magicserve init
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
This command will automatically create a base **`magicserve.json`** file in the current directory.
|
|
47
|
+
|
|
48
|
+
### Configuration File: `magicserve.json`
|
|
49
|
+
|
|
50
|
+
Your central directory manages and starts the applications referenced within the **`magicserve.json`**. Its structure is this simple:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
[
|
|
54
|
+
{
|
|
55
|
+
"path": "../your-frontend-project",
|
|
56
|
+
"domain": "your-project.test",
|
|
57
|
+
"type": "node",
|
|
58
|
+
"port": 3000
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"path": "../your-backend-api",
|
|
62
|
+
"domain": "api.your-project.test",
|
|
63
|
+
"type": "php",
|
|
64
|
+
"port": 3001,
|
|
65
|
+
"tunnel": "my-cool-api-dev"
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Properties:**
|
|
71
|
+
- **`path`**: Relative or absolute path to the project's directory where the server should run.
|
|
72
|
+
- **`domain`**: The local development domain that will be automatically mapped (e.g. `*.test`).
|
|
73
|
+
- **`type`**: `node` (Runs using `npm run dev`) or `php` (Runs the PHP built-in server using `php -S`).
|
|
74
|
+
- **`port`**: The internal port the service will use.
|
|
75
|
+
- **`tunnel`**: *(Optional)* Subdomain to securely expose your internal port to the public internet via `localtunnel` (Great for testing third-party Webhooks like Mercado Libre or local mobile testing).
|
|
76
|
+
|
|
77
|
+
Once configured or modified to your liking, you can use the control commands.
|
|
78
|
+
|
|
79
|
+
## Available Commands
|
|
80
|
+
|
|
81
|
+
## Architecture: How it works under the hood
|
|
82
|
+
|
|
83
|
+
Magicserve instantly orchestrates multiple local tools so you don't have to manage them manually.
|
|
84
|
+
|
|
85
|
+
```mermaid
|
|
86
|
+
flowchart TD
|
|
87
|
+
Dev([👨💻 Developer])
|
|
88
|
+
World([🌐 External Webhooks / Web])
|
|
89
|
+
|
|
90
|
+
subgraph Your Local Machine
|
|
91
|
+
Nginx(Nginx Reverse Proxy with HTTPS)
|
|
92
|
+
LT(LocalTunnel Reverse Tunnel)
|
|
93
|
+
Node((Node Server\ne.g. 3000))
|
|
94
|
+
PHP((PHP Server\ne.g. 3001))
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
Dev -- "https://your-project.test" --> Nginx
|
|
98
|
+
World -- "https://my-api.loca.lt" --> LT
|
|
99
|
+
|
|
100
|
+
Nginx -- "localhost:3000" --> Node
|
|
101
|
+
Nginx -- "localhost:3001" --> PHP
|
|
102
|
+
LT -- "Tunnel" --> PHP
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Within the directory where your `magicserve.json` is located, you have the following magic commands available:
|
|
106
|
+
|
|
107
|
+
- **`magicserve start`**: Starts all services declared in `magicserve.json` on the defined ports, generates dynamic SSL certificates if necessary, and configures Nginx.
|
|
108
|
+
- **`magicserve stop`**: Orderly stops the active services mentioned in your `magicserve.json`.
|
|
109
|
+
- **`magicserve status`**: Shows a terminal output of which projects are currently active and their PIDs.
|
|
110
|
+
- **`magicserve stopall`**: Emergency command. Finds and destroys ALL active daemons, related Nginx configurations, certificates, processes, and purges all custom localhost entries system-wide, restoring your computer's clean state.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### Features in v1.2.0 🚇
|
|
115
|
+
|
|
116
|
+
- **Integrated Localtunnel**: Permanently and automatically expose any of your API ports to the internet via the new `tunnel` property in config JSON to seamlessly receive third-party **Webhooks** (Mercado Libre, Stripe, etc).
|
|
117
|
+
|
|
118
|
+
### Features in v1.1.0 🚀
|
|
119
|
+
|
|
120
|
+
- **Version Display**: Now you can see the Magicserve version directly in the terminal.
|
|
121
|
+
- **Large Body Support**: Nginx and PHP are automatically configured to support up to **100MB** payloads (JSON and file uploads), fixing the "413 Request Entity Too Large" error.
|
|
122
|
+
- **Automatic SSL**: Native support for HTTPS via `mkcert`.
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "magicserve",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Script to run local environments via magicserve.json",
|
|
5
|
+
"files": [
|
|
6
|
+
"run.sh"
|
|
7
|
+
],
|
|
8
|
+
"bin": {
|
|
9
|
+
"magicserve": "./run.sh"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/davidlomas/magicserve.git"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"local",
|
|
20
|
+
"run",
|
|
21
|
+
"env",
|
|
22
|
+
"magicompras"
|
|
23
|
+
],
|
|
24
|
+
"author": "",
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/davidlomas/magicserve/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/davidlomas/magicserve#readme"
|
|
30
|
+
}
|
package/run.sh
ADDED
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# run.sh
|
|
4
|
+
|
|
5
|
+
# El directorio de trabajo actual (donde se ejecuta el comando)
|
|
6
|
+
SCRIPT_DIR="$(pwd)"
|
|
7
|
+
CONFIG_FILE="$SCRIPT_DIR/magicserve.json"
|
|
8
|
+
|
|
9
|
+
# El directorio donde reside el script (para leer package.json)
|
|
10
|
+
REAL_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
VERSION=$(jq -r '.version' "$REAL_SCRIPT_DIR/package.json" 2>/dev/null || echo "1.1.0")
|
|
12
|
+
|
|
13
|
+
MAGICSERVE_DIR="$SCRIPT_DIR/.magicserve"
|
|
14
|
+
LOGS_DIR="$MAGICSERVE_DIR/logs"
|
|
15
|
+
PIDS_DIR="$MAGICSERVE_DIR/pids"
|
|
16
|
+
|
|
17
|
+
# Asegurar que los directorios internos existen
|
|
18
|
+
mkdir -p "$LOGS_DIR" "$PIDS_DIR"
|
|
19
|
+
|
|
20
|
+
echo "🪄 Magicserve v$VERSION"
|
|
21
|
+
echo ""
|
|
22
|
+
|
|
23
|
+
if [ "$1" != "stopall" ] && [ "$1" != "init" ] && [ ! -f "$CONFIG_FILE" ]; then
|
|
24
|
+
echo "❌ Error: magicserve.json no encontrado en el directorio actual."
|
|
25
|
+
echo "💡 Truco: Ejecuta 'magicserve init' para generar un template base."
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
if ! command -v jq &> /dev/null; then
|
|
30
|
+
echo "❌ jq no instalado → brew install jq"
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
ACTION=$1
|
|
35
|
+
|
|
36
|
+
usage() {
|
|
37
|
+
echo "Uso:"
|
|
38
|
+
echo " magicserve [start|stop|stopall|status|init]"
|
|
39
|
+
echo ""
|
|
40
|
+
echo " init - Crea un archivo magicserve.json de plantilla en la carpeta actual"
|
|
41
|
+
echo " start - Inicia todos los servicios del magicserve.json"
|
|
42
|
+
echo " stop - Detiene los servicios del magicserve.json"
|
|
43
|
+
echo " stopall - Busca y detiene TODOS los dominios (sin depender de magicserve.json) y borra todo rastro"
|
|
44
|
+
echo " status - Muestra el estado de los servicios"
|
|
45
|
+
exit 1
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
start_server() {
|
|
49
|
+
local PATH_DIR=$1
|
|
50
|
+
local DOMAIN=$2
|
|
51
|
+
local TYPE=$3
|
|
52
|
+
local PORT=$4
|
|
53
|
+
|
|
54
|
+
local PID_FILE="$PIDS_DIR/${DOMAIN}.pid"
|
|
55
|
+
|
|
56
|
+
echo "🚀 Iniciando $DOMAIN ($TYPE) en puerto $PORT..."
|
|
57
|
+
|
|
58
|
+
# Navegar al directorio del proyecto relativo al script
|
|
59
|
+
cd "$SCRIPT_DIR/$PATH_DIR" || {
|
|
60
|
+
echo "❌ Error: Directorio $PATH_DIR no encontrado para $DOMAIN"
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if [ "$TYPE" == "node" ]; then
|
|
65
|
+
nohup npm run dev -- --port $PORT > "$LOGS_DIR/${DOMAIN}.log" 2>&1 &
|
|
66
|
+
local PID=$!
|
|
67
|
+
echo $PID > "$PID_FILE"
|
|
68
|
+
echo "✅ Node corriendo (PID: $PID)"
|
|
69
|
+
elif [ "$TYPE" == "php" ]; then
|
|
70
|
+
# El docroot por defecto para php es el directorio actual
|
|
71
|
+
nohup php -d upload_max_filesize=100M -d post_max_size=100M -S "localhost:$PORT" -t . > "$LOGS_DIR/${DOMAIN}.log" 2>&1 &
|
|
72
|
+
local PID=$!
|
|
73
|
+
echo $PID > "$PID_FILE"
|
|
74
|
+
echo "✅ PHP corriendo (PID: $PID)"
|
|
75
|
+
else
|
|
76
|
+
echo "❌ Tipo $TYPE no soportado (usa 'node' o 'php')"
|
|
77
|
+
fi
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
start_proxy() {
|
|
81
|
+
local DOMAIN=$1
|
|
82
|
+
local PORT=$2
|
|
83
|
+
|
|
84
|
+
echo "🔐 Configurando SSL y Proxy Nginx para $DOMAIN -> $PORT..."
|
|
85
|
+
|
|
86
|
+
local HOSTS_FILE="/etc/hosts"
|
|
87
|
+
local NGINX_SERVER_DIR="/opt/homebrew/etc/nginx/servers"
|
|
88
|
+
local NGINX_CONF="$NGINX_SERVER_DIR/${DOMAIN}.conf"
|
|
89
|
+
local CERT_DIR="$HOME/.ssl"
|
|
90
|
+
local CERT="$CERT_DIR/$DOMAIN.pem"
|
|
91
|
+
local KEY="$CERT_DIR/$DOMAIN-key.pem"
|
|
92
|
+
|
|
93
|
+
# Validar si mkcert y nginx están instalados
|
|
94
|
+
if ! command -v mkcert &> /dev/null; then
|
|
95
|
+
echo "❌ mkcert no instalado → brew install mkcert"
|
|
96
|
+
exit 1
|
|
97
|
+
fi
|
|
98
|
+
if ! command -v nginx &> /dev/null; then
|
|
99
|
+
echo "❌ nginx no instalado → brew install nginx"
|
|
100
|
+
exit 1
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# Generar carpeta de certificados si no existe
|
|
104
|
+
mkdir -p "$CERT_DIR" "$NGINX_SERVER_DIR"
|
|
105
|
+
sudo chown -R $(whoami) "$CERT_DIR"
|
|
106
|
+
|
|
107
|
+
# Instalar mkcert CA si no lo está (suave)
|
|
108
|
+
mkcert -install > /dev/null 2>&1
|
|
109
|
+
|
|
110
|
+
# Generar los certificados para el dominio si no existen
|
|
111
|
+
if [ ! -f "$CERT" ] || [ ! -f "$KEY" ]; then
|
|
112
|
+
echo "🆕 Generando certificado SSL para $DOMAIN..."
|
|
113
|
+
mkcert -cert-file "$CERT" -key-file "$KEY" "$DOMAIN"
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# Limpiar en /etc/hosts el dominio y volver a añadirlo
|
|
117
|
+
sudo sed -i '' "/[[:space:]]$DOMAIN$/d" "$HOSTS_FILE"
|
|
118
|
+
echo "127.0.0.1 $DOMAIN" | sudo tee -a "$HOSTS_FILE" > /dev/null
|
|
119
|
+
|
|
120
|
+
# Crear configuración de Nginx para el dominio
|
|
121
|
+
sudo tee "$NGINX_CONF" > /dev/null <<EOF
|
|
122
|
+
server {
|
|
123
|
+
listen 443 ssl;
|
|
124
|
+
server_name $DOMAIN;
|
|
125
|
+
|
|
126
|
+
ssl_certificate $CERT;
|
|
127
|
+
ssl_certificate_key $KEY;
|
|
128
|
+
|
|
129
|
+
client_max_body_size 100M;
|
|
130
|
+
|
|
131
|
+
location / {
|
|
132
|
+
proxy_pass http://localhost:$PORT;
|
|
133
|
+
proxy_set_header Host \$host;
|
|
134
|
+
proxy_set_header X-Real-IP \$remote_addr;
|
|
135
|
+
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
136
|
+
proxy_set_header X-Forwarded-Proto https;
|
|
137
|
+
|
|
138
|
+
# WebSockets Support (Vite HMR)
|
|
139
|
+
proxy_http_version 1.1;
|
|
140
|
+
proxy_set_header Upgrade \$http_upgrade;
|
|
141
|
+
proxy_set_header Connection "upgrade";
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
server {
|
|
146
|
+
listen 80;
|
|
147
|
+
server_name $DOMAIN;
|
|
148
|
+
return 301 https://\$host\$request_uri;
|
|
149
|
+
}
|
|
150
|
+
EOF
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
start_tunnel() {
|
|
154
|
+
local DOMAIN=$1
|
|
155
|
+
local PORT=$2
|
|
156
|
+
local TUNNEL_SUBDOMAIN=$3
|
|
157
|
+
|
|
158
|
+
echo "🚇 Iniciando túnel para $DOMAIN en puerto $PORT..."
|
|
159
|
+
local TUNNEL_PID_FILE="$PIDS_DIR/${DOMAIN}_tunnel.pid"
|
|
160
|
+
|
|
161
|
+
# Si pasaron false o null, no hacer nada
|
|
162
|
+
if [ "$TUNNEL_SUBDOMAIN" == "false" ] || [ "$TUNNEL_SUBDOMAIN" == "null" ] || [ -z "$TUNNEL_SUBDOMAIN" ]; then
|
|
163
|
+
return
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
local TUNNEL_LOG="$LOGS_DIR/${DOMAIN}_tunnel.log"
|
|
167
|
+
|
|
168
|
+
if [ "$TUNNEL_SUBDOMAIN" == "true" ]; then
|
|
169
|
+
nohup npx localtunnel --port $PORT > "$TUNNEL_LOG" 2>&1 &
|
|
170
|
+
else
|
|
171
|
+
nohup npx localtunnel --port $PORT --subdomain "$TUNNEL_SUBDOMAIN" > "$TUNNEL_LOG" 2>&1 &
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
local PID=$!
|
|
175
|
+
echo $PID > "$TUNNEL_PID_FILE"
|
|
176
|
+
echo "✅ Túnel corriendo (PID: $PID)"
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
start_all() {
|
|
180
|
+
echo "🌟 Iniciando todos los servicios desde magicserve.json..."
|
|
181
|
+
|
|
182
|
+
local LENGTH=$(jq '. | length' "$CONFIG_FILE")
|
|
183
|
+
for (( i=0; i<$LENGTH; i++ )); do
|
|
184
|
+
local PATH_DIR=$(jq -r ".[$i].path" "$CONFIG_FILE")
|
|
185
|
+
local DOMAIN=$(jq -r ".[$i].domain" "$CONFIG_FILE")
|
|
186
|
+
local TYPE=$(jq -r ".[$i].type" "$CONFIG_FILE")
|
|
187
|
+
local PORT=$(jq -r ".[$i].port" "$CONFIG_FILE")
|
|
188
|
+
local TUNNEL=$(jq -r ".[$i].tunnel // empty" "$CONFIG_FILE")
|
|
189
|
+
|
|
190
|
+
start_server "$PATH_DIR" "$DOMAIN" "$TYPE" "$PORT"
|
|
191
|
+
start_proxy "$DOMAIN" "$PORT"
|
|
192
|
+
|
|
193
|
+
if [ -n "$TUNNEL" ]; then
|
|
194
|
+
start_tunnel "$DOMAIN" "$PORT" "$TUNNEL"
|
|
195
|
+
fi
|
|
196
|
+
done
|
|
197
|
+
|
|
198
|
+
echo "🔄 Recargando Nginx..."
|
|
199
|
+
if sudo nginx -t > /dev/null 2>&1; then
|
|
200
|
+
sudo nginx -s reload || sudo nginx
|
|
201
|
+
echo "✅ Nginx configurado exitosamente."
|
|
202
|
+
else
|
|
203
|
+
echo "❌ Error en configuración de Nginx. Revisa /opt/homebrew/etc/nginx/servers/"
|
|
204
|
+
fi
|
|
205
|
+
echo "🎉 ¡Todo listo!"
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
stop_all() {
|
|
209
|
+
echo "🛑 Deteniendo todos los servicios..."
|
|
210
|
+
|
|
211
|
+
local HOSTS_FILE="/etc/hosts"
|
|
212
|
+
local NGINX_SERVER_DIR="/opt/homebrew/etc/nginx/servers"
|
|
213
|
+
|
|
214
|
+
local LENGTH=$(jq '. | length' "$CONFIG_FILE")
|
|
215
|
+
for (( i=0; i<$LENGTH; i++ )); do
|
|
216
|
+
local DOMAIN=$(jq -r ".[$i].domain" "$CONFIG_FILE")
|
|
217
|
+
local PID_FILE="$PIDS_DIR/${DOMAIN}.pid"
|
|
218
|
+
|
|
219
|
+
if [ -f "$PID_FILE" ]; then
|
|
220
|
+
local PID=$(cat "$PID_FILE")
|
|
221
|
+
if ps -p $PID > /dev/null; then
|
|
222
|
+
kill $PID
|
|
223
|
+
echo "🛑 Servidor para $DOMAIN detenido (PID: $PID)."
|
|
224
|
+
else
|
|
225
|
+
echo "⚠️ Proceso para $DOMAIN no encontrado (el archivo PID será limpiado)."
|
|
226
|
+
fi
|
|
227
|
+
rm "$PID_FILE"
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
local TUNNEL_PID_FILE="$PIDS_DIR/${DOMAIN}_tunnel.pid"
|
|
231
|
+
if [ -f "$TUNNEL_PID_FILE" ]; then
|
|
232
|
+
local TPID=$(cat "$TUNNEL_PID_FILE")
|
|
233
|
+
if ps -p $TPID > /dev/null; then
|
|
234
|
+
kill $TPID
|
|
235
|
+
echo "🛑 Túnel para $DOMAIN detenido (PID: $TPID)."
|
|
236
|
+
else
|
|
237
|
+
echo "⚠️ Proceso de túnel para $DOMAIN no encontrado."
|
|
238
|
+
fi
|
|
239
|
+
rm "$TUNNEL_PID_FILE"
|
|
240
|
+
fi
|
|
241
|
+
|
|
242
|
+
# Limpiar de /etc/hosts
|
|
243
|
+
sudo sed -i '' "/[[:space:]]$DOMAIN$/d" "$HOSTS_FILE"
|
|
244
|
+
|
|
245
|
+
# Eliminar configuración de nginx
|
|
246
|
+
local NGINX_CONF="$NGINX_SERVER_DIR/${DOMAIN}.conf"
|
|
247
|
+
if [ -f "$NGINX_CONF" ]; then
|
|
248
|
+
sudo rm "$NGINX_CONF"
|
|
249
|
+
fi
|
|
250
|
+
done
|
|
251
|
+
|
|
252
|
+
# Recargar nginx
|
|
253
|
+
if sudo nginx -t > /dev/null 2>&1; then
|
|
254
|
+
sudo nginx -s reload > /dev/null 2>&1
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
echo "✅ Todo detenido."
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
status() {
|
|
261
|
+
echo "📊 Estado de los servicios:"
|
|
262
|
+
local LENGTH=$(jq '. | length' "$CONFIG_FILE")
|
|
263
|
+
for (( i=0; i<$LENGTH; i++ )); do
|
|
264
|
+
local DOMAIN=$(jq -r ".[$i].domain" "$CONFIG_FILE")
|
|
265
|
+
local PID_FILE="$PIDS_DIR/${DOMAIN}.pid"
|
|
266
|
+
|
|
267
|
+
if [ -f "$PID_FILE" ]; then
|
|
268
|
+
local PID=$(cat "$PID_FILE")
|
|
269
|
+
if ps -p $PID > /dev/null; then
|
|
270
|
+
echo "🟢 $DOMAIN: Corriendo (PID: $PID)"
|
|
271
|
+
else
|
|
272
|
+
echo "🔴 $DOMAIN: Archivo PID existe pero el proceso no está corriendo"
|
|
273
|
+
fi
|
|
274
|
+
else
|
|
275
|
+
echo "⚪️ $DOMAIN: Detenido"
|
|
276
|
+
fi
|
|
277
|
+
|
|
278
|
+
local TUNNEL_PID_FILE="$PIDS_DIR/${DOMAIN}_tunnel.pid"
|
|
279
|
+
if [ -f "$TUNNEL_PID_FILE" ]; then
|
|
280
|
+
local TPID=$(cat "$TUNNEL_PID_FILE")
|
|
281
|
+
if ps -p $TPID > /dev/null; then
|
|
282
|
+
echo " ↳ 🚇 Túnel expuesto (PID: $TPID)"
|
|
283
|
+
else
|
|
284
|
+
echo " ↳ 🔴 Túnel: Archivo PID existe pero no está corriendo"
|
|
285
|
+
fi
|
|
286
|
+
fi
|
|
287
|
+
done
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
stop_all_global() {
|
|
291
|
+
echo "🔥 STOPALL: Buscando y eliminando TODOS los dominios y rastros de la computadora..."
|
|
292
|
+
echo ""
|
|
293
|
+
|
|
294
|
+
local HOSTS_FILE="/etc/hosts"
|
|
295
|
+
local NGINX_SERVER_DIR="/opt/homebrew/etc/nginx/servers"
|
|
296
|
+
local CERT_DIR="$HOME/.ssl"
|
|
297
|
+
local FOUND_SOMETHING=false
|
|
298
|
+
|
|
299
|
+
# ─── 1. Limpiar archivos .pid locales ───
|
|
300
|
+
echo "🔍 Buscando archivos .pid locales..."
|
|
301
|
+
if [ -d "$PIDS_DIR" ]; then
|
|
302
|
+
for PID_FILE in "$PIDS_DIR"/*.pid; do
|
|
303
|
+
[ -f "$PID_FILE" ] || continue
|
|
304
|
+
FOUND_SOMETHING=true
|
|
305
|
+
local PID=$(cat "$PID_FILE")
|
|
306
|
+
local BASENAME=$(basename "$PID_FILE")
|
|
307
|
+
local DOMAIN_NAME=${BASENAME%.pid}
|
|
308
|
+
|
|
309
|
+
if ps -p $PID > /dev/null 2>&1; then
|
|
310
|
+
kill $PID 2>/dev/null
|
|
311
|
+
echo " 🛑 Proceso detenido: $DOMAIN_NAME (PID: $PID)"
|
|
312
|
+
else
|
|
313
|
+
echo " ⚠️ Proceso ya no existía: $DOMAIN_NAME (PID: $PID)"
|
|
314
|
+
fi
|
|
315
|
+
done
|
|
316
|
+
fi
|
|
317
|
+
if [ "$FOUND_SOMETHING" = false ]; then
|
|
318
|
+
echo " ✅ No se encontraron archivos .pid"
|
|
319
|
+
fi
|
|
320
|
+
|
|
321
|
+
# ─── 2. Matar TODOS los servidores PHP built-in de la computadora ───
|
|
322
|
+
echo ""
|
|
323
|
+
echo "🔍 Buscando servidores PHP built-in (php -S)..."
|
|
324
|
+
local PHP_PIDS=$(pgrep -f "php -S" 2>/dev/null)
|
|
325
|
+
if [ -n "$PHP_PIDS" ]; then
|
|
326
|
+
echo "$PHP_PIDS" | while read PID; do
|
|
327
|
+
local CMD=$(ps -p $PID -o args= 2>/dev/null)
|
|
328
|
+
kill $PID 2>/dev/null
|
|
329
|
+
echo " 🛑 PHP detenido (PID: $PID) → $CMD"
|
|
330
|
+
done
|
|
331
|
+
else
|
|
332
|
+
echo " ✅ No se encontraron servidores PHP"
|
|
333
|
+
fi
|
|
334
|
+
|
|
335
|
+
# ─── 3. Matar TODOS los servidores Node de desarrollo ───
|
|
336
|
+
echo ""
|
|
337
|
+
echo "🔍 Buscando servidores Node de desarrollo (vite, next, nuxt, webpack)..."
|
|
338
|
+
local NODE_PIDS=$(pgrep -f "(vite|next dev|nuxt|webpack-dev-server|node.*dev)" 2>/dev/null)
|
|
339
|
+
if [ -n "$NODE_PIDS" ]; then
|
|
340
|
+
echo "$NODE_PIDS" | while read PID; do
|
|
341
|
+
local CMD=$(ps -p $PID -o args= 2>/dev/null | head -c 120)
|
|
342
|
+
kill $PID 2>/dev/null
|
|
343
|
+
echo " 🛑 Node detenido (PID: $PID) → $CMD"
|
|
344
|
+
done
|
|
345
|
+
else
|
|
346
|
+
echo " ✅ No se encontraron servidores Node de desarrollo"
|
|
347
|
+
fi
|
|
348
|
+
|
|
349
|
+
# ─── 3.5. Matar procesos de localtunnel ───
|
|
350
|
+
echo ""
|
|
351
|
+
echo "🔍 Buscando procesos de localtunnel..."
|
|
352
|
+
local LT_PIDS=$(pgrep -f "localtunnel" 2>/dev/null)
|
|
353
|
+
if [ -n "$LT_PIDS" ]; then
|
|
354
|
+
echo "$LT_PIDS" | while read PID; do
|
|
355
|
+
kill $PID 2>/dev/null
|
|
356
|
+
echo " 🛑 localtunnel detenido (PID: $PID)"
|
|
357
|
+
done
|
|
358
|
+
else
|
|
359
|
+
echo " ✅ No se encontraron procesos de localtunnel"
|
|
360
|
+
fi
|
|
361
|
+
|
|
362
|
+
# ─── 4. Eliminar TODAS las configuraciones de nginx en servers/ ───
|
|
363
|
+
echo ""
|
|
364
|
+
echo "🔍 Buscando configuraciones de Nginx..."
|
|
365
|
+
FOUND_SOMETHING=false
|
|
366
|
+
if [ -d "$NGINX_SERVER_DIR" ]; then
|
|
367
|
+
for CONF_FILE in "$NGINX_SERVER_DIR"/*.conf; do
|
|
368
|
+
[ -f "$CONF_FILE" ] || continue
|
|
369
|
+
FOUND_SOMETHING=true
|
|
370
|
+
local CONF_NAME=$(basename "$CONF_FILE")
|
|
371
|
+
sudo rm -f "$CONF_FILE"
|
|
372
|
+
echo " 🗑️ Eliminado: $CONF_NAME"
|
|
373
|
+
done
|
|
374
|
+
fi
|
|
375
|
+
if [ "$FOUND_SOMETHING" = false ]; then
|
|
376
|
+
echo " ✅ No se encontraron configuraciones de Nginx"
|
|
377
|
+
fi
|
|
378
|
+
|
|
379
|
+
# ─── 5. Limpiar /etc/hosts (TODAS las entradas custom de 127.0.0.1) ───
|
|
380
|
+
echo ""
|
|
381
|
+
echo "🔍 Limpiando /etc/hosts (todas las entradas custom)..."
|
|
382
|
+
# Contar entradas de 127.0.0.1 que NO sean localhost
|
|
383
|
+
local HOSTS_BEFORE=$(grep -c '^127\.0\.0\.1' "$HOSTS_FILE" 2>/dev/null || echo 0)
|
|
384
|
+
# Eliminar todas las líneas 127.0.0.1 que NO sean localhost
|
|
385
|
+
sudo sed -i '' '/^127\.0\.0\.1[[:space:]]\{1,\}localhost$/!{ /^127\.0\.0\.1/d; }' "$HOSTS_FILE"
|
|
386
|
+
local HOSTS_AFTER=$(grep -c '^127\.0\.0\.1' "$HOSTS_FILE" 2>/dev/null || echo 0)
|
|
387
|
+
local REMOVED=$((HOSTS_BEFORE - HOSTS_AFTER))
|
|
388
|
+
if [ $REMOVED -gt 0 ]; then
|
|
389
|
+
echo " 🗑️ Se eliminaron $REMOVED entradas custom de /etc/hosts"
|
|
390
|
+
else
|
|
391
|
+
echo " ✅ No se encontraron entradas custom en /etc/hosts"
|
|
392
|
+
fi
|
|
393
|
+
|
|
394
|
+
# ─── 6. Eliminar TODO el contenido de ~/.ssl/ ───
|
|
395
|
+
echo ""
|
|
396
|
+
echo "🔍 Limpiando $CERT_DIR (todos los archivos)..."
|
|
397
|
+
if [ -d "$CERT_DIR" ] && [ "$(ls -A "$CERT_DIR" 2>/dev/null)" ]; then
|
|
398
|
+
local SSL_COUNT=$(ls -1 "$CERT_DIR" | wc -l | tr -d ' ')
|
|
399
|
+
rm -rf "$CERT_DIR"/*
|
|
400
|
+
echo " 🗑️ Se eliminaron $SSL_COUNT archivos de $CERT_DIR"
|
|
401
|
+
else
|
|
402
|
+
echo " ✅ No se encontraron archivos en $CERT_DIR"
|
|
403
|
+
fi
|
|
404
|
+
|
|
405
|
+
# ─── 7. Eliminar logs ───
|
|
406
|
+
echo ""
|
|
407
|
+
echo "🔍 Limpiando logs..."
|
|
408
|
+
if [ -d "$LOGS_DIR" ] && [ "$(ls -A "$LOGS_DIR" 2>/dev/null)" ]; then
|
|
409
|
+
rm -f "$LOGS_DIR"/*
|
|
410
|
+
echo " 🗑️ Logs eliminados"
|
|
411
|
+
else
|
|
412
|
+
echo " ✅ No se encontraron logs"
|
|
413
|
+
fi
|
|
414
|
+
|
|
415
|
+
# ─── 8. Detener Nginx completamente ───
|
|
416
|
+
echo ""
|
|
417
|
+
echo "🔍 Deteniendo Nginx..."
|
|
418
|
+
if pgrep -x nginx > /dev/null 2>&1; then
|
|
419
|
+
sudo nginx -s stop > /dev/null 2>&1
|
|
420
|
+
echo " 🛑 Nginx detenido"
|
|
421
|
+
else
|
|
422
|
+
echo " ✅ Nginx no estaba corriendo"
|
|
423
|
+
fi
|
|
424
|
+
|
|
425
|
+
echo ""
|
|
426
|
+
echo "🧹 ¡Todo limpio! No queda rastro."
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
init_config() {
|
|
430
|
+
if [ -f "$CONFIG_FILE" ]; then
|
|
431
|
+
echo "⚠️ El archivo magicserve.json ya existe en este directorio."
|
|
432
|
+
exit 1
|
|
433
|
+
fi
|
|
434
|
+
cat <<EOF > "$CONFIG_FILE"
|
|
435
|
+
[
|
|
436
|
+
{
|
|
437
|
+
"path": "../tu-proyecto-frontal",
|
|
438
|
+
"domain": "tu-proyecto.test",
|
|
439
|
+
"type": "node",
|
|
440
|
+
"port": 3000
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
"path": "../tu-api-backend",
|
|
444
|
+
"domain": "api.tu-proyecto.test",
|
|
445
|
+
"type": "php",
|
|
446
|
+
"port": 3001,
|
|
447
|
+
"tunnel": "mi-super-api-dev"
|
|
448
|
+
}
|
|
449
|
+
]
|
|
450
|
+
EOF
|
|
451
|
+
echo "✅ Archivo magicserve.json base generado exitosamente."
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
case "$ACTION" in
|
|
455
|
+
init)
|
|
456
|
+
init_config
|
|
457
|
+
;;
|
|
458
|
+
start)
|
|
459
|
+
start_all
|
|
460
|
+
;;
|
|
461
|
+
stop)
|
|
462
|
+
stop_all
|
|
463
|
+
;;
|
|
464
|
+
stopall)
|
|
465
|
+
stop_all_global
|
|
466
|
+
;;
|
|
467
|
+
status)
|
|
468
|
+
status
|
|
469
|
+
;;
|
|
470
|
+
*)
|
|
471
|
+
usage
|
|
472
|
+
;;
|
|
473
|
+
esac
|