# Tunnels with Docker

> Connect a running Docker container to the Apoxy edge using a tunnel.

This guide runs an Apache web server in Docker and exposes it through an Apoxy tunnel. The same pattern works for any containerized service you already have running.

## Prerequisites

- The Apoxy CLI installed and authenticated (`apoxy auth`).
- Docker installed and running.

## Start an Apache container

Run the official Apache image, publishing port 8080 on your host:

```bash
docker run -d --name my-apache -p 8080:80 httpd:alpine
```

Confirm it's working:

```bash
curl http://localhost:8080
```

You should see "It works!".

## Start the tunnel

Open a new terminal and start a tunnel:

```bash
apoxy tunnel run my-docker-tunnel --auto
```

The tunnel connects your machine to the Apoxy edge. Because the Apache container publishes port 8080 on your host, the tunnel can reach it at `localhost:8080` — no special Docker networking required.

## Create a Backend and route

When the tunnel connects, Apoxy's backplane makes it DNS-resolvable at `my-docker-tunnel.tun.apoxy.net`. This FQDN is internal to Apoxy's routing layer — it isn't reachable from the public internet. Create a Backend that points to it, then route public traffic through that Backend via the default Gateway.

Create a file called `docker-route.yaml`:

```yaml
apiVersion: core.apoxy.dev/v1alpha2
kind: Backend
metadata:
  name: docker-tunnel-backend
spec:
  endpoints:
  - fqdn: my-docker-tunnel.tun.apoxy.net

---
apiVersion: gateway.apoxy.dev/v1
kind: HTTPRoute
metadata:
  name: docker-route
spec:
  parentRefs:
  - name: default
  hostnames:
  - apache.your-org.apoxy.app
  rules:
  - backendRefs:
    - kind: Backend
      name: docker-tunnel-backend
      port: 8080
```

Replace `apache.your-org.apoxy.app` with a subdomain under your Apoxy organization.

Apply it:

```bash
apoxy apply -f docker-route.yaml
```

## Verify

```bash
curl http://apache.your-org.apoxy.app/
```

You should see "It works!" — the same response as hitting the container locally, now served through the Apoxy edge.

## How it works

The traffic path is:

1. Request hits `apache.your-org.apoxy.app` at the Apoxy edge.
2. The HTTPRoute matches on the default Gateway and forwards to the Backend, which resolves `my-docker-tunnel.tun.apoxy.net` to the tunnel's overlay address.
3. The edge sends the request down the QUIC tunnel to your machine.
4. Your machine forwards to `localhost:8080`, which Docker maps to the Apache container's port 80.

This works because Docker's `-p 8080:80` flag binds the container's port to your host. The tunnel doesn't need to know about Docker — it just reaches `localhost:8080`.

## Using Docker networks directly

If you don't want to publish ports on the host, you can run the tunnel client inside the same Docker network as your service:

```bash
docker network create apoxy-net

docker run -d --name my-apache --network apoxy-net httpd:alpine

docker run -it --rm --network apoxy-net \
  -v $HOME/.config/apoxy:/root/.config/apoxy \
  apoxy-dev/apoxy:latest \
  tunnel run my-docker-tunnel --auto
```

In this case, update the Backend's endpoint FQDN to reach the container directly by its Docker DNS name, and set the backendRef port to the container's native port (80).

## Clean up

```bash
docker stop my-apache && docker rm my-apache
apoxy delete -f docker-route.yaml
```
