diff --git a/compose.yaml b/compose.yaml index 4e901fa9..e219d147 100644 --- a/compose.yaml +++ b/compose.yaml @@ -5,6 +5,7 @@ services: init: true # This setting makes sure that signals from main process inside the container are correctly forwarded to children. See https://docs.docker.com/reference/compose-file/services/#init restart: always # This makes sure that the container starts always together with the host OS. See https://docs.docker.com/reference/compose-file/services/#restart oom_score_adj: -500 # This makes the Linux OOM killer strongly prefer other processes, keeping the AIO interface reachable under memory pressure. See https://docs.kernel.org/admin-guide/cgroup-v1/memory.html + cpu_shares: 2048 # This doubles the default CPU share weighting so the mastercontainer stays responsive under heavy load. See https://docs.docker.com/reference/compose-file/services/#cpu_shares container_name: nextcloud-aio-mastercontainer # This line is not allowed to be changed as otherwise AIO will not work correctly volumes: - nextcloud_aio_mastercontainer:/mnt/docker-aio-config # This line is not allowed to be changed as otherwise the built-in backup solution will not work diff --git a/develop.md b/develop.md index 27bbaabb..d50fd67a 100644 --- a/develop.md +++ b/develop.md @@ -10,6 +10,7 @@ sudo docker run \ --publish 80:80 \ --publish 8080:8080 \ --publish 8443:8443 \ +--cpu-shares 2048 \ --volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \ --volume /var/run/docker.sock:/var/run/docker.sock:ro \ ghcr.io/nextcloud-releases/all-in-one:develop diff --git a/multiple-instances.md b/multiple-instances.md index 80913a5d..bce0ed03 100644 --- a/multiple-instances.md +++ b/multiple-instances.md @@ -145,6 +145,7 @@ apt install --no-install-recommends qemu-system qemu-utils libvirt-clients libvi --restart always \ --oom-score-adj -500 \ --publish 8080:8080 \ + --cpu-shares 2048 \ --env APACHE_PORT=11000 \ --env APACHE_IP_BINDING=0.0.0.0 \ --env TALK_PORT=3478 \ diff --git a/php/README.md b/php/README.md index 782b198b..1dfb42c4 100644 --- a/php/README.md +++ b/php/README.md @@ -33,6 +33,7 @@ docker run \ --rm \ --name nextcloud-aio-mastercontainer \ --oom-score-adj -500 \ +--cpu-shares 2048 \ --volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \ --volume /var/run/docker.sock:/var/run/docker.sock \ ghcr.io/nextcloud-releases/all-in-one:latest diff --git a/php/containers-schema.json b/php/containers-schema.json index e5d38ebd..7ec561e1 100644 --- a/php/containers-schema.json +++ b/php/containers-schema.json @@ -148,6 +148,11 @@ "shm_size": { "type": "integer" }, + "cpu_shares": { + "type": "integer", + "minimum": 512, + "maximum": 2048 + }, "secrets": { "type": "array", "items": { diff --git a/php/containers.json b/php/containers.json index 2706b697..bbcc7db2 100644 --- a/php/containers.json +++ b/php/containers.json @@ -83,7 +83,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": -100 + "oom_score_adj": -100, + "cpu_shares": 1024 }, { "container_name": "nextcloud-aio-database", @@ -141,7 +142,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": -300 + "oom_score_adj": -300, + "cpu_shares": 1024 }, { "container_name": "nextcloud-aio-nextcloud", @@ -287,7 +289,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": -100 + "oom_score_adj": -100, + "cpu_shares": 1024 }, { "container_name": "nextcloud-aio-notify-push", @@ -329,7 +332,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 100 + "oom_score_adj": 100, + "cpu_shares": 1024 }, { "container_name": "nextcloud-aio-redis", @@ -373,7 +377,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": -300 + "oom_score_adj": -300, + "cpu_shares": 1024 }, { "container_name": "nextcloud-aio-collabora", @@ -424,7 +429,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 300 + "oom_score_adj": 300, + "cpu_shares": 512 }, { "container_name": "nextcloud-aio-talk", @@ -495,7 +501,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 300 + "oom_score_adj": 300, + "cpu_shares": 512 }, { "container_name": "nextcloud-aio-talk-recording", @@ -550,7 +557,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 300 + "oom_score_adj": 300, + "cpu_shares": 512 }, { "container_name": "nextcloud-aio-borgbackup", @@ -622,7 +630,8 @@ "/tmp", "/nextcloud_aio_volumes" ], - "oom_score_adj": -300 + "oom_score_adj": -300, + "cpu_shares": 1024 }, { "container_name": "nextcloud-aio-watchtower", @@ -646,7 +655,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": -300 + "oom_score_adj": -300, + "cpu_shares": 1024 }, { "container_name": "nextcloud-aio-domaincheck", @@ -680,7 +690,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 300 + "oom_score_adj": 300, + "cpu_shares": 512 }, { "container_name": "nextcloud-aio-clamav", @@ -726,7 +737,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 300 + "oom_score_adj": 300, + "cpu_shares": 512 }, { "container_name": "nextcloud-aio-onlyoffice", @@ -771,7 +783,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 300 + "oom_score_adj": 300, + "cpu_shares": 512 }, { "container_name": "nextcloud-aio-eurooffice", @@ -821,7 +834,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 300 + "oom_score_adj": 300, + "cpu_shares": 512 }, { "container_name": "nextcloud-aio-imaginary", @@ -864,7 +878,8 @@ "secrets": [ "IMAGINARY_SECRET" ], - "oom_score_adj": 300 + "oom_score_adj": 300, + "cpu_shares": 512 }, { "container_name": "nextcloud-aio-fulltextsearch", @@ -919,7 +934,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 300 + "oom_score_adj": 300, + "cpu_shares": 512 }, { "container_name": "nextcloud-aio-docker-socket-proxy", @@ -947,7 +963,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 100 + "oom_score_adj": 100, + "cpu_shares": 1024 }, { "container_name": "nextcloud-aio-harp", @@ -1000,7 +1017,8 @@ "profiles": [ "harp" ], - "oom_score_adj": 100 + "oom_score_adj": 100, + "cpu_shares": 1024 }, { "container_name": "nextcloud-aio-whiteboard", @@ -1047,7 +1065,8 @@ "cap_drop": [ "NET_RAW" ], - "oom_score_adj": 300 + "oom_score_adj": 300, + "cpu_shares": 512 } ] } diff --git a/php/src/Container/Container.php b/php/src/Container/Container.php index 3df2be23..2dc7e02e 100644 --- a/php/src/Container/Container.php +++ b/php/src/Container/Container.php @@ -30,6 +30,7 @@ readonly class Container { /** @var string[] */ public array $sysctls, public int $shmSize, + public int $cpuShares, public bool $apparmorUnconfined, /** @var string[] */ public array $backupVolumes, diff --git a/php/src/ContainerDefinitionFetcher.php b/php/src/ContainerDefinitionFetcher.php index 00c0ebc1..657decf6 100644 --- a/php/src/ContainerDefinitionFetcher.php +++ b/php/src/ContainerDefinitionFetcher.php @@ -318,6 +318,11 @@ readonly class ContainerDefinitionFetcher { $shmSize = $entry['shm_size']; } + $cpuShares = 512; + if (isset($entry['cpu_shares'])) { + $cpuShares = $entry['cpu_shares']; + } + $apparmorUnconfined = false; if (isset($entry['apparmor_unconfined'])) { $apparmorUnconfined = $entry['apparmor_unconfined']; @@ -382,6 +387,7 @@ readonly class ContainerDefinitionFetcher { $capAdd, $sysctls, $shmSize, + $cpuShares, $apparmorUnconfined, $backupVolumes, $nextcloudExecCommands, diff --git a/php/src/Docker/DockerActionManager.php b/php/src/Docker/DockerActionManager.php index ec5bb97e..79050907 100644 --- a/php/src/Docker/DockerActionManager.php +++ b/php/src/Docker/DockerActionManager.php @@ -394,6 +394,11 @@ readonly class DockerActionManager { $requestBody['HostConfig']['ShmSize'] = $shmSize; } + $cpuShares = $container->cpuShares; + if ($cpuShares > 0) { + $requestBody['HostConfig']['CpuShares'] = $cpuShares; + } + $tmpfs = []; foreach ($container->tmpfs as $tmp) { $mode = ""; diff --git a/readme.md b/readme.md index 3cfce30c..15f9f83e 100644 --- a/readme.md +++ b/readme.md @@ -205,6 +205,7 @@ sudo docker run \ --publish 80:80 \ --publish 8080:8080 \ --publish 8443:8443 \ + --cpu-shares 2048 \ --volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \ --volume /var/run/docker.sock:/var/run/docker.sock:ro \ ghcr.io/nextcloud-releases/all-in-one:latest @@ -222,6 +223,7 @@ sudo docker run \ - `--publish 80:80` — publishes container port 80 on host port 80 (used for ACME http-challenge when obtaining certificates, used for for the AIO-interface running inside the mastercontainer). Not required if you run AIO behind a reverse proxy. - `--publish 8080:8080` — publishes the AIO interface (self-signed certificate) on host port 8080. You may map a different host port if 8080 is in use (e.g. `--publish 8081:8080`). - `--publish 8443:8443` — publishes the AIO interface with a valid certificate on host port 8443 (requires ports 80 and 8443 to be reachable and a domain pointing to your server). Not required if you run AIO behind a reverse proxy. + - `--cpu-shares 2048` — gives the mastercontainer twice the default CPU share weighting (default is 1024), ensuring it stays responsive under heavy load from sibling containers. - `--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config` — stores mastercontainer configuration in the named Docker volume. Do not change this volume name; built-in backups depend on it. - `--volume /var/run/docker.sock:/var/run/docker.sock:ro` — mounts the Docker socket (read-only) so the mastercontainer can manage other containers. On Windows/macOS or when using rootless Docker, this path may need adjustment; see the platform-specific docs. If you change the socket path, also set `WATCHTOWER_DOCKER_SOCKET_PATH` accordingly. If you prefer not to expose the socket, see the manual-install documentation: [Manual install without docker socket access](https://github.com/nextcloud/all-in-one/tree/main/manual-install) - `ghcr.io/nextcloud-releases/all-in-one:latest` — the mastercontainer image. @@ -728,6 +730,7 @@ docker run ^ --publish 80:80 ^ --publish 8080:8080 ^ --publish 8443:8443 ^ +--cpu-shares 2048 ^ --volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config ^ --volume //var/run/docker.sock:/var/run/docker.sock:ro ^ ghcr.io/nextcloud-releases/all-in-one:latest diff --git a/reverse-proxy.md b/reverse-proxy.md index cf119b49..1ab6d856 100644 --- a/reverse-proxy.md +++ b/reverse-proxy.md @@ -1117,6 +1117,7 @@ sudo docker run \ --restart always \ --oom-score-adj -500 \ --publish 8080:8080 \ +--cpu-shares 2048 \ --env APACHE_PORT=11000 \ --env APACHE_IP_BINDING=0.0.0.0 \ --env APACHE_ADDITIONAL_NETWORK="" \ @@ -1137,6 +1138,7 @@ ghcr.io/nextcloud-releases/all-in-one:latest - `--restart always` This is the "restart policy". `always` means that the container should always get started with the Docker daemon. See the Docker documentation for further detail about restart policies: https://docs.docker.com/config/containers/start-containers-automatically/ - `--oom-score-adj -500` This instructs the Linux OOM killer to strongly prefer killing other processes before the mastercontainer, keeping the AIO interface accessible even under memory pressure. - `--publish 8080:8080` This means that port 8080 of the container should get published on the host using port 8080. This port is used for the AIO interface and uses a self-signed certificate by default. You can also use a different host port if port 8080 is already used on your host, for example `--publish 8081:8080` (only the first port can be changed for the host, the second port is for the container and must remain at 8080). +- `--cpu-shares 2048` This gives the mastercontainer twice the default CPU share weighting (default is 1024), ensuring it stays responsive under heavy load from sibling containers. - `--env APACHE_PORT=11000` This is the port that is published on the host that runs Docker and Nextcloud AIO at which the reverse proxy should point at. - `--env APACHE_IP_BINDING=0.0.0.0` This can be modified to allow access to the published port on the host only from certain ip-addresses. [See this documentation](#3-limit-the-access-to-the-apache-container) - `--env APACHE_ADDITIONAL_NETWORK=""` This can be used to put the sibling apache container that is created by AIO into a specified network - useful if your reverse proxy runs as a container on the same host. [See this documentation](#adapting-the-sample-web-server-configurations-below) @@ -1168,6 +1170,7 @@ docker run ^ --restart always ^ --oom-score-adj -500 ^ --publish 8080:8080 ^ +--cpu-shares 2048 ^ --env APACHE_PORT=11000 ^ --env APACHE_IP_BINDING=0.0.0.0 ^ --env APACHE_ADDITIONAL_NETWORK="" ^