Variables de entorno en Windows, Linux y macOS sin errores

Saúl Perales .

6 de agosto de 2026

Mujer sonríe junto a un escritorio de Linux con carpetas, el pingüino Tux y gráficos de uso de CPU. Se habla de variables de entorno.

Una aplicación cambia de comportamiento según el equipo, el usuario o el entorno donde se ejecuta. Las variables de entorno permiten comunicarle esos valores dinámicos sin modificar el código, desde la ruta de una carpeta hasta el modo de producción o la dirección de una base de datos. Explico cómo funcionan, cómo configurarlas en Windows, Linux y macOS, y qué precauciones conviene aplicar para no convertir un ajuste práctico en un problema de seguridad.

La configuración correcta separa el código de los valores que cambian

  • Definición Las variables son pares formados por un nombre y un valor que un proceso puede leer durante su ejecución.
  • Ámbitos Pueden existir solo en una terminal, afectar a un usuario o aplicarse a todo el sistema.
  • Comandos Linux y macOS utilizan normalmente export, mientras PowerShell emplea $env:NOMBRE.
  • Seguridad Un archivo .env no cifra las credenciales y nunca debería subirse al repositorio.
  • Despliegues Docker y las plataformas CI/CD permiten inyectar configuración distinta en cada entorno.

Diagrama muestra cómo las variables de entorno globales son accesibles en un proceso, pero las variables modificadas localmente no se comparten con otros procesos.

Qué son y cómo llegan a una aplicación

Una variable de entorno es un dato de configuración expresado como un par NOMBRE=valor. El sistema operativo lo pone a disposición de un proceso, y este puede leerlo cuando arranca o mientras funciona. Por ejemplo, LANG=es_ES.UTF-8 puede influir en el idioma, mientras PORT=3000 indica en qué puerto debe escuchar un servidor.

La idea importante es que el valor vive fuera del código fuente. Una misma aplicación puede conectarse a una base de datos local durante el desarrollo y a un servicio gestionado en producción usando exactamente el mismo programa, pero con configuraciones diferentes.

El proceso suele recibir una copia del entorno de su proceso padre. Por eso, una variable creada en una terminal normalmente está disponible para los programas lanzados desde ella, pero no necesariamente para una aplicación que ya estaba abierta o para otra terminal independiente. Esta herencia explica muchos errores que parecen inexplicables al principio.

Variables predefinidas y variables de aplicación

El sistema incluye valores habituales como PATH, HOME, USER, TEMP o USERPROFILE. PATH es especialmente relevante porque contiene las carpetas donde la terminal busca ejecutables cuando escribimos comandos como node, python o git.

Las variables creadas por una aplicación tienen otro propósito. Nombres como DATABASE_URL, API_BASE_URL, LOG_LEVEL o APP_ENV describen la configuración que necesita ese proyecto. Yo prefiero usar nombres claros y consistentes, normalmente en mayúsculas y con guiones bajos, porque así se localizan rápido en scripts y registros de despliegue.

Para qué sirven en el desarrollo de software

Su utilidad principal está en separar la lógica estable de los valores que cambian entre máquinas. Esto evita editar archivos cada vez que se cambia de ordenador, se prueba una API distinta o se publica una nueva versión.

  • Configuración por entorno: APP_ENV=development puede activar mensajes detallados, mientras APP_ENV=production aplica un comportamiento más restrictivo.
  • Rutas y puertos: una aplicación puede recibir UPLOAD_DIR o PORT sin asumir una ubicación fija.
  • Servicios externos: API_BASE_URL permite cambiar entre una API de pruebas y la real.
  • Opciones de ejecución: LOG_LEVEL=debug ayuda a diagnosticar errores, aunque conviene desactivarlo en producción.
  • Automatización: scripts de compilación, pruebas y despliegue pueden reutilizarse con distintos valores.

También ayudan a trabajar en equipo. Cada desarrollador puede tener una base de datos local y unas credenciales propias sin introducir cambios personales en los archivos compartidos. El proyecto debe incluir, eso sí, un archivo de ejemplo como .env.example con los nombres necesarios y valores ficticios.

No todo debe convertirse en una variable. Una regla de formato, una ruta crítica del programa o una opción que jamás cambia suele encajar mejor en la configuración versionada. Cuando se externaliza absolutamente todo, el sistema gana flexibilidad pero pierde trazabilidad y facilidad de diagnóstico.

Cómo configurarlas en Windows, Linux y macOS

Linux y macOS

En una terminal compatible con Bash o Zsh, una variable temporal se define así:

export API_BASE_URL="http://localhost:8080"
export PORT="3000"

Solo afectará a esa sesión y a los procesos que se lancen desde ella. Para comprobar el valor se puede usar echo "$PORT" o printenv PORT. Para eliminarlo, el comando es unset PORT.

Si se necesita cargarla automáticamente, puede añadirse a ~/.bashrc, ~/.zshrc o ~/.profile, según el shell y el tipo de sesión. Después hay que abrir una terminal nueva o recargar el archivo con source ~/.zshrc. Yo suelo probar primero el cambio de forma temporal; así evito dejar una configuración incorrecta en todos los inicios de sesión.

Windows PowerShell

En PowerShell, la sintaxis para la sesión actual es distinta:

$env:API_BASE_URL = "http://localhost:8080"
$env:PORT = "3000"

Para consultar las variables disponibles se puede ejecutar Get-ChildItem Env: o leer una concreta con $env:PORT. El equivalente habitual en el símbolo del sistema es set PORT=3000, pero esa asignación también queda limitada a la ventana actual.

Para una configuración persistente, Windows ofrece el cuadro de Variables de entorno dentro de las propiedades avanzadas del sistema. PowerShell también permite establecer valores de usuario con [Environment]::SetEnvironmentVariable("PORT","3000","User"). Las aplicaciones abiertas antes del cambio pueden conservar el entorno anterior, por lo que a menudo es necesario reiniciarlas.

La diferencia entre temporal y permanente

Alcance Duración Uso recomendable
Sesión de terminal Hasta cerrar la terminal Pruebas rápidas y diagnósticos
Usuario Hasta modificarla o eliminarla Herramientas y preferencias personales
Sistema Disponible para varios usuarios y servicios Configuración compartida del equipo
Proceso o contenedor Mientras se ejecuta ese servicio Aplicaciones aisladas y despliegues

El alcance más amplio no siempre es el mejor. Una ruta de desarrollo puede pertenecer al usuario, mientras que un valor para un servicio concreto debería quedarse en su proceso o contenedor. Cuanto menor sea el ámbito, menor será también la posibilidad de afectar accidentalmente a otras aplicaciones.

Archivos .env, contenedores y despliegues automáticos

Muchos proyectos utilizan un archivo llamado .env para reunir valores locales:

APP_ENV=development
PORT=3000
DATABASE_URL=postgresql://usuario:contraseña@localhost:5432/app

Este formato resulta cómodo, pero no es universal. El sistema operativo no carga automáticamente un .env; debe hacerlo el framework, una biblioteca o la herramienta de ejecución. En Node.js, Python, Laravel, Docker Compose y otros entornos, la lectura depende de la configuración concreta del proyecto.

La práctica básica es añadir .env a .gitignore y publicar únicamente .env.example. El archivo de ejemplo documenta nombres, formatos y valores de muestra, pero nunca debe contener una contraseña real. Si una credencial ya se ha subido a Git, borrarla del último commit no basta: hay que revocarla y sustituirla.

Docker Compose

En Docker, los valores pueden pasar al contenedor desde el archivo de composición, un archivo de entorno o la línea de comandos. Un ejemplo sencillo sería:

services:
  web:
    image: mi-aplicacion:latest
    environment:
      APP_ENV: production
      PORT: 8080

La aplicación dentro del contenedor verá esos valores como parte de su entorno. Esto permite usar la misma imagen en pruebas y producción con configuraciones distintas. Sin embargo, incluir una contraseña directamente en docker-compose.yml puede exponerla al repositorio, a las copias de seguridad o a los registros de cambios.

Para información sensible, prefiero mecanismos de secretos proporcionados por el orquestador o el proveedor de alojamiento. Una variable de entorno sirve para configuración; no ofrece por sí sola cifrado, control de acceso ni ocultación frente a cualquier proceso con permisos suficientes.

CI/CD y variables por entorno

Las plataformas de integración y despliegue continuo permiten definir valores a nivel de proyecto, organización o entorno. Así, una canalización puede usar una URL de pruebas en la rama de desarrollo y otra de producción al publicar una versión aprobada.

Conviene distinguir entre una variable normal, que puede ser visible en la configuración o en los registros, y un secreto protegido. Las claves de API, tokens, certificados y contraseñas deben almacenarse en el gestor de secretos de la plataforma, limitarse al entorno que las necesita y evitarse en comandos que puedan quedar registrados.

Errores habituales que provocan fallos difíciles de ver

Confundir la sintaxis del shell

export PORT=3000, set PORT=3000 y $env:PORT="3000" no son intercambiables. Cada orden pertenece a una herramienta distinta. Copiar un comando de Linux en PowerShell puede crear un valor incorrecto o no crear ninguno.

Modificar PATH sin conservar lo anterior

Reemplazar PATH por una sola carpeta puede hacer que desaparezcan comandos esenciales del sistema. En sistemas Unix se suele ampliar con export PATH="$PATH:/nueva/ruta"; en Windows, la edición debe conservar las entradas existentes. Las rutas duplicadas no suelen romper nada de inmediato, pero dificultan saber qué versión de un ejecutable se está utilizando.

Olvidar las comillas y los tipos

Los valores se manejan normalmente como texto. Si una contraseña contiene espacios, caracteres especiales o símbolos interpretados por el shell, necesita una forma de escape adecuada. Además, PORT=3000 llega a muchas aplicaciones como la cadena "3000", por lo que el programa debe convertirla a número y validar que esté dentro de un rango razonable.

Esperar que una aplicación ya abierta vea el cambio

Una variable modificada en la terminal no actualiza automáticamente los procesos que ya estaban ejecutándose. Reiniciar el servidor, el IDE o el servicio suele ser la solución. En Windows, también puede hacer falta cerrar y volver a abrir el programa que inicia la aplicación.

Lee también: Cómo borrar las cookies en Chrome, Edge, Firefox y Safari

Usar un nombre distinto al que espera el código

DATABASE_URL, DATABASE_URI y DB_URL pueden parecer equivalentes para una persona, pero son nombres diferentes para el programa. Mantener una lista de variables obligatorias y validar su presencia al arrancar produce errores claros en lugar de fallos silenciosos a mitad de una petición.

Cómo usarlas sin crear un riesgo de seguridad

El error más extendido consiste en creer que una variable de entorno es un almacén seguro. En realidad, puede aparecer en volcados de procesos, paneles de depuración, registros, herramientas de monitorización o mensajes de error. No debe imprimirse su valor en logs, especialmente durante una incidencia.

  • Guarda las credenciales en un gestor de secretos cuando el proyecto sale del ordenador local.
  • Concede a cada servicio solo los permisos que necesita y utiliza tokens con caducidad cuando sea posible.
  • Valida que las variables obligatorias existan antes de iniciar la aplicación.
  • Comprueba el formato de URLs, puertos, rutas y valores booleanos.
  • Revisa el historial de Git si una clave se expone y rótala de inmediato.
  • Evita pasar secretos como argumentos de comandos, porque pueden quedar visibles en el historial o en la lista de procesos.

También aplico una separación sencilla entre valores públicos y sensibles. El nombre de una API, el nivel de logs o un puerto no tienen el mismo riesgo que un token de acceso. Tratar todo como secreto complica el trabajo; tratar todo como público puede provocar una filtración seria.

En aplicaciones web, estas variables suelen leerse en el servidor. Exponerlas al navegador o incluirlas durante la compilación puede hacer que cualquier visitante las vea. Antes de usar un prefijo destinado al cliente, compruebo qué valores terminan realmente en el código JavaScript distribuido.

Una configuración sencilla que sigue siendo mantenible

Para un proyecto pequeño, mi método consiste en documentar cada nombre en .env.example, cargar los valores reales fuera del repositorio y validar la configuración al inicio. Después pruebo el mismo arranque en desarrollo, pruebas y producción con un conjunto de valores específico para cada entorno.

La clave no está en crear muchas variables, sino en que cada una tenga un propósito claro, un responsable y un ámbito controlado. Cuando una aplicación falla, saber de dónde procede cada valor reduce mucho el tiempo de diagnóstico y evita cambios improvisados en el código.

Bien utilizadas, estas variables convierten la configuración en una pieza flexible del software. No sustituyen a un gestor de secretos ni corrigen una arquitectura deficiente, pero ofrecen una base limpia para ejecutar la misma aplicación en varios equipos, contenedores y entornos sin duplicar el código.

Preguntas frecuentes

Un proceso suele recibir una copia del entorno de su proceso padre. Por eso, una variable creada en una terminal está disponible para los programas que se lancen desde ella, pero no necesariamente para otra terminal ni para una aplicación que ya estaba abierta.
En Linux y macOS, export PORT="3000" solo afecta a la sesión actual y a sus procesos descendientes; en PowerShell se usa $env:PORT = "3000". Para conservarla, puede añadirse a archivos como ~/.bashrc o ~/.zshrc, o configurarse en Windows mediante las propiedades avanzadas del sistema.
Un archivo .env no cifra las credenciales. Debe incluirse en .gitignore y sustituirse por un .env.example con valores ficticios; si una clave real se sube a Git, hay que revocarla y reemplazarla, no solo borrar el commit.
Docker Compose puede inyectarlas en el contenedor mediante la configuración, un archivo de entorno o la línea de comandos, permitiendo usar la misma imagen con valores distintos. En CI/CD, las contraseñas, tokens y claves deben guardarse como secretos protegidos, limitarse al entorno necesario y no aparecer en registros.
Calificar artículo

Promedio: 0.0 / 5 · 0 calificaciones

Etiquetas

docker powershell ci/cd variables de entorno secretos
Autor Saúl Perales
Saúl Perales
Soy Saúl Perales y mi trayectoria profesional abarca 15 años dedicados a desentrañar los complejos mundos de la tecnología, la inteligencia artificial y la ciberseguridad. Desde siempre me ha fascinado la forma en que la tecnología moldea nuestro presente y futuro, y mi objetivo es traducir esa fascinación en contenido accesible y útil para todos los lectores de esediciones.es. Me esfuerzo por analizar las tendencias emergentes, contrastar la información de fuentes fiables y simplificar conceptos que a menudo pueden parecer abrumadores, asegurando siempre que el conocimiento que comparto sea preciso, actual y fácil de comprender. Mi enfoque se centra en ofrecer una perspectiva clara y fundamentada sobre los avances y desafíos en estos campos dinámicos.
Comentarios (0)
Añadir comentario