# Docker

> Capture a Docker Compose project's containers with a generated override: proxy variables, the certificate mounted, and requests labelled by service.

Source: https://docs.subcloak.com/cloak-proxy/devices/docker/

Added in Cloak Proxy 0.4.0.

Containers don't use the Mac's proxy or keychain. Cloak Proxy writes a Compose override that points each service at Cloak Proxy on your Mac, mounts its certificate into the container, and sets the variables that Node.js, Python, OpenSSL, curl, git, Deno and the AWS SDKs read the certificate from. Your own compose file isn't changed, and each service's requests show under the service's name in the **Apps** sidebar.

*[Screenshot: The Docker page of Device & Runtime Setup with the shopapp project chosen, its services web, api and worker selected and db not, the generated compose.override.yaml, and a Write Override button. A Compose project with three of its four services captured.]*

## Capture a Compose project

1. Open **Proxy › Device & Runtime Setup…** and choose **Docker**.

2. Click **Choose Project…** and pick the folder with your `compose.yaml` (or `compose.yml`, `docker-compose.yaml`, `docker-compose.yml`).

3. Under **Services**, leave on the services whose HTTP traffic you want. Databases, caches and queues usually don't speak HTTP: turn them off.

4. Click **Write Override**.

5. Recreate the containers so they pick up the new settings:

   ```bash title="Terminal"
   docker compose up -d
   ```

6. Add the hosts your services call to **SSL Proxying** to read their HTTPS.

Requests show in the traffic list as soon as the services make them.

> **Tip:**
> The override is a normal Compose file next to yours: `docker compose config` shows the merged result. Commit it to share the setup, or add it to `.gitignore` if it's only for you; it contains your certificate's path on this Mac.

### Where the override goes

| Your project has | Cloak Proxy writes | Start with |
|---|---|---|
| No override file | `compose.override.yaml` (or `docker-compose.override.yml`, matching your file's name) | `docker compose up -d`. Compose reads the override on its own. |
| Its own override file | `compose.cloak-proxy.yaml`, next to it | The command on the page, which passes all three files with `-f` |

Cloak Proxy only replaces files it wrote (they start with `# Generated by Cloak Proxy`).

## What the override sets

For each service you chose:

| Setting | Value | For |
|---|---|---|
| `HTTP_PROXY`, `HTTPS_PROXY`, `http_proxy`, `https_proxy` | `http://docker-<service>:<project>@host.docker.internal:9090` | Most HTTP libraries |
| `NO_PROXY`, `no_proxy` | `localhost`, `127.0.0.1`, `::1` and every service and container name | Calls between services go straight to each other |
| `NODE_USE_ENV_PROXY` | `1` | Node.js 24 and later |
| `NODE_EXTRA_CA_CERTS` | `/usr/local/share/ca-certificates/cloak-proxy-ca.crt` | Node.js |
| `SSL_CERT_FILE`, `REQUESTS_CA_BUNDLE`, `CURL_CA_BUNDLE`, `GIT_SSL_CAINFO`, `AWS_CA_BUNDLE` | `/etc/ssl/certs/cloak-proxy-bundle.pem` | OpenSSL, Python, Ruby, curl, git and the AWS SDKs |
| `DENO_CERT` | the certificate | Deno |
| A read-only bind mount | the certificate at `/usr/local/share/ca-certificates/cloak-proxy-ca.crt` | Everything above, and `update-ca-certificates` |
| A read-only bind mount | the bundle at `/etc/ssl/certs/cloak-proxy-bundle.pem` | The system's root certificates plus Cloak Proxy's, so HTTPS that isn't decrypted keeps working |
| `extra_hosts` | `host.docker.internal:host-gateway` | Lets Linux engines find the host |
| A label | `com.subcloak.cloakproxy.capture` | Shows which containers are captured (`docker ps --filter label=com.subcloak.cloakproxy.capture`) |

Compose merges these into each service: your own variables, volumes and hosts stay.

## Requests by service

Docker Desktop forwards every container's connection to your Mac from the same address, so the proxy can't tell containers apart by address. Instead, each service's proxy address carries a tag: the user name `docker-<service>` with the project as the password. HTTP clients send it to the proxy with every request; Cloak Proxy reads it, names the request after the service, and never forwards it.

In the **Apps** sidebar each service shows with a box icon, such as **api** (Docker · shopapp). Filter, mute or decrypt by service name like any other app. The page shows **Traffic arriving** next to services whose requests have reached Cloak Proxy.

On Linux engines where a container's own address reaches the proxy, Cloak Proxy also matches addresses from `docker inspect`.

## A single container

The page shows the flags for `docker run`:

```bash title="Terminal"
docker run -e HTTP_PROXY=http://docker-app:cloak@host.docker.internal:9090 \
  -e HTTPS_PROXY=http://docker-app:cloak@host.docker.internal:9090 \
  -e NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/cloak-proxy-ca.crt \
  -v "$HOME/Library/Application Support/CloakProxy/cloak-proxy-ca.pem:/usr/local/share/ca-certificates/cloak-proxy-ca.crt:ro" \
  --add-host=host.docker.internal:host-gateway IMAGE
```

The full set, with every variable, is on the page and from `cloakctl capture-config docker-run`. For an env file (`docker run --env-file` or a service's `env_file:`), use `cloakctl capture-config env-file`.

## Docker engines

| Engine | Works as is? |
|---|---|
| Docker Desktop | Yes. `host.docker.internal` reaches Cloak Proxy on the Mac. |
| OrbStack | Yes. |
| Colima, Rancher Desktop, Podman | Containers connect over the network: turn on **Settings › Network › Allow other devices to connect**. |
| Docker on a Linux server | Run [`cloakctl run`](https://docs.subcloak.com/cloak-proxy/automation/headless-and-ci/) on that machine and pass `proxy_host` (MCP) or `--proxy-host` (cloakctl) |

## Stop capturing

Click **Stop Capturing** on the Docker page, or delete the override file, then run `docker compose up -d` again. Only the file Cloak Proxy wrote is removed.

## From MCP and the command line

[`capture_config`](https://docs.subcloak.com/cloak-proxy/automation/mcp-tools-reference/#capture_config) with `kind: "docker_compose"` and `project` previews the override; add `write: true` to save it, and `services` to pick services. `kind: "docker_run"` and `"env_file"` return the single-container versions. `capture_setup` with `target: "docker"` and `apply: "compose-override"` writes it as a setup step.

```bash title="Terminal"
cloakctl capture-config docker-compose --project . --service api --service web --write
cloakctl capture-config docker-run --service worker
cloakctl setup docker --apply compose-override --project .
```

## Limits

- Programs that ignore the proxy variables (some Go programs built without `ProxyFromEnvironment`, Java, raw sockets) aren't captured. Java needs [its own settings](https://docs.subcloak.com/cloak-proxy/devices/java-firefox-docker-flutter-electron/).
- Programs that read only the system's certificate store, and not the variables above, need `update-ca-certificates` run in the container (Debian, Ubuntu and Alpine images), which the mount makes possible.
- Clients that don't send proxy credentials still go through the proxy, but show under Docker's own name instead of the service's.
- Calls between services aren't captured: they stay on the Compose network, which the proxy on your Mac isn't part of.

## Related

  - [Terminal and runtimes](https://docs.subcloak.com/cloak-proxy/devices/terminal-and-runtimes/): The same variables for a shell on your Mac.
  - [Headless and CI](https://docs.subcloak.com/cloak-proxy/automation/headless-and-ci/): Run the proxy without the app, on a server or in CI.
  - [Capturing browser](https://docs.subcloak.com/cloak-proxy/devices/capturing-browser/): A browser that's already proxied.
  - [SSL Proxying](https://docs.subcloak.com/cloak-proxy/capture/ssl-proxying/): Choose which hosts to decrypt.
