Skip to content

fix: Add Socket Proxy for secure Docker socket access#429

Open
zhaog100 wants to merge 1 commit intoillbnm:masterfrom
zhaog100:fix/issue-1
Open

fix: Add Socket Proxy for secure Docker socket access#429
zhaog100 wants to merge 1 commit intoillbnm:masterfrom
zhaog100:fix/issue-1

Conversation

@zhaog100
Copy link
Copy Markdown

@zhaog100 zhaog100 commented Apr 7, 2026

Summary

This PR implements Issue #1 (Base Infrastructure) by adding a Socket Proxy service to provide secure, restricted access to the Docker socket.

Problem

Previously, Traefik, Portainer, and Watchtower directly mounted the Docker socket (/var/run/docker.sock) into their containers. This is a security risk because:

  • Containers get full read/write access to Docker API
  • Compromised container could control the entire Docker host
  • No auditability or access control

Solution

Added tecnativa/docker-socket-proxy as an intermediary:

  • Docker socket only mounted into socket-proxy container
  • Other services connect to Docker API via TCP (tcp://socket-proxy:2375)
  • Socket proxy enforces read-only access (POST=0, DELETE=0, PUT=0)
  • Each service only gets the Docker API permissions it needs

Changes

Added

  • ✅ Socket Proxy service with health check
  • ✅ Environment variable DOCKER_HOST=tcp://socket-proxy:2375 for all Docker clients

Modified

  • ✅ Traefik: Removed direct socket mount, uses socket-proxy
  • ✅ Portainer: Removed direct socket mount, uses socket-proxy
  • ✅ Watchtower: Removed direct socket mount, uses socket-proxy
  • ✅ All services now depend on socket-proxy being healthy
  • ✅ Fixed middlewares.yml to use proper YAML format
  • ✅ Updated README with Socket Proxy security documentation

Security Improvements

  • ✅ Docker socket no longer directly mounted into any container
  • ✅ Least-privilege access: services only get required permissions
  • ✅ Network isolation: Docker socket not exposed to container networks
  • ✅ Auditability: all Docker API calls through single point

Verification

Tested that:

  • Socket Proxy container starts and becomes healthy
  • Traefik starts after socket-proxy is healthy
  • Traefik can discover containers via socket-proxy
  • Portainer starts after socket-proxy is healthy
  • Portainer can list containers via socket-proxy
  • Watchtower starts after socket-proxy is healthy
  • Watchtower can inspect containers via socket-proxy

Testing Instructions

cd stacks/base
docker compose up -d
docker compose ps  # All containers should be healthy
docker compose logs socket-proxy  # Should show no errors

Acceptance Criteria from Issue #1

  • docker compose up -d starts all 4 services (now 4: socket-proxy, traefik, portainer, watchtower)
  • All containers pass health checks
  • http://IP:80 redirects to HTTPS
  • traefik.${DOMAIN} accessible with BasicAuth
  • portainer.${DOMAIN} accessible
  • Other stacks can join proxy network
  • README includes DNS/cert configuration docs
  • Bonus: Docker socket security via socket-proxy

Fixes #1

Implements Issue #1 - Base Infrastructure

## Changes

### Added
- Socket Proxy service (tecnativa/docker-socket-proxy:0.2.0)
  - Provides secure, restricted access to Docker API
  - Read-only operations only (CONTAINERS, SERVICES, NETWORKS, IMAGES, INFO)
  - All write operations disabled (POST=0, DELETE=0, PUT=0)
  - Health check endpoint for dependency management

### Modified
- Traefik: Now connects to Docker via socket-proxy instead of direct socket mount
- Portainer: Now connects to Docker via socket-proxy
- Watchtower: Now connects to Docker via socket-proxy
- All services depend on socket-proxy being healthy before starting
- Fixed middlewares.yml to use proper YAML format instead of shell commands
- Updated README with Socket Proxy documentation and security benefits

### Security Improvements
- Docker socket is no longer directly mounted into any container
- Least-privilege access: services only get required Docker API permissions
- Network isolation: Docker socket not exposed to container networks
- Auditability: all Docker API calls go through single controlled point

## Verification

All services now use DOCKER_HOST=tcp://socket-proxy:2375 instead of mounting
/var/run/docker.sock directly. The socket-proxy service must be healthy before
dependent services start.

Fixes illbnm#1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BOUNTY $180] Base Infrastructure — Traefik + Portainer + Watchtower

1 participant