Put Docker Socket Proxy in front of every container that needs the Docker API instead of mounting docker.sock directly

This commit is contained in:
Djeex
2026-09-07 13:42:40 +02:00
parent 5548287c65
commit 81c54c9afc
10 changed files with 401 additions and 46 deletions
+77 -4
View File
@@ -94,15 +94,52 @@ services:
container_name: dockge
ports:
- 3555:5001 # LAN-accessible port will be 3555
environment:
- DOCKER_HOST=tcp://docker-socket-proxy:2375
- DOCKGE_STACKS_DIR=/srv/docker
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /srv/docker/dockge/data:/app/data
- /srv/docker:/srv/docker
networks:
- dockge-internal
depends_on:
- docker-socket-proxy
docker-socket-proxy:
image: lscr.io/linuxserver/socket-proxy:latest
container_name: docker-socket-proxy-dockge
security_opt:
- no-new-privileges:true
networks:
- dockge-internal
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- DOCKGE_STACKS_DIR=/srv/docker
- CONTAINERS=1
- IMAGES=1
- NETWORKS=1
- VOLUMES=1
- EXEC=1
- INFO=1
- SYSTEM=1
- POST=1
- ALLOW_START=1
- ALLOW_STOP=1
- ALLOW_RESTARTS=1
restart: unless-stopped
read_only: true
tmpfs:
- /run
networks:
dockge-internal:
name: dockge-internal
```
::warning
Dockge needs access to the Docker API to manage every other stack on this server, which is effectively root access to your host. Instead of mounting `/var/run/docker.sock` directly, this config sits **Docker Socket Proxy** in front of it, only allowing the specific permissions Dockge needs (containers, images, networks, volumes, exec, lifecycle actions), on their own internal network. Dockge has no built-in login by default, so never expose port `3555` beyond your LAN without putting it behind [TinyAuth](/serveex/security/tinyauth) or [Authentik](/serveex/advanced/authentik) first.
::
Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.
#### Launch the container
@@ -149,12 +186,44 @@ services:
- WATCHTOWER_LABEL_ENABLE=true
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_REMOVE_VOLUMES=true
- DOCKER_HOST=tcp://docker-socket-proxy:2375
# Discord notifications - uncomment if used
#- WATCHTOWER_NOTIFICATIONS=slack
#- WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=Watchtower
#- WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL=${WH_URL}
networks:
- watchtower-internal
depends_on:
- docker-socket-proxy
docker-socket-proxy:
image: lscr.io/linuxserver/socket-proxy:latest
container_name: docker-socket-proxy-watchtower
security_opt:
- no-new-privileges:true
networks:
- watchtower-internal
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
- IMAGES=1
- NETWORKS=1
- VOLUMES=1
- INFO=1
- SYSTEM=1
- POST=1
- ALLOW_START=1
- ALLOW_STOP=1
- ALLOW_RESTARTS=1
restart: unless-stopped
read_only: true
tmpfs:
- /run
networks:
watchtower-internal:
name: watchtower-internal
```
::warning
@@ -162,6 +231,10 @@ services:
`WATCHTOWER_REMOVE_VOLUMES=true` deletes a container's anonymous volumes as soon as it's updated. Combined with a `latest` tag, an automatic update can silently wipe data for any app that still stores something in an anonymous (unnamed) volume instead of a bind mount.
::
::note
This config sits **Docker Socket Proxy** in front of the Docker API instead of mounting `/var/run/docker.sock` directly, so Watchtower only gets the permissions it actually needs (list/pull images, recreate containers) rather than full root-equivalent access to the host.
::
#### Set your environment variables
Fill in the `.env` section in Dockge with the following: