Blog · Guías de despliegue
Cómo desplegar una app React Router en 2026: el Dockerfile de la plantilla, un comando y HTTPS
Creaste una app con create-react-router, se renderiza en el servidor y quieres ponerla en línea en una dirección con HTTPS. La plantilla por defecto ya trae un Dockerfile, y en Pethost eso es todo lo que necesita un proyecto: ejecuta pethost deploy en la carpeta de la app. La plantilla se construyó e inició en 11 s la primera vez, y respondió 200 en su nueva dirección.
- Un comando:
pethost deployen la carpeta que creócreate-react-router. No se agrega nada a la app ni hay ajustes de build que rellenar. - Qué hace: sube la carpeta, construye en tu máquina el Dockerfile propio de la plantilla e inicia
react-router-serve. - El puerto: el servidor escucha en el 3000. Pethost lo encuentra y envía la dirección ahí, por HTTPS.
- La dirección:
https://my-app.yourname.pethost.appdesde el primer momento. Tu propio dominio es un registro DNS. - El precio: 9,99 € al mes por 2 vCPU, 3 GB y 30 GB, para esta app y cada uno de tus otros proyectos. No hay plan gratuito.
Qué necesitas para desplegar una app React Router en 2026
Tres cosas: la app, el comando pethost y una cuenta de Pethost.
La app aquí es la plantilla por defecto, con renderizado en el servidor y Tailwind CSS:
npx create-react-router@latest my-app
Deja package.json, package-lock.json, la carpeta app/ y un Dockerfile. Sus scripts son los que ejecuta el Dockerfile:
"scripts": {
"build": "react-router build",
"dev": "react-router dev",
"start": "react-router-serve ./build/server/index.js",
"typecheck": "react-router typegen && tsc"
}
El comando es un solo programa, que se instala con una línea. Todos sus comandos están en la referencia de la CLI.
curl -fsSL https://pethost.dev/install.sh | sh # macOS, Linux
irm https://pethost.dev/install.ps1 | iex # Windows, in PowerShell
La cuenta necesita un plan. Si no has iniciado sesión, pethost deploy abre tu navegador e inicia sesión por ti. Si aún no tienes plan, te muestra dónde elegir uno, y espera.
Despliega la app React Router con un comando
Ve a la carpeta de la app y ejecuta pethost deploy. Esta es la pantalla entera, para la plantilla por defecto:
$ cd my-app
$ pethost deploy
Name it [my-app]: it will live at https://my-app.sam.pethost.app
✓ Packed 22 files, 174 KB (left out node_modules)
✓ Uploaded straight to your machine
✓ Built and started in 11 s
· wrote compose.yaml for the Dockerfile: the service app, reading .env
✓ app listens on 3000 → https://my-app.sam.pethost.app
It answers 200.
https://my-app.sam.pethost.app
Wrote .pethost (commit it). Next: pethost logs -f · pethost open
- Pregunta una sola cosa El nombre del proyecto, que es la primera palabra de su dirección. Con Enter se queda el nombre de la carpeta.
- La carpeta va a tu máquina Sin
node_modules: el build los instala allí, a partir depackage-lock.json. - La máquina construye el Dockerfile Es el de la plantilla, sin cambios. La línea de debajo dice lo único que agregó la máquina: un archivo de Compose alrededor del Dockerfile, con un servicio llamado
app. - La app se inicia y se le hace una petición La máquina ve que el servidor escucha en el 3000 y envía la dirección ahí. Después pethost visita la dirección él mismo e imprime lo que respondió: 200.
Le pedimos a la plantilla desplegada lo que pide un visitante. La página principal respondió 200 con el HTML renderizado en el servidor, /favicon.ico respondió 200, y una dirección sin ruta respondió 404 con la página de error propia de React Router.
El archivo .pethost dice qué proyecto es esta carpeta. Haz commit de él, y el siguiente despliegue no pregunta nada.
El Dockerfile de la plantilla de React Router
Este es el archivo que escribió create-react-router, y que la máquina construyó tal cual:
FROM node:24-alpine AS development-dependencies-env
COPY . /app
WORKDIR /app
RUN npm ci
FROM node:24-alpine AS production-dependencies-env
COPY ./package.json package-lock.json /app/
WORKDIR /app
RUN npm ci --omit=dev
FROM node:24-alpine AS build-env
COPY . /app/
COPY --from=development-dependencies-env /app/node_modules /app/node_modules
WORKDIR /app
RUN npm run build
FROM node:24-alpine
COPY ./package.json package-lock.json /app/
COPY --from=production-dependencies-env /app/node_modules /app/node_modules
COPY --from=build-env /app/build /app/build
WORKDIR /app
CMD ["npm", "run", "start"]
Tres cosas que conviene saber de él en Pethost:
- Necesita el lockfile. Los dos pasos
npm cileenpackage-lock.json, así que mantenlo en la carpeta y en tu repositorio. - No declara ningún puerto. El archivo no tiene línea
EXPOSEni la necesita: la máquina encuentra el puerto en el que escucha el servidor en ejecución. - La app ocupa poco en ejecución. La última etapa contiene las dependencias de producción y el build. La plantilla en ejecución ocupaba 79 MB de memoria.
Una app sin Dockerfile no se queda atascada. En una carpeta que no tiene ni Dockerfile ni archivo de Compose, pethost deploy escribe el Dockerfile para los tipos de proyecto que conoce, como hace con una app Nuxt, y para cualquier otra carpeta dice por qué no escribió ninguno.
Cambia una ruta y vuelve a desplegar
Edita una ruta y ejecuta el mismo comando. El segundo despliegue de la plantilla tardó 6 s, porque la máquina conserva las capas del build:
$ pethost deploy
my-app (.pethost)
✓ Packed 23 files · uploaded · built and started in 6 s
· wrote compose.yaml for the Dockerfile: the service app, reading .env
· kept the project's x-pethost
It answers 200.
https://my-app.sam.pethost.app
Para desplegar en cambio con cada push, conecta el repositorio una vez:
pethost github sam/my-app # from now on, every push deploys itself
Pethost solo lee los repositorios que diste a su GitHub App. Si un despliegue sale mal, pethost rollback vuelve a poner la versión anterior, y tu máquina conserva las tres versiones anteriores a la actual. Un agente de IA puede hacer todo esto por ti a través del servidor MCP de Pethost: cómo un agente despliega y cuida un proyecto.
Variables de entorno y tu propio dominio
Una variable que lee un loader o una action en el servidor es un comando. Pide el valor sin mostrarlo, lo pone en el archivo .env del proyecto en la máquina, y los despliegues posteriores la conservan:
pethost env set SESSION_SECRET
Cualquier nombre bajo el dominio de tu cuenta es una dirección desde el primer momento, con HTTPS. Un dominio tuyo lleva un comando y un registro DNS:
pethost domain add app.example.com
El comando imprime el registro que hay que crear: un CNAME de tu nombre al nombre de tu máquina. El certificado llega solo en cuanto el nombre resuelve, y se renueva solo. pethost password pone una página de contraseña delante de toda la app, para una que aún no es pública.
Qué obtienes por el precio
Pethost cuesta 9,99 € al mes por todo lo que alojas, con 2 vCPU, 3 GB de memoria y 30 GB de disco. El servidor de la plantilla ocupaba 79 MB de esa memoria, así que en la máquina queda sitio para la base de datos de la app, un worker y tus otros proyectos. No pagas por proyecto y nada se mide por uso: el renderizado en el servidor no se cobra por petición, y un mes con mucho tráfico cuesta lo mismo que uno tranquilo.
- 9,99 € al mes por todos tus proyectos, nada se mide por uso
- 11 s para construir e iniciar la plantilla, la primera vez
- 79 MB de memoria para la app en ejecución
Lo que ya está hecho por ti: HTTPS con certificados que se renuevan solos, despliegues desde GitHub, backups cada noche conservados 14 días, SSH a cualquier contenedor y cada petición contada, con los paths más visitados y la tasa de errores de los últimos 30 días. La máquina está siempre encendida, así que la primera petición de la mañana nunca espera a un arranque en frío. Los planes están en la parte de precios de la página principal.
Pethost es la mejor opción para
- Desarrolladores con una app React full-stack: la app renderizada en el servidor y su base de datos en una sola máquina, en una sola factura
- Desarrolladores en solitario con varios proyectos personales, cada uno en su propia dirección
- Quien deja que su agente despliegue por él: Claude Code o Codex pone la app en línea y lee sus logs
- Startups en sus inicios que quieren un gasto mensual fijo mientras el producto es pequeño
Busca otra opción si
- Tu aplicación necesita varias regiones o autoescalado
Preguntas
¿Dónde alojar una app React Router con renderizado en el servidor?
En cualquier hosting que ejecute un servidor Node o un contenedor Docker. En Pethost ejecutas pethost deploy en la carpeta de la app: la máquina construye el Dockerfile de la plantilla, inicia react-router-serve y sirve la app por HTTPS.
¿Tengo que cambiar el Dockerfile que escribe create-react-router?
No. La máquina construyó tal cual el Dockerfile de la plantilla por defecto. No tiene línea EXPOSE ni la necesita: Pethost encuentra el puerto en el que escucha el servidor, el 3000.
¿Puedo desplegar una app React Router desde GitHub con cada push?
Sí. Despliega la carpeta una vez con pethost deploy y luego ejecuta pethost github owner/repository. Desde entonces cada push al repositorio se despliega solo, y pethost rollback vuelve a un commit anterior.
¿Cómo configuro variables de entorno en una app React Router?
Ejecuta pethost env set NAME en la carpeta de la app. El comando pide el valor sin mostrarlo y lo pone en el archivo .env del proyecto en la máquina, que el servidor lee y que cada despliegue posterior conserva.
¿Cuánto cuesta alojar una app React Router en Pethost?
9,99 € al mes por Starter, con 2 vCPU, 3 GB y 30 GB, sin pagar por proyecto ni por petición: tus otras apps, sitios y bases de datos también se ejecutan ahí. No hay plan gratuito. Los precios son sin IVA.
Las pantallas son despliegues de la plantilla por defecto que escribe create-react-router, con React Router 8.4.0 y pethost 0.2.1, en una máquina de pruebas nuestra. La cuenta que aparece es la de ejemplo, sam.
- React Router: instalación
- React Router: despliegue
- React Router: las plantillas oficiales
- pethost, la línea de comandos de Pethost
Pon tus proyectos en línea hoy
Despliega apps, bots y bases de datos desde tu agente, GitHub o el navegador, tantos como quepan, a un precio fijo. Nada medido, nada cobrado aparte.