Entornos de desarrollo, staging y producción

Desarrollo es donde escribes el código, staging es una copia parecida a producción para la revisión final y producción atiende a los usuarios reales. Cada uno tiene su config, secretos y datos, con el mismo código.

Actualizado el 9 min de lectura

Objetivos de aprendizaje

Después de leer este artículo podrás:

  • Explicar para qué sirve cada entorno y cuándo vale la pena tener staging
  • Separar config, secretos y bases de datos por entorno
  • Promover el mismo código de desarrollo a staging y a producción
En esta página

Toda app empieza igual: la ejecutas en tu laptop, funciona, la subes y los usuarios reales la ven. El problema llega cuando el "en mi máquina funciona" se encuentra con una base de datos de producción, una clave de API distinta o un proveedor de pagos que cobra tarjetas de verdad.

Los entornos separados resuelven eso. Ejecutas el mismo código en más de un lugar, y cada lugar tiene su propia configuración y sus propios datos. Un error en uno no llega a los demás.

push a developmerge a main+ aprobación manualDesarrollotu máquinaa1b2c3ddevelopmentclave localdatos falsosStagingrevisión finala1b2c3dstagingclave de pruebaanonimizadosProducciónusuarios realesa1b2c3dproductionclave realdatos reales
El mismo commit pasa por los tres entornos; solo cambian la config, los secretos y los datos entre uno y otro.

¿Qué son desarrollo, staging y producción?#

Un entorno es una copia en ejecución de tu app junto con todo lo que necesita: config, secretos, base de datos y almacenamiento.

Entorno Quién lo usa Datos Para qué
Desarrollo Tú, en tu máquina Falsos, desechables Escribir y depurar código rápido
Staging Tú y tu equipo, a veces un cliente Falsos o anonimizados Revisión final de un build parecido a producción
Producción Usuarios reales Reales Servir la app en vivo

Algunos equipos añaden un entorno de preview por pull request, o llaman a staging "QA" o "preproducción". Los nombres dan igual. Lo importante es que cada uno esté aislado.

¿Por qué staging compensa el trabajo extra?#

El desarrollo local oculta problemas que solo aparecen en un servidor: una variable de entorno que falta, otra versión del runtime, una regla de firewall, una base de datos mucho más grande que tus datos de prueba. The Twelve-Factor App llama a estas diferencias el problema de paridad entre dev y prod y señala tres brechas: el tiempo entre escribir y publicar el código, quién lo escribe frente a quién lo despliega, y las herramientas usadas en cada lugar.

Staging cierra la brecha de las herramientas. Corre en un servidor, con el mismo runtime y el mismo tipo de base de datos que producción, así que un fallo aparece antes de que lo vean los usuarios. También es el lugar adecuado para probar lo que nunca deberías probar con datos reales: migraciones de base de datos, webhooks de pago en el modo de prueba del proveedor e importaciones masivas.

No siempre lo necesitas. Un bot de hobby de una sola persona y sin usuarios que paguen puede saltarse staging, siempre que puedas revertir rápido. Añádelo cuando un deploy malo cueste dinero o confianza.

¿Qué tiene que cambiar entre entornos?#

Tres cosas cambian de un entorno a otro, y nada más debería cambiar.

1. Configuración. The Twelve-Factor App guarda la config en el entorno, no en el código. Todo lo que varía entre deploys es config: URLs de base de datos, claves de API, la URL pública, el nivel de log. Tu código lee todo eso desde variables de entorno, como se explica en qué son las variables de entorno.

2. Secretos. Staging debe usar tokens y claves distintos de los de producción. Si se filtra una clave de staging, o alguien del equipo la pega en un chat, producción sigue a salvo. En proveedores de pago y plataformas de bots, usa el modo de prueba o un bot de prueba aparte, nunca las credenciales reales.

3. Datos. Nunca apuntes staging a la base de datos de producción. Un script de prueba con un bug editaría filas reales. Crea una base de datos aparte, con el mismo motor y la misma versión que producción. Llénala con datos falsos, o con una copia de producción a la que se le quitaron o mezclaron nombres, correos y tokens.

Todo lo demás, desde la versión del runtime hasta la lista de dependencias, debe coincidir. El código es el mismo commit en todos los entornos.

¿Cómo montas los entornos, paso a paso?#

1. Elige una variable que nombre el entorno. Por ejemplo, APP_ENV con los valores development, staging y production. Úsala para los logs y algunos ajustes, no para grandes cambios de comportamiento. Cuanto más se ramifica tu código según el nombre del entorno, menos demuestra staging.

2. Carga la config en un solo lugar. Este módulo de Node.js lee las variables una vez, falla enseguida si falta alguna y mantiene el resto del código libre de process.env:

js
// config.js
const required = (name) => {
  const value = process.env[name];
  if (!value) throw new Error(`Missing environment variable: ${name}`);
  return value;
};

export const config = {
  env: process.env.APP_ENV ?? "development",
  databaseUrl: required("DATABASE_URL"),
  apiKey: required("API_KEY"),
  logLevel: process.env.LOG_LEVEL ?? "info",
};

En local, pon los valores en un archivo .env que no se sube al repositorio (consulta el archivo .env). En un servidor, defínelos en los ajustes de entorno de la plataforma. En las versiones recientes de Node.js, el propio runtime carga el archivo, sin biblioteca: node --env-file=.env config.js.

3. Crea una app y una base de datos aparte por entorno. Staging tiene su propia app, su propia base de datos y su propio dominio o subdominio. No reutilices la app de producción con otra flag.

4. Asocia ramas a entornos. Un flujo habitual: las ramas de funcionalidad se prueban en local, un push a develop o staging despliega en staging, y un merge a main despliega en producción. Mantén las ramas cortas para que staging no se aleje de main.

5. Promueve el mismo código. Lo que probaste en staging debe ser exactamente el commit que va a producción. Si recompilas desde otras fuentes, o haces merge de cambios extra después de probar, el resultado de staging ya no demuestra nada.

¿Cómo automatizas la promoción con GitHub Actions?#

GitHub Actions tiene una función pensada para esto: los environments. Un environment es un destino con nombre, como staging o production. Cada uno guarda sus propios secretos y variables, y un job que declara environment: production lee los valores de ese environment. Para producción también puedes exigir que un revisor apruebe la ejecución, añadir un temporizador de espera o limitar qué ramas pueden desplegar.

Los secretos de un environment solo llegan a los jobs que lo referencian. También hay límites por plan: en repositorios privados, los environments y reglas como los revisores obligatorios y los temporizadores de espera dependen del plan de GitHub, así que revisa la documentación de environments para tu caso.

Este workflow despliega staging en cada push a develop y producción en cada push a main, con el mismo script de deploy y valores distintos:

yaml
name: Deploy

on:
  push:
    branches: [develop, main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: lts/*
      - run: npm ci
      - run: npm test

  deploy:
    needs: test
    runs-on: ubuntu-latest
    environment:
      name: ${{ github.ref_name == 'main' && 'production' || 'staging' }}
    steps:
      - uses: actions/checkout@v7
      - name: Deploy
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
          TARGET_APP: ${{ vars.TARGET_APP }}
        run: ./scripts/deploy.sh

Crea dos environments en Settings > Environments y define DEPLOY_TOKEN y TARGET_APP en cada uno con valores distintos. El archivo del workflow sigue siendo idéntico. Donde tu plan lo permita, activa revisores obligatorios para production, para que una persona confirme la release. Para lo básico de los workflows, consulta deploys automáticos con GitHub Actions.

¿Cómo manejas los cambios de base de datos entre entornos?#

Los cambios de esquema son la parte más arriesgada de la promoción. Escríbelos como archivos de migración en el repositorio, ejecútalos primero en staging y solo después en producción. Si una migración falla o tarda demasiado en staging, lo descubriste sin costo. Migraciones de base de datos en el deploy cubre el orden y los patrones seguros.

Los datos de staging rara vez son tan grandes como los de producción. Una migración que tarda un segundo en unos cientos de filas puede bloquear una tabla durante minutos con millones. Si ese riesgo importa, prueba con una copia anonimizada de los datos de producción.

¿Cuáles son los errores más comunes?#

  • Staging apuntando a recursos de producción. Basta un .env copiado para que staging escriba en la base de datos real o envíe correos de verdad. Pon nombres claros a las variables y revísalas al crear un entorno.
  • Compartir secretos entre entornos. Una clave de staging filtrada no debe abrir producción.
  • Staging desactualizado. Si ejecuta una rama vieja, otra versión del runtime u otra versión del motor de base de datos, pasar en él demuestra poco. Actualízalo en cada merge.
  • Probar con código distinto al de producción. No añadas atajos como if (staging) que se salten la autenticación o simulen servicios que usas en producción.
  • Notificaciones reales desde staging. Los bots de staging que entran en servidores reales, o las apps que envían correos a clientes reales, generan confusión. Usa cuentas de prueba, un token de bot de prueba y un sandbox de correo.
  • Saltarse la comprobación tras el deploy. Un pipeline en verde solo significa que el comando terminó. Abre la app y lee los logs después de cada release.

Cómo hacerlo en Square Cloud#

En Square Cloud, cada entorno es su propia aplicación con sus propias variables de entorno, así que staging y producción nunca comparten config por accidente. Crea una aplicación para producción y otra para staging. Las variables se definen por aplicación en el panel, la API, la CLI o la extensión de VS Code; el panel puede importar un archivo .env, y un cambio se aplica en el siguiente reinicio, sin rebuild. La variable SQUARECLOUD_APP_ID le da a la app su propio ID en runtime, lo que resulta útil en los logs.

Para los datos, el hosting de bases de datos empieza en el plan Standard; a partir de ese plan, crea una base de datos aparte para staging y dale a cada app su propia cadena de conexión. Las aplicaciones web reciben un subdominio *.squareweb.app en todos los planes, suficiente para una URL de staging; el dominio personalizado para producción empieza en el plan Standard. La RAM del plan es un pool compartido por todas tus aplicaciones, con un mínimo de 256 MB por aplicación en segundo plano y 512 MB por aplicación web, así que la copia de staging consume del mismo pool que producción.

Para automatizar la promoción, usa la GitHub Action oficial con el patrón de environments de arriba. Guarda SQUARECLOUD_API_KEY como secreto y el ID de la aplicación como la variable SQUARECLOUD_APP_ID en cada environment de GitHub:

yaml
      - uses: actions/checkout@v7
      - uses: squarecloudofc/github-action@v2
        with:
          token: ${{ secrets.SQUARECLOUD_API_KEY }}
          command: commit ${{ vars.SQUARECLOUD_APP_ID }} --restart

El environment de staging guarda el ID de la aplicación de staging, y el de producción guarda el de producción. Antes de una release arriesgada, toma un snapshot manual de la aplicación de producción desde el panel; los snapshots manuales están disponibles en todos los planes, y uno se restaura en la misma aplicación o, con un clic, en una aplicación nueva. El archivo de configuración squarecloud.app es opcional: el panel lo genera al desplegar, y escribirlo en la raíz del proyecto es la alternativa. La página de la GitHub Action muestra el workflow completo y las entradas de la action.

Deploy

Sube desde GitHub, la CLI o un ZIP y publica en segundos

Más información

Preguntas frecuentes

¿Necesito un entorno de staging en un proyecto pequeño?

No siempre. Si eres el único desarrollador y un deploy malo cuesta poco, un buen entorno local y un rollback rápido pueden bastar. Añade staging cuando los errores salgan caros: usuarios que pagan, bases de datos compartidas, pagos o un equipo.

¿Staging puede compartir la base de datos de producción?

No. Una prueba, una migración mala o un script con un bug cambiarían datos de usuarios reales. Dale a staging su propia base de datos, con datos falsos o anonimizados.

¿Staging debe usar el mismo código que producción?

Sí. El sentido de staging es probar exactamente el código que irá a producción. Solo cambia la configuración, como la URL de la base de datos, las claves de API y el nombre del entorno.

¿Cuántos entornos necesito?

Dos es el mínimo habitual: tu máquina para desarrollo y producción. Un tercero, staging, se sitúa entre ambos. Los equipos grandes añaden más, como un entorno de preview por pull request.

Siguiente artículo¿Qué es Docker Compose?Docker Compose describe una aplicación de varios contenedores en un archivo YAML y la levanta con un comando. Mira cómo funciona, un ejemplo y sus límites.

Más en Deploy

Ver los 33 artículos