> ## 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 Telepresence with Docker

> Guide showing how to run Telepresence inside Docker to intercept Kubernetes services, run local containers for debugging, use bind mounts for hot reload, and build images with Telepresence

In this lesson we'll demonstrate running the Telepresence user daemon inside a Docker container on your local machine. Running Telepresence in Docker is less intrusive than changing host networking, avoids requiring elevated privileges, and makes it easier to run Telepresence alongside other local tooling.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/Sd_r7JaRKfit4jl0/images/Telepresence-for-Kubernetes/Telepresence-For-Kubernetes/Demo-Telepresence-with-Docker/telepresence-docker-demo-slide-kodekloud.jpg?fit=max&auto=format&n=Sd_r7JaRKfit4jl0&q=85&s=5db7bca7491681be1622ac3fc29ba0e4" alt="A presentation slide with &#x22;Demo&#x22; on the left and a turquoise curved panel on the right reading &#x22;Telepresence with Docker.&#x22; The slide also shows a small &#x22;© Copyright KodeKloud&#x22; note in the bottom-left corner." width="1920" height="1080" data-path="images/Telepresence-for-Kubernetes/Telepresence-For-Kubernetes/Demo-Telepresence-with-Docker/telepresence-docker-demo-slide-kodekloud.jpg" />
</Frame>

Prerequisites:

* Telepresence installed (v2.x+ recommended)
* Docker installed and running
* Access to a Kubernetes cluster (context configured)

***

## 1) Run the Telepresence user daemon inside Docker

First, disconnect any active Telepresence session and then connect using the `--docker` flag to run the Telepresence user daemon inside a container:

```bash theme={null}
# Stop any existing Telepresence session
telepresence quit

# Start Telepresence user daemon in Docker
telepresence connect --docker
```

You should see console output similar to:

```bash theme={null}
› telepresence quit
Disconnected

› telepresence connect --docker
Launching Telepresence User Daemon
Connected to context arn:aws:eks:us-east-1:195275640053:cluster/telepresence, namespace default (https://C22C5458C5800FD626C361045762447E.gr7.us-east-1.eks.amazonaws.com)
```

Verify the Telepresence status and confirm the daemon runs in a container:

```bash theme={null}
telepresence status
```

Example (abridged) status output:

```text theme={null}
OSS Daemon in container arn_aws_eks_us-east-1_195275640053_cluster_telepresence-default-cn: Running
Version                : 2.20.0
Status                 : Connected
Kubernetes context     : arn:aws:eks:us-east-1:195275640053:cluster/telepresence
Container network      : container:tp-arn_aws_eks_us-east-1_195275640053_cluster_telepresence-default-cn
Namespace              : default
Intercepts             : 0 total
DNS Local IP           : 127.0.0.11
DNS Remote IP          : 192.168.45.89
```

And confirm with Docker:

```bash theme={null}
docker ps
```

Example:

```text theme={null}
CONTAINER ID   IMAGE                                         COMMAND                  CREATED         STATUS         PORTS
469b3ff7dcdb   ghcr.io/telepresenceio/telepresence:2.20.0   "telepresence connec..." 18 seconds ago  Up 17 seconds   127.0.1:42715->42715/tcp  tp-arn_aws_eks_us-east-1_195275640053_cluster_telepresence-default-cn
```

<Callout icon="lightbulb" color="#1CB2FE">
  Running Telepresence inside Docker avoids changing host networking and needing admin privileges while still enabling Kubernetes service interception and local debugging workflows.
</Callout>

***

## 2) Intercept cluster traffic to a local Docker container

The common workflow is to intercept traffic destined for a Kubernetes Service/Deployment and forward it to a process running locally. With Telepresence you can run that process inside a Docker container.

Example Node.js "auth" service (index.js):

```javascript theme={null}
// index.js (auth service)
const express = require("express");
const app = express();
const port = 8000;

app.get("/", (req, res) => {
  res.json({ message: "this is the auth service running on my machine" });
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});
```

Build an image and create an intercept that runs your image locally with `--docker-run`:

```bash theme={null}
# Build image from current directory
docker build -t telepresence-auth:v2 .

# Create a Telepresence intercept that runs the image in a container.
# `--docker-run` tells Telepresence to run your code inside Docker.
# The `--` separates Telepresence flags from Docker flags/args.
telepresence intercept auth-depl --port 8000 --docker-run -- telepresence-auth:v2
```

When you run an intercept with `--docker-run`, Telepresence starts the specified image locally and attaches the intercept so cluster traffic to the intercepted service is routed to that container.

Confirm the container is running:

```bash theme={null}
docker ps
```

***

<Callout icon="lightbulb" color="#1CB2FE">
  The double dash (`--`) separates flags intended for Telepresence from flags and arguments passed to Docker (for example `-v`, `-e`, or the container's CMD). Everything after `--` is treated as Docker arguments.
</Callout>

***

## 3) Example: Product service — modify code, build, and intercept

Make code changes to the `products` service and run it locally via Telepresence. The snippet below shows an async route that fetches inventory data, merges it into product objects, and returns the combined result. Replace the inventory fetch URL with the appropriate service address in your setup (for example `http://inventory-service:3000`).

```javascript theme={null}
// snippet from products service
app.get("/", async (req, res) => {
  try {
    // fetch inventory data from the inventory service
    const response = await fetch("http://inventory-service:3000/inventory");
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const { data } = await response.json();

    const productsWithInventory = filteredProducts.map((product) => {
      return {
        ...product,
        inventoryCount: data[product.id] || 0,
      };
    });

    res.json({ data: productsWithInventory, message: "running on container on local machine" });
  } catch (e) {
    console.error(e);
    res.status(500).json({ error: e.message });
  }
});
```

Build the Docker image:

```bash theme={null}
docker build -t my-test-image .
```

Intercept the `products-depl` deployment and run your image locally:

```bash theme={null}
telepresence intercept products-depl --port 8000 --docker-run -- my-test-image
```

Sample Telepresence intercept output (abridged):

```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
  Intercepting           : all TCP connections

Example app listening on port 8000
```

Test via the product service external endpoint (replace the example ELB host with your own):

```bash theme={null}
curl a2517fc7ab3ee41999dd7c47eed9f866-376507947.us-east-1.elb.amazonaws.com:3000/?product_ids=1,2,3
```

Example JSON response:

```json theme={null}
{
  "data": [
    { "id": 1, "name": "iphone 14", "price": 900, "category": "electronics", "onSale": false, "inventoryCount": 864 },
    { "id": 2, "name": "Samsung 40in TV", "price": 500, "category": "electronics", "onSale": true, "inventoryCount": 911 },
    { "id": 3, "name": "Apple MacbookPro", "price": 2500, "category": "electronics", "onSale": false, "inventoryCount": 189 }
  ],
  "message": "running on container on local machine"
}
```

***

## 4) Avoid rebuilding images on every change — use bind mounts and hot-reload

Rebuilding images for every code change slows down iteration. Use Docker bind mounts to map your local source directory into the container and override the container command to a development runner (for example `npm run dev` using `nodemon`) so the container picks up file changes instantly.

Example: bind-mount the current directory into `/usr/src/app` in the container and run `npm run dev`:

```bash theme={null}
telepresence intercept products-depl --port 8000 --docker-run -- -v $(pwd):/usr/src/app my-test-image npm run dev
```

Notes:

* `-v $(pwd):/usr/src/app` mounts your local project into the container path expected by your Dockerfile.
* `my-test-image` is the base image used to start the container.
* `npm run dev` (after the image name) becomes the container's command so nodemon will hot-reload on file changes.

Example nodemon container logs:

```text theme={null}
> products@1.0.0 dev
> nodemon index.js

[nodemon] 3.1.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,cjs,json
[nodemon] starting `node index.js`
http://inventory-service:3000/
Example app listening on port 8000
```

When you update local files, nodemon restarts the server inside the container immediately because the source is bind-mounted.

***

## 5) Let Telepresence build the image for you with --docker-build

If you prefer Telepresence to build the image automatically, use `--docker-build` and `--docker-build-opt` to pass build options like `tag=`. Telepresence expects a literal `IMAGE` token at the end (after the final `--`) which it replaces with the built image.

Example:

```bash theme={null}
telepresence intercept products-depl \
  --port 8000 \
  --docker-build products/ \
  --docker-build-opt tag=my-debug-image \
  -- IMAGE
```

Notes:

* `products/` is the path with your Dockerfile.
* `--docker-build-opt tag=my-debug-image` tags the generated image as `my-debug-image`.
* The literal `IMAGE` token is required; Telepresence uses it to hook the built image into the intercept.

Verify the container and the built image:

```bash theme={null}
docker ps
docker image ls | grep my-debug-image
```

Example snippets:

```text theme={null}
docker ps
CONTAINER ID   IMAGE                      NAMES                               COMMAND                  CREATED         STATUS         PORTS
2c1f9448a12f   75d1f2ff141f               intercept-products-depl-8000        "docker-entrypoint.s..."  8 seconds ago   Up 8 seconds

docker image ls
my-debug-image   latest   75d1f2ff141f   3 minutes ago   ...
```

You can still use bind mounts (`-v`) and override commands with `--docker-build` to enable hot-reload workflows.

***

## Quick reference: common Telepresence + Docker commands

| Command | Purpose | Example |
| -: | - | - |
| Connect Telepresence inside Docker | Run user daemon inside a container | `telepresence connect --docker` |
| Show Telepresence status | Verify daemon & intercepts | `telepresence status` |
| Run local image as intercept target | Run your image locally and attach intercept | `telepresence intercept auth-depl --port 8000 --docker-run -- telepresence-auth:v2` |
| Use bind mount & hot-reload | Mount source and run dev command in container | `telepresence intercept products-depl --port 8000 --docker-run -- -v $(pwd):/usr/src/app my-test-image npm run dev` |
| Let Telepresence build image | Build image from source and run it | `telepresence intercept products-depl --port 8000 --docker-build products/ --docker-build-opt tag=my-debug-image -- IMAGE` |

***

## Summary

* Use `telepresence connect --docker` to run the Telepresence user daemon inside a Docker container.
* Use `telepresence intercept ... --docker-run -- <image> [docker-args] [cmd]` to run a local container as the intercept target.
* Use Docker bind mounts (`-v`) and override the container command (e.g., `npm run dev`) to enable hot-reload without rebuilding images.
* Use `--docker-build` and `--docker-build-opt` to have Telepresence build the image for you.
* The `--` separator is critical: flags before it apply to Telepresence; everything after it is passed to Docker.

Links and further reading:

* [Telepresence](https://www.telepresence.io/)
* [Docker](https://www.docker.com/)
* [Kubernetes Basics](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/)
* [nodemon](https://nodemon.io/)
* [AWS Elastic Load Balancing (ELB) docs](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/what-is-load-balancing.html)

<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/409f313b-7c84-4815-b0ba-6973f5a1975f" />
</CardGroup>


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