---
title: Socat Proxy
description: Use socat to proxy the Docker socket through Docker Socket Proxy, allowing Beszel to collect container stats without exposing the full Docker socket.
---


:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
This project addresses a common use case:

- I have [Beszel](https://beszel.dev/), a monitoring container running in host mode, which requires access to the Docker socket to collect container statistics.
- To avoid exposing the Docker socket fully to Beszel, I use [Docker Socket Proxy](https://github.com/Tecnativa/docker-socket-proxy), a container that sits between the Docker socket and the consuming container. It filters requests by setting appropriate permissions, preventing full exposure of the Docker socket.

The problem arises when **Beszel** runs in host mode. In that case, it must connect directly to **Docker Socket Proxy** on a host port, meaning the proxy’s port is exposed. This allows any container or application on the host to access it and use the Docker socket.

This is where [Socat Proxy](https://git.djeex.fr/Djeex/socat-proxy) comes in. It is a container that:

- Creates a UNIX socket
- Listens on this socket
- Forwards requests to Docker Socket Proxy and back
- Replaces the real Docker socket by exposing the proxy socket in the target container via a bind mount (in this case, Beszel)

With this setup, Docker Socket Proxy communicates with Socat Proxy in their isolated bridge network, while the UNIX socket bind-mounted on the host has restricted permissions, preventing access from other containers or applications.

In short:

![](/img/nonsense/socat-proxy.svg)

For example, with Beszel, the configuration would look like this:

```yaml [compose.yaml]
---
services:
  socat-proxy:
    image: git.djeex.fr/djeex/socat-proxy:latest
    container_name: socat-proxy-beszel
    environment:
      - TARGET_HOST=${TARGET_HOST}
      - TARGET_PORT=${TARGET_PORT}
      - UNIX_SOCKET_PATH=${UNIX_SOCKET_PATH}
      - HOST_SOCKET_PATH=${HOST_SOCKET_PATH}
      - UNIX_SOCKET_NAME=${UNIX_SOCKET_NAME}
    volumes:
      - ${HOST_SOCKET_PATH}:${UNIX_SOCKET_PATH}
    restart: unless-stopped
    depends_on:
      - ${TARGET_HOST}

  socket-proxy:
    image: lscr.io/linuxserver/socket-proxy:latest
    container_name: ${TARGET_HOST}
    security_opt:
      - no-new-privileges:true
    environment:
      - CONTAINERS=1
      - INFO=1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    restart: unless-stopped
    read_only: true
    tmpfs:
      - /run

  beszel-agent:
    image: henrygd/beszel-agent:latest
    container_name: beszel-agent
    restart: unless-stopped
    network_mode: host
    security_opt:
      - no-new-privileges:true
    volumes:
      - ${HOST_SOCKET_PATH}/${UNIX_SOCKET_NAME}:/var/run/docker.sock:ro
    environment:
      - #... your Beszel environment variables
    depends_on:
      - socat-proxy
```

More information is available on the repository:

::card{title="🐋 **Socat Proxy**" to="https://git.djeex.fr/Djeex/socat-proxy" target="_blank"}
A lightweight bind-mount socket proxy
::
