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:
@@ -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:
|
||||
|
||||
@@ -43,10 +43,41 @@ services:
|
||||
- .env
|
||||
environment:
|
||||
- DOZZLE_HOSTNAME=${DOMAIN}
|
||||
- DOCKER_HOST=tcp://docker-socket-proxy:2375
|
||||
networks:
|
||||
- dozzle-internal
|
||||
depends_on:
|
||||
- docker-socket-proxy
|
||||
|
||||
docker-socket-proxy:
|
||||
image: lscr.io/linuxserver/socket-proxy:latest
|
||||
container_name: docker-socket-proxy-dozzle
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
networks:
|
||||
- dozzle-internal
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
- CONTAINERS=1
|
||||
- IMAGES=1
|
||||
- INFO=1
|
||||
- EVENTS=1
|
||||
- ALLOW_LOGS=1
|
||||
restart: unless-stopped
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /run
|
||||
|
||||
networks:
|
||||
dozzle-internal:
|
||||
name: dozzle-internal
|
||||
```
|
||||
|
||||
::note
|
||||
Dozzle only ever reads container logs, so this config sits **Docker Socket Proxy** in front of the Docker API instead of mounting `/var/run/docker.sock` directly, keeping `POST` disabled entirely: Dozzle can list containers and stream their logs, and nothing else.
|
||||
::
|
||||
|
||||
::tip{icon=""}
|
||||
✨ __Tip:__ Add the watchtower label to each container to automate updates
|
||||
|
||||
|
||||
@@ -53,13 +53,35 @@ services:
|
||||
network_mode: host
|
||||
volumes:
|
||||
- ./socket:/beszel_socket
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
LISTEN: /beszel_socket/beszel.sock
|
||||
DOCKER_HOST: tcp://127.0.0.1:2375
|
||||
# Do not remove quotes around the key
|
||||
KEY: ${KEY}
|
||||
depends_on:
|
||||
- docker-socket-proxy
|
||||
|
||||
docker-socket-proxy:
|
||||
image: lscr.io/linuxserver/socket-proxy:latest
|
||||
container_name: docker-socket-proxy-beszel
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
ports:
|
||||
- 127.0.0.1:2375:2375
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
- CONTAINERS=1
|
||||
restart: unless-stopped
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /run
|
||||
```
|
||||
|
||||
::note
|
||||
`beszel-agent` runs with `network_mode: host`, so it can't join a dedicated internal network like the other proxied stacks on this site; instead, **Docker Socket Proxy** publishes its API on `127.0.0.1` only, reachable from the agent via the host's own loopback interface, with just `CONTAINERS=1` enabled since the agent only needs to read container stats.
|
||||
::
|
||||
|
||||
::tip{icon=""}
|
||||
✨ __Tip:__ Add the Watchtower label to each container to automate updates.
|
||||
|
||||
@@ -122,11 +144,28 @@ services:
|
||||
container_name: beszel-agent
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
LISTEN: ${PORT}
|
||||
KEY: ${KEY}
|
||||
DOCKER_HOST: tcp://127.0.0.1:2375
|
||||
depends_on:
|
||||
- docker-socket-proxy
|
||||
|
||||
docker-socket-proxy:
|
||||
image: lscr.io/linuxserver/socket-proxy:latest
|
||||
container_name: docker-socket-proxy-beszel
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
ports:
|
||||
- 127.0.0.1:2375:2375
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
- CONTAINERS=1
|
||||
restart: unless-stopped
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /run
|
||||
```
|
||||
|
||||
And in `.env`:
|
||||
|
||||
@@ -19,7 +19,7 @@ Authentik also supports multi-factor authentication, including TOTP (a code gene
|
||||
|
||||
It's a great alternative to VPNs for securely exposing services, especially ones that lack MFA or login protection (e.g., the SWAG dashboard).
|
||||
|
||||
Authentik has [extensive documentation](https://docs.goauthentik.io/docs/installation/docker-compose) and [great tutorials from Cooptonian](https://www.youtube.com/@cooptonian). Here, we’ll cover the basics using Dockge as an example.
|
||||
Authentik has [extensive documentation](https://docs.goauthentik.io/install-config/install/docker-compose) and [great tutorials from Cooptonian](https://www.youtube.com/@cooptonian). Here, we’ll cover the basics using Dockge as an example.
|
||||
|
||||
There are two main modes you should know:
|
||||
|
||||
@@ -156,24 +156,54 @@ services:
|
||||
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
|
||||
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
||||
# `user: root` and the docker socket volume are optional.
|
||||
# See more for the docker socket integration here:
|
||||
# `user: root` and the Docker integration below are optional, only needed if you
|
||||
# want Authentik to auto-manage embedded outposts on this host. See:
|
||||
# https://goauthentik.io/docs/outposts/integrations/docker
|
||||
# Removing `user: root` also prevents the worker from fixing the permissions
|
||||
# on the mounted folders, so when removing this make sure the folders have the correct UID/GID
|
||||
# (1000:1000 by default)
|
||||
user: root
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./media:/media
|
||||
- ./certs:/certs
|
||||
- ./custom-templates:/templates
|
||||
- ./ssh:/authentik/.ssh
|
||||
networks:
|
||||
- default
|
||||
- authentik-internal
|
||||
env_file:
|
||||
- .env
|
||||
depends_on:
|
||||
- postgresql
|
||||
- redis
|
||||
- docker-socket-proxy
|
||||
|
||||
docker-socket-proxy:
|
||||
image: lscr.io/linuxserver/socket-proxy:latest
|
||||
container_name: docker-socket-proxy-authentik
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
networks:
|
||||
- authentik-internal
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
- CONTAINERS=1
|
||||
- IMAGES=1
|
||||
- NETWORKS=1
|
||||
- INFO=1
|
||||
- POST=1
|
||||
- ALLOW_START=1
|
||||
- ALLOW_STOP=1
|
||||
- ALLOW_RESTARTS=1
|
||||
restart: unless-stopped
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /run
|
||||
|
||||
networks:
|
||||
authentik-internal:
|
||||
name: authentik-internal
|
||||
|
||||
volumes:
|
||||
database:
|
||||
@@ -182,6 +212,10 @@ volumes:
|
||||
driver: local
|
||||
```
|
||||
|
||||
::note
|
||||
This adds **Docker Socket Proxy** so the optional Docker integration never needs `/var/run/docker.sock` mounted directly into the worker. If you enable it, set the connection's Docker URL in the admin UI to `http://docker-socket-proxy:2375` instead of the local socket path, as [Authentik's own docs recommend](https://goauthentik.io/docs/outposts/integrations/docker) for socket-proxy setups.
|
||||
::
|
||||
|
||||
### Begin the initial setup
|
||||
|
||||
In the `.env` file, the `PG_PASS` and `AUTHENTIK_SECRET_KEY` variables are already set.
|
||||
@@ -322,7 +356,7 @@ Go to _Settings_, click the _MFA_ section, then _Register_. Choose a method like
|
||||
You’ll now be prompted to enter a one-time code at every login.
|
||||
|
||||
## Protecting a Native App
|
||||
Authentik is natively compatible with several applications. You can find the list and [support here](https://docs.goauthentik.io/integrations/services/).
|
||||
Authentik is natively compatible with several applications. You can find the list and [support here](https://integrations.goauthentik.io/).
|
||||
|
||||
## Protecting an App via Reverse Proxy
|
||||
SWAG lets you insert Authentik’s login page between a request and access to your service. To do this:
|
||||
@@ -436,9 +470,9 @@ We assume you’ve already installed [Docker](/serveex/core/docker) and [SWAG](/
|
||||
|
||||
### Create the stack folder
|
||||
|
||||
On your remote machine, use [Dockge](/serveex/core/docker/#installer-dockge-pour-gérer-et-déployer-les-conteneurs) to create a stack named `authentik-outpost`.
|
||||
On your remote machine, use [Dockge](/serveex/core/docker/#install-dockge-to-manage-and-deploy-containers) to create a stack named `authentik-outpost`.
|
||||
|
||||
If you haven’t installed [Dockge](/serveex/core/docker/#installer-dockge-pour-gérer-et-déployer-les-conteneurs), create a folder `/srv/docker/authentik-outpost`, or directly via command line:
|
||||
If you haven’t installed [Dockge](/serveex/core/docker/#install-dockge-to-manage-and-deploy-containers), create a folder `/srv/docker/authentik-outpost`, or directly via command line:
|
||||
|
||||
```bash [Terminal]
|
||||
sudo mkdir -P /srv/docker/authentik-outpost
|
||||
@@ -515,7 +549,7 @@ We assume the Dockge network name is `authentik-outpost_default`.
|
||||
|
||||
### Restart SWAG
|
||||
|
||||
If using [Dockge](/serveex/core/docker/#installer-dockge-pour-gérer-et-déployer-les-conteneurs), restart SWAG.
|
||||
If using [Dockge](/serveex/core/docker/#install-dockge-to-manage-and-deploy-containers), restart SWAG.
|
||||
|
||||
Otherwise, via terminal:
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ description: Install Arcane, a modern Docker and Compose management web UI, as a
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
|
||||
::note{to="/serveex/core/docker#installer-dockge-pour-gérer-et-déployer-les-conteneurs"}
|
||||
::note{to="/serveex/core/docker#install-dockge-to-manage-and-deploy-containers"}
|
||||
|
||||
This is an advanced alternative to **Dockge**: it can manage several remote Docker hosts from a single instance, and supports OIDC login natively instead of relying on a separate forward-auth proxy.
|
||||
::
|
||||
@@ -72,7 +72,7 @@ services:
|
||||
|
||||
docker-socket-proxy:
|
||||
image: lscr.io/linuxserver/socket-proxy:latest
|
||||
container_name: arcane-docker-proxy
|
||||
container_name: docker-socket-proxy-arcane
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
networks:
|
||||
|
||||
Reference in New Issue
Block a user