mirror of
https://github.com/linuxserver/docker-modmanager.git
synced 2026-02-20 08:34:32 +08:00
Support multi-host operation
This commit is contained in:
parent
4697a93f89
commit
7c0ba55c36
40
README.md
40
README.md
@ -62,6 +62,43 @@ If a mod requires additional packages to be installed, each container will still
|
||||
|
||||
Note that the Modmanager container itself does not support applying mods *or* custom files/services.
|
||||
|
||||
### Multiple Hosts
|
||||
|
||||
>[!WARNING]
|
||||
>Make sure you fully understand what you're doing before you try and set this up as there are lots of ways it can go wrong.
|
||||
|
||||
Modmanager can query & download mods for remote hosts, as well as the one on which it is installed. At a very basic level if you're just using the DOCKER_MODS env and not the docker integration, simply mount the `/modcache` folder on your remote host(s), ensuring it is writeable by all participating containers.
|
||||
|
||||
If you are using the docker integration, our only supported means for connecting to remote hosts is [our socket proxy container](). Run an instance on each remote host:
|
||||
|
||||
>[!WARNING]
|
||||
>DO NOT expose a socket proxy to your LAN that allows any write operations (`POST=1`, `ALLOW_RESTART=1`, etc) or that exposes any more information than is absolutely necessary. NEVER expose a socket proxy to your WAN.
|
||||
|
||||
```yml
|
||||
modmanager-dockerproxy:
|
||||
image: lscr.io/linuxserver/socket-proxy:latest
|
||||
container_name: modmanager-dockerproxy
|
||||
environment:
|
||||
- CONTAINERS=1
|
||||
- POST=0
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
tmpfs:
|
||||
- /run:exec
|
||||
ports:
|
||||
- 2375:2375
|
||||
restart: unless-stopped
|
||||
read_only: true
|
||||
```
|
||||
|
||||
And then add it to the `DOCKER_MODS_EXTRA_HOSTS` env using the full protocol and port, e.g.
|
||||
|
||||
```yaml
|
||||
- DOCKER_MODS_EXTRA_HOSTS=tcp://host1.example.com:2375|tcp://host2.example.com:2375|tcp://192.168.0.5:2375
|
||||
```
|
||||
|
||||
As above you will need to mount the `/modcache` folder on your remote host(s), ensuring it is writeable by all participating containers.
|
||||
|
||||
### Security considerations
|
||||
|
||||
Mapping `docker.sock` is a potential security liability because docker has root access on the host and any process that has full access to `docker.sock` would also have root access on the host. Docker api has no built-in way to set limitations on access, however, you can use a proxy for the `docker.sock` via a solution like [our docker socket proxy](https://github.com/linuxserver/docker-socket-proxy), which adds the ability to limit access. Then you would just set `DOCKER_HOST=` environment variable to point to the proxy address.
|
||||
@ -84,6 +121,7 @@ services:
|
||||
environment:
|
||||
- DOCKER_MODS= `#optional`
|
||||
- DOCKER_HOST= `#optional`
|
||||
- DOCKER_MODS_EXTRA_HOSTS= `#optional`
|
||||
volumes:
|
||||
- /path/to/modcache:/modcache
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro `#optional`
|
||||
@ -97,6 +135,7 @@ docker run -d \
|
||||
--name=modmanager \
|
||||
-e DOCKER_MODS= `#optional` \
|
||||
-e DOCKER_HOST= `#optional` \
|
||||
-e DOCKER_MODS_EXTRA_HOSTS= `#optional` \
|
||||
-v /path/to/modcache:/modcache \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock:ro `#optional` \
|
||||
--restart unless-stopped \
|
||||
@ -111,6 +150,7 @@ Containers are configured using parameters passed at runtime (such as those abov
|
||||
| :----: | --- |
|
||||
| `-e DOCKER_MODS=` | Pipe-delimited (`\|`) list of mods to download |
|
||||
| `-e DOCKER_HOST=` | Specify the docker endpoint to use if not using the docker.sock |
|
||||
| `-e DOCKER_MODS_EXTRA_HOSTS=` | Pipe-delimited (`\|`) list of additional hosts to query & download mods for. See app setup section for details. |
|
||||
| `-v /modcache` | Modmanager mod storage. |
|
||||
| `-v /var/run/docker.sock:ro` | Mount the host docker socket into the container. |
|
||||
|
||||
|
||||
@ -66,6 +66,43 @@ full_custom_readme: |
|
||||
|
||||
Note that the Modmanager container itself does not support applying mods *or* custom files/services.
|
||||
|
||||
### Multiple Hosts
|
||||
|
||||
>[!WARNING]
|
||||
>Make sure you fully understand what you're doing before you try and set this up as there are lots of ways it can go wrong.
|
||||
|
||||
Modmanager can query & download mods for remote hosts, as well as the one on which it is installed. At a very basic level if you're just using the DOCKER_MODS env and not the docker integration, simply mount the `/modcache` folder on your remote host(s), ensuring it is writeable by all participating containers.
|
||||
|
||||
If you are using the docker integration, our only supported means for connecting to remote hosts is [our socket proxy container](). Run an instance on each remote host:
|
||||
|
||||
>[!WARNING]
|
||||
>DO NOT expose a socket proxy to your LAN that allows any write operations (`POST=1`, `ALLOW_RESTART=1`, etc) or that exposes any more information than is absolutely necessary. NEVER expose a socket proxy to your WAN.
|
||||
|
||||
```yml
|
||||
modmanager-dockerproxy:
|
||||
image: lscr.io/linuxserver/socket-proxy:latest
|
||||
container_name: modmanager-dockerproxy
|
||||
environment:
|
||||
- CONTAINERS=1
|
||||
- POST=0
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
tmpfs:
|
||||
- /run:exec
|
||||
ports:
|
||||
- 2375:2375
|
||||
restart: unless-stopped
|
||||
read_only: true
|
||||
```
|
||||
|
||||
And then add it to the `DOCKER_MODS_EXTRA_HOSTS` env using the full protocol and port, e.g.
|
||||
|
||||
```yaml
|
||||
- DOCKER_MODS_EXTRA_HOSTS=tcp://host1.example.com:2375|tcp://host2.example.com:2375|tcp://192.168.0.5:2375
|
||||
```
|
||||
|
||||
As above you will need to mount the `/modcache` folder on your remote host(s), ensuring it is writeable by all participating containers.
|
||||
|
||||
### Security considerations
|
||||
|
||||
Mapping `docker.sock` is a potential security liability because docker has root access on the host and any process that has full access to `docker.sock` would also have root access on the host. Docker api has no built-in way to set limitations on access, however, you can use a proxy for the `docker.sock` via a solution like [our docker socket proxy](https://github.com/linuxserver/docker-socket-proxy), which adds the ability to limit access. Then you would just set `DOCKER_HOST=` environment variable to point to the proxy address.
|
||||
@ -88,6 +125,7 @@ full_custom_readme: |
|
||||
environment:
|
||||
- DOCKER_MODS= `#optional`
|
||||
- DOCKER_HOST= `#optional`
|
||||
- DOCKER_MODS_EXTRA_HOSTS= `#optional`
|
||||
volumes:
|
||||
- /path/to/modcache:/modcache
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro `#optional`
|
||||
@ -101,6 +139,7 @@ full_custom_readme: |
|
||||
--name=modmanager \
|
||||
-e DOCKER_MODS= `#optional` \
|
||||
-e DOCKER_HOST= `#optional` \
|
||||
-e DOCKER_MODS_EXTRA_HOSTS= `#optional` \
|
||||
-v /path/to/modcache:/modcache \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock:ro `#optional` \
|
||||
--restart unless-stopped \
|
||||
@ -115,6 +154,7 @@ full_custom_readme: |
|
||||
| :----: | --- |
|
||||
| `-e DOCKER_MODS=` | Pipe-delimited (`\|`) list of mods to download |
|
||||
| `-e DOCKER_HOST=` | Specify the docker endpoint to use if not using the docker.sock |
|
||||
| `-e DOCKER_MODS_EXTRA_HOSTS=` | Pipe-delimited (`\|`) list of additional hosts to query & download mods for. See app setup section for details. |
|
||||
| `-v /modcache` | Modmanager mod storage. |
|
||||
| `-v /var/run/docker.sock:ro` | Mount the host docker socket into the container. |
|
||||
|
||||
|
||||
@ -1,26 +1,50 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
|
||||
# Main script loop
|
||||
if [[ -e "/var/run/docker.sock" ]] || [[ -n "${DOCKER_HOST}" ]]; then
|
||||
find_docker_mods() {
|
||||
# Mods provided via Docker
|
||||
echo -e "[mod-init] Searching all containers for DOCKER_MODS..."
|
||||
for CONTAINER in $(docker ps -q); do
|
||||
CONTAINER_MODS=$(docker inspect "${CONTAINER}" | jq -r '.[].Config.Env | to_entries | map(select(.value | match("DOCKER_MODS="))) | .[].value')
|
||||
CONTAINER_NAME=$(docker inspect "${CONTAINER}" | jq -r .[].Name | cut -d '/' -f2)
|
||||
if [[ "${2}" != "default" ]]; then
|
||||
docker context create "${2}" --docker "host=${1}" >/dev/null 2>&1
|
||||
fi
|
||||
docker --context "${2}" ps -q >/dev/null 2>&1 || DOCKER_MOD_CONTEXT_FAIL=true
|
||||
if [[ "${DOCKER_MOD_CONTEXT_FAIL}" == "true" ]]; then
|
||||
unset DOCKER_MOD_CONTEXT_FAIL
|
||||
echo "[mod-init] (ERROR) Cannot connect to the Docker daemon at ${2}, skipping host"
|
||||
return
|
||||
fi
|
||||
echo -e "[mod-init] Searching all containers in the ${2} context for DOCKER_MODS..."
|
||||
for CONTAINER in $(docker --context "${2}" ps -q); do
|
||||
CONTAINER_MODS=$(docker --context "${2}" inspect "${CONTAINER}" | jq -r '.[].Config.Env | to_entries | map(select(.value | match("DOCKER_MODS="))) | .[].value')
|
||||
CONTAINER_NAME=$(docker --context "${2}" inspect "${CONTAINER}" | jq -r .[].Name | cut -d '/' -f2)
|
||||
if [[ -n ${CONTAINER_MODS} ]]; then
|
||||
CONTAINER_MODS=$(awk -F '=' '{print $2}' <<< "${CONTAINER_MODS}")
|
||||
for CONTAINER_MOD in $(tr '|' '\n' <<< "${CONTAINER_MODS}"); do
|
||||
if [[ "${DOCKER_MODS}" =~ ${CONTAINER_MOD} ]]; then
|
||||
echo -e "[mod-init] ${CONTAINER_MOD} already in mod list, skipping"
|
||||
else
|
||||
echo -e "[mod-init] Found new mod ${CONTAINER_MODS} for container ${CONTAINER_NAME}"
|
||||
echo -e "[mod-init] Found new mod ${CONTAINER_MOD} for container ${CONTAINER_NAME}"
|
||||
DOCKER_MODS="${DOCKER_MODS}|${CONTAINER_MOD}"
|
||||
DOCKER_MODS="${DOCKER_MODS#|}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
if [[ "${2}" != "default" ]]; then
|
||||
docker context rm "${2}" >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# Main script loop
|
||||
if [[ -e "/var/run/docker.sock" ]] || [[ -n "${DOCKER_HOST}" ]]; then
|
||||
find_docker_mods "${DOCKER_HOST:-docker.sock}" "default"
|
||||
fi
|
||||
|
||||
if [[ -n "${DOCKER_MODS_EXTRA_HOSTS}" ]]; then
|
||||
for DOCKER_MOD_CONTEXT in $(echo "${DOCKER_MODS_EXTRA_HOSTS}" | tr '|' '\n'); do
|
||||
DOCKER_MOD_CONTEXT_NAME="${DOCKER_MOD_CONTEXT##*//}"
|
||||
DOCKER_MOD_CONTEXT_NAME="${DOCKER_MOD_CONTEXT_NAME%%:*}"
|
||||
find_docker_mods "${DOCKER_MOD_CONTEXT}" "${DOCKER_MOD_CONTEXT_NAME}"
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ -n "${DOCKER_MODS}" ]]; then
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user