> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Env file

> Guide to exporting pod environment variables with Telepresence into a .env file and loading them with dotenv so local processes receive API_URL and behave like in-cluster pods

In this lesson you will reproduce and fix a common problem that occurs when using Telepresence to intercept a Kubernetes deployment: your locally running process fails because a pod environment variable containing the inventory service URL (`API_URL`) is not present on your workstation.

This guide walks through the failure scenario, explains why it happens, and shows how to export pod environment variables with Telepresence into a `.env` file and consume them locally with `dotenv`.

## Problem overview

* The Kubernetes Deployment sets `API_URL` in the container environment to point at the in-cluster inventory service.
* When you create a Telepresence intercept and run the application locally, those pod environment variables are not automatically available to the local process.
* The local process then attempts to call the inventory service with an undefined URL and throws `ERR_INVALID_URL`.

Example error when `API_URL` is undefined:

```text theme={null}
Error [ERR_INVALID_URL]: Invalid URL: undefined?product_ids=1,2,3
    at onParseError (internal/url.js:263:9)
    at new URL (internal/url.js:339:5)
    ...
{
  code: 'ERR_INVALID_URL',
  input: 'undefined?product_ids=1,2,3'
}
```

Reproducing snippet that fails when `apiURL` is undefined:

```javascript theme={null}
const products = [];

app.get("/", async (req, res) => {
  try {
    const productIds = req.query.product_ids;
    console.log(productIds);
    const idsArray = productIds.split(",").map((id) => parseInt(id.trim(), 10));
    console.log(idsArray);
    const filteredProducts = products.filter((product) =>
      idsArray.includes(product.id)
    );
    console.log(filteredProducts);

    // If apiURL is undefined, this fetch will throw ERR_INVALID_URL
    const response = await fetch(`${apiURL}?product_ids=${idsArray.join(",")}`);
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const inventory = await response.json();
    // ... respond with combined product + inventory data
  } catch (err) {
    console.error(err);
    res.status(500).send(err.message);
  }
});
```

Note: the snippet above references `apiURL` directly; unless you set `apiURL` from `process.env.API_URL` the variable will be `undefined` and the request URL will be invalid.

## Deployment manifest example (shows API\_URL set in the pod)

```yaml theme={null}
spec:
  template:
    spec:
      containers:
      - name: products
        volumeMounts:
        - name: db-config
          mountPath: /tmp
        ports:
        - containerPort: 3000
          name: web
        env:
        - name: "API_URL"
          value: "http://inventory-service:3000/"
---
apiVersion: v1
kind: Service
metadata:
  name: products-service
spec:
  type: LoadBalancer
```

## Why it fails when intercepting

* The Deployment configures `API_URL` for the container when running in-cluster.
* Telepresence intercepts by stopping the real pod traffic and routing traffic to your workstation. It does not automatically inject the pod's environment variables into your shell.
* Your local process therefore does not have the same environment (internal DNS names, service ports), causing service calls to fail.

## Solution overview

Use Telepresence's `--env-file` option to export the pod environment to a file (commonly named `.env`), then load that file into your local Node.js process with a library such as `dotenv`. This ensures your local process sees the same values (for example, `API_URL`) as the in-cluster pod.

## Step-by-step reproduction and fix

1. Make sure there's no existing intercept for the workload:

```bash theme={null}
telepresence list
telepresence leave products-depl
```

2. Create an intercept and ask Telepresence to write the pod's environment to a file (by convention `.env`):

```bash theme={null}
telepresence intercept products-depl -p 8000 --env-file .env
```

Sample Telepresence output:

```text theme={null}
Using Deployment products-depl
    Intercept name          : products-depl
    State                   : ACTIVE
    Workload kind           : Deployment
    Destination             : 127.0.0.1:8000
    Service Port Identifier : 3000/TCP
    Volume Mount Point      : /tmp/telfs-3110725221
    Intercepting            : all TCP connections
```

3. Telepresence will create the `.env` file in your current directory. It contains all the pod environment variables, for example:

```dotenv theme={null}
API_URL=http://inventory-service:3000/
AUTH_SERVICE_PORT=tcp://10.100.10.52:3000
AUTH_SERVICE_PORT_3000_TCP=tcp://10.100.10.52:3000
AUTH_SERVICE_PORT_3000_TCP_ADDR=10.100.10.52
AUTH_SERVICE_PORT_3000_TCP_PORT=3000
AUTH_SERVICE_PORT_3000_TCP_PROTO=tcp
AUTH_SERVICE_SERVICE_HOST=10.100.10.52
AUTH_SERVICE_SERVICE_PORT=3000
A_TELEPRESENCE_MOUNTS=/tmp:/var/run/secrets/kubernetes.io/serviceaccount
INVENTORY_SERVICE_PORT=tcp://10.100.246.69:3000
INVENTORY_SERVICE_PORT_3000_TCP=tcp://10.100.246.69:3000
INVENTORY_SERVICE_PORT_3000_TCP_ADDR=10.100.246.69
INVENTORY_SERVICE_PORT_3000_TCP_PORT=3000
INVENTORY_SERVICE_PORT_3000_TCP_PROTO=tcp
INVENTORY_SERVICE_SERVICE_HOST=10.100.246.69
INVENTORY_SERVICE_SERVICE_PORT=3000
KUBERNETES_PORT=tcp://10.100.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.100.0.1:443
KUBERNETES_PORT_443_TCP_ADDR=10.100.0.1
```

4. Update your local Node.js application to load `.env` and override any existing environment variables so the local process uses the same values as the pod.

Example Express server that uses `dotenv` and reads `API_URL` from `process.env`:

```javascript theme={null}
// Load environment variables from .env and override any existing values
require('dotenv').config({ override: true });

const express = require("express");
const app = express();
const port = 8000;

// Ensure we use the environment variable provided by Telepresence (.env)
const apiURL = process.env.API_URL;
console.log("API_URL:", apiURL);

const products = [
  {
    id: 1,
    name: "iphone 14",
    price: 900,
    category: "electronics",
    onSale: false
  },
  {
    id: 2,
    name: "pixel 7",
    price: 600,
    category: "electronics",
    onSale: true
  }
];

app.get("/", async (req, res) => {
  try {
    const productIds = req.query.product_ids || '';
    const idsArray = productIds
      .split(",")
      .map((id) => parseInt(id.trim(), 10))
      .filter(Number.isFinite);

    const filteredProducts = products.filter((product) =>
      idsArray.includes(product.id)
    );

    // apiURL should now be defined from process.env.API_URL
    const response = await fetch(`${apiURL}?product_ids=${idsArray.join(",")}`);
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const inventory = await response.json();

    res.json({
      products: filteredProducts,
      inventory
    });
  } catch (err) {
    console.error(err);
    res.status(500).send(err.message);
  }
});

app.listen(port, () => {
  console.log(`Products service listening at http://localhost:${port}`);
});
```

Once you have the `.env` file created by Telepresence and you run your local server with the code above, requests that require the inventory service should succeed because `API_URL` is now defined as it was in-cluster.

<Callout icon="lightbulb" color="#1CB2FE">
  Node runtime note: The example uses global `fetch` — available in Node 18+. If you are on an older Node version, install and import `node-fetch` (or upgrade Node) before using `fetch`.
</Callout>

## Quick reference: Telepresence commands and files

| Purpose | Command / File | Notes |
| - | - | - |
| List current intercepts | `telepresence list` | Shows active intercepts and statuses |
| Remove an intercept | `telepresence leave products-depl` | Replace `products-depl` with your intercept name |
| Create intercept and export pod env | `telepresence intercept products-depl -p 8000 --env-file .env` | `--env-file` writes pod env vars to `.env` |
| Local env file | `.env` | Contains `API_URL` and other in-cluster env values; do not commit |

## Summary

* The Deployment configured `API_URL` in the pod, but when you intercept and run locally you must provide those same environment variables on your workstation.
* Telepresence's `--env-file` option extracts pod environment variables to a file (commonly `.env`).
* Use a library such as `dotenv` to load that file into your local process so the local behavior matches the in-cluster environment.

<Callout icon="lightbulb" color="#1CB2FE">
  Add your `.env` file to `.gitignore` and avoid committing it. The `.env` file may contain internal IPs and service endpoints that should not be checked into source control.
</Callout>

## Links and references

* Telepresence (official project): [https://www.telepresence.io/](https://www.telepresence.io/)
* Telepresence docs: [https://www.telepresence.io/docs/](https://www.telepresence.io/docs/)
* dotenv npm package: [https://www.npmjs.com/package/dotenv](https://www.npmjs.com/package/dotenv)
* Kubernetes documentation: [https://kubernetes.io/docs/](https://kubernetes.io/docs/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/telepresence-for-kubernetes/module/0eb5dcb6-2e2a-40d9-9caa-bd3149741aeb/lesson/2a2316b1-448a-4d03-994b-8d5ce97d3edf" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.