Socat Proxy


This project addresses a common use case:

  • I have Beszel, 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, 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 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:

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

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: