mirror of
https://github.com/nextcloud/all-in-one.git
synced 2026-05-22 19:30:11 +00:00
Compare commits
9 Commits
copilot/im
...
copilot/se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbafd6ff8c | ||
|
|
adcc41f401 | ||
|
|
68bb93a2c8 | ||
|
|
a415c76ad2 | ||
|
|
79e05f33cd | ||
|
|
ef58220c09 | ||
|
|
6a9e55a8de | ||
|
|
8356d0dadc | ||
|
|
3e72f06d32 |
@@ -2,7 +2,7 @@
|
||||
FROM caddy:2.11.2-alpine AS caddy
|
||||
|
||||
# From https://github.com/docker-library/httpd/blob/master/2.4/alpine/Dockerfile
|
||||
FROM httpd:2.4.67-alpine3.23
|
||||
FROM httpd:2.4.66-alpine3.23
|
||||
|
||||
COPY --from=caddy /usr/bin/caddy /usr/bin/caddy
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# syntax=docker/dockerfile:latest
|
||||
FROM haproxy:3.3.8-alpine
|
||||
FROM haproxy:3.3.7-alpine
|
||||
|
||||
# hadolint ignore=DL3002
|
||||
USER root
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:latest
|
||||
# Probably from here https://github.com/elastic/dockerfiles/blob/9.3/elasticsearch/Dockerfile
|
||||
FROM elasticsearch:9.4.0
|
||||
FROM elasticsearch:9.3.3
|
||||
|
||||
USER root
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:latest
|
||||
# From https://github.com/redis/docker-library-redis/blob/release/8.2/alpine/Dockerfile
|
||||
FROM redis:8.6.3-alpine
|
||||
FROM redis:8.6.2-alpine
|
||||
|
||||
COPY --chmod=775 start.sh /start.sh
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# syntax=docker/dockerfile:latest
|
||||
FROM nats:2.14.0-scratch AS nats
|
||||
FROM nats:2.12.8-scratch AS nats
|
||||
FROM eturnal/eturnal:1.12.2-alpine AS eturnal
|
||||
FROM strukturag/nextcloud-spreed-signaling:2.1.1 AS signaling
|
||||
FROM alpine:3.23.4 AS janus
|
||||
|
||||
@@ -4,7 +4,6 @@ services:
|
||||
image: ghcr.io/nextcloud-releases/all-in-one:latest # This is the container image used. You can switch to ghcr.io/nextcloud-releases/all-in-one:beta if you want to help testing new releases. See https://github.com/nextcloud/all-in-one#how-to-switch-the-channel
|
||||
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
|
||||
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. 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
|
||||
|
||||
@@ -144,7 +144,6 @@ apt install --no-install-recommends qemu-system qemu-utils libvirt-clients libvi
|
||||
--name nextcloud-aio-mastercontainer \
|
||||
--restart always \
|
||||
--publish 8080:8080 \
|
||||
--cpu-shares 2048 \
|
||||
--env APACHE_PORT=11000 \
|
||||
--env APACHE_IP_BINDING=0.0.0.0 \
|
||||
--env TALK_PORT=3478 \
|
||||
|
||||
@@ -141,9 +141,6 @@
|
||||
"shm_size": {
|
||||
"type": "integer"
|
||||
},
|
||||
"cpu_shares": {
|
||||
"type": "integer"
|
||||
},
|
||||
"secrets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
@@ -81,8 +81,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 1024
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-database",
|
||||
@@ -139,8 +138,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 1024
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-nextcloud",
|
||||
@@ -282,8 +280,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 1024
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-notify-push",
|
||||
@@ -324,8 +321,7 @@
|
||||
"read_only": true,
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 1024
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-redis",
|
||||
@@ -367,8 +363,7 @@
|
||||
"read_only": true,
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 1024
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-collabora",
|
||||
@@ -418,8 +413,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 512
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-talk",
|
||||
@@ -490,8 +484,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 512
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-talk-recording",
|
||||
@@ -545,8 +538,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 512
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-borgbackup",
|
||||
@@ -617,8 +609,7 @@
|
||||
"tmpfs": [
|
||||
"/tmp",
|
||||
"/nextcloud_aio_volumes"
|
||||
],
|
||||
"cpu_shares": 1024
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-watchtower",
|
||||
@@ -641,8 +632,7 @@
|
||||
"read_only": true,
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 1024
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-domaincheck",
|
||||
@@ -675,8 +665,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 512
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-clamav",
|
||||
@@ -723,8 +712,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 512
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-onlyoffice",
|
||||
@@ -768,8 +756,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 512
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-imaginary",
|
||||
@@ -811,8 +798,7 @@
|
||||
],
|
||||
"secrets": [
|
||||
"IMAGINARY_SECRET"
|
||||
],
|
||||
"cpu_shares": 512
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-fulltextsearch",
|
||||
@@ -864,8 +850,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 512
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-docker-socket-proxy",
|
||||
@@ -892,8 +877,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 1024
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-harp",
|
||||
@@ -934,8 +918,7 @@
|
||||
],
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 1024
|
||||
]
|
||||
},
|
||||
{
|
||||
"container_name": "nextcloud-aio-whiteboard",
|
||||
@@ -981,8 +964,7 @@
|
||||
"read_only": true,
|
||||
"cap_drop": [
|
||||
"NET_RAW"
|
||||
],
|
||||
"cpu_shares": 512
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
26
php/public/clean-history.js
Normal file
26
php/public/clean-history.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// This script is loaded after a successful token-based login.
|
||||
// It replaces the browser's current history entry (stripping the token from the
|
||||
// URL) before navigating to the main AIO page, so the token is never left in
|
||||
// the browser history and cannot be accidentally exposed via the back-button.
|
||||
//
|
||||
// The target URL is passed via the script tag's data-target attribute.
|
||||
// document.currentScript is only available during synchronous script execution
|
||||
// (not with defer/async), so this script is loaded without those attributes.
|
||||
//
|
||||
// We replace with location.pathname only (no query string, no hash), which
|
||||
// intentionally strips the ?token=… parameter and any hash fragment from the
|
||||
// recorded history entry.
|
||||
|
||||
// Guard against environments where document.currentScript may be null.
|
||||
if (!document.currentScript) {
|
||||
window.location.replace('/');
|
||||
} else {
|
||||
const rawTarget = document.currentScript.dataset.target;
|
||||
|
||||
// Only accept the exact relative path we set server-side to prevent any
|
||||
// potential open-redirect via a manipulated data-target value.
|
||||
const target = rawTarget === '../../' ? rawTarget : '/';
|
||||
|
||||
history.replaceState(null, '', location.pathname);
|
||||
window.location.replace(target);
|
||||
}
|
||||
@@ -68,7 +68,7 @@ session_start([
|
||||
"use_strict_mode" => true, // Only allow initialized session IDs. See https://www.php.net/manual/en/session.configuration.php#ini.session.use-strict-mode
|
||||
"cookie_secure" => true, // Only send cookies over https (not http). See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#secure
|
||||
"cookie_httponly" => true, // Block the cookie from being read with js in the browser, will still be send for fetch request triggered by js. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#httponly
|
||||
"cookie_samesite" => "Lax", // Send the cookie with same-site requests and top-level cross-site navigations (e.g. redirect after token-based getlogin). "Strict" would block the session cookie on the redirect that follows a cross-site navigation, breaking the getlogin flow from Nextcloud's admin panel. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#samesitesamesite-value
|
||||
"cookie_samesite" => "Strict", // Only send the cookie with requests triggered by AIO itself. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#samesitesamesite-value
|
||||
]);
|
||||
|
||||
if ($wasAuthenticated) {
|
||||
@@ -181,7 +181,7 @@ $app->get('/containers', function (Request $request, Response $response, array $
|
||||
'community_containers' => $configurationManager->listAvailableCommunityContainers(),
|
||||
'community_containers_enabled' => $configurationManager->aioCommunityContainers,
|
||||
'bypass_container_update' => $bypass_container_update,
|
||||
]);
|
||||
])->withHeader('Cache-Control', 'no-store');
|
||||
})->setName('profile');
|
||||
$app->get('/login', function (Request $request, Response $response, array $args) use ($container) {
|
||||
$view = Twig::fromRequest($request);
|
||||
@@ -209,7 +209,7 @@ $app->get('/setup', function (Request $request, Response $response, array $args)
|
||||
[
|
||||
'password' => $setup->Setup(),
|
||||
]
|
||||
);
|
||||
)->withHeader('Cache-Control', 'no-store');
|
||||
});
|
||||
$app->get('/log', function (Request $request, Response $response, array $args) use ($container) {
|
||||
$params = $request->getQueryParams();
|
||||
|
||||
@@ -28,7 +28,6 @@ readonly class Container {
|
||||
/** @var string[] */
|
||||
public array $capAdd,
|
||||
public int $shmSize,
|
||||
public int $cpuShares,
|
||||
public bool $apparmorUnconfined,
|
||||
/** @var string[] */
|
||||
public array $backupVolumes,
|
||||
|
||||
@@ -303,11 +303,6 @@ 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'];
|
||||
@@ -366,7 +361,6 @@ readonly class ContainerDefinitionFetcher {
|
||||
$enableNvidiaGpu,
|
||||
$capAdd,
|
||||
$shmSize,
|
||||
$cpuShares,
|
||||
$apparmorUnconfined,
|
||||
$backupVolumes,
|
||||
$nextcloudExecCommands,
|
||||
|
||||
@@ -339,7 +339,7 @@ readonly class DockerController {
|
||||
|
||||
$body = $nonbufResp->getBody();
|
||||
$addToStreamingResponseBody = function (string $message) use ($body) : void {
|
||||
$body->write("<div>$message</div>");
|
||||
$body->write('<div>' . htmlspecialchars($message, ENT_QUOTES | ENT_HTML5) . '</div>');
|
||||
};
|
||||
|
||||
$this->dockerActionManager->SystemPrune($addToStreamingResponseBody);
|
||||
@@ -430,7 +430,7 @@ readonly class DockerController {
|
||||
// if it'll actually pull an image), but which should not need to know anything about the
|
||||
// wanted markup or formatting.
|
||||
$addToStreamingResponseBody = function (Container $container, string $message) use ($nonbufResp) : void {
|
||||
$nonbufResp->getBody()->write("<div>{$container->displayName}: {$message}</div>");
|
||||
$nonbufResp->getBody()->write('<div>' . htmlspecialchars($container->displayName, ENT_QUOTES | ENT_HTML5) . ': ' . htmlspecialchars($message, ENT_QUOTES | ENT_HTML5) . '</div>');
|
||||
};
|
||||
|
||||
return $addToStreamingResponseBody;
|
||||
|
||||
@@ -39,7 +39,19 @@ readonly class LoginController {
|
||||
$token = $request->getQueryParams()['token'] ?? '';
|
||||
if($this->authManager->CheckToken($token)) {
|
||||
$this->authManager->SetAuthState(true);
|
||||
return $response->withHeader('Location', '../..')->withStatus(302);
|
||||
// Return a minimal HTML page that uses JavaScript to replace the browser's
|
||||
// current history entry (removing the token from it) before navigating to
|
||||
// the main AIO page. This prevents the token from remaining in browser history.
|
||||
// The script is served from 'self'; same-origin scripts are already trusted under
|
||||
// the 'script-src-elem self' CSP directive, so no SRI hash is needed here.
|
||||
$response->getBody()->write(
|
||||
'<!DOCTYPE html>' .
|
||||
'<html lang="en">' .
|
||||
'<head><script src="../../clean-history.js" data-target="../../"></script></head>' .
|
||||
'<body></body>' .
|
||||
'</html>'
|
||||
);
|
||||
return $response->withHeader('Content-Type', 'text/html; charset=utf-8')->withStatus(200);
|
||||
}
|
||||
|
||||
// Punish failed auth attempts with a delay, as a very simple means against bots.
|
||||
|
||||
@@ -374,11 +374,6 @@ readonly class DockerActionManager {
|
||||
$requestBody['HostConfig']['ShmSize'] = $shmSize;
|
||||
}
|
||||
|
||||
$cpuShares = $container->cpuShares;
|
||||
if ($cpuShares > 0) {
|
||||
$requestBody['HostConfig']['CpuShares'] = $cpuShares;
|
||||
}
|
||||
|
||||
$tmpfs = [];
|
||||
foreach ($container->tmpfs as $tmp) {
|
||||
$mode = "";
|
||||
|
||||
@@ -1 +1 @@
|
||||
13.0.3
|
||||
13.0.1
|
||||
|
||||
@@ -202,7 +202,6 @@ 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
|
||||
@@ -219,7 +218,6 @@ 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.
|
||||
@@ -705,7 +703,6 @@ 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
|
||||
|
||||
@@ -1105,7 +1105,6 @@ sudo docker run \
|
||||
--name nextcloud-aio-mastercontainer \
|
||||
--restart always \
|
||||
--publish 8080:8080 \
|
||||
--cpu-shares 2048 \
|
||||
--env APACHE_PORT=11000 \
|
||||
--env APACHE_IP_BINDING=0.0.0.0 \
|
||||
--env APACHE_ADDITIONAL_NETWORK="" \
|
||||
@@ -1125,7 +1124,6 @@ ghcr.io/nextcloud-releases/all-in-one:latest
|
||||
- `--name nextcloud-aio-mastercontainer` This is the name of the container. This line is not allowed to be changed, since mastercontainer updates would fail.
|
||||
- `--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/
|
||||
- `--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)
|
||||
@@ -1156,7 +1154,6 @@ docker run ^
|
||||
--name nextcloud-aio-mastercontainer ^
|
||||
--restart always ^
|
||||
--publish 8080:8080 ^
|
||||
--cpu-shares 2048 ^
|
||||
--env APACHE_PORT=11000 ^
|
||||
--env APACHE_IP_BINDING=0.0.0.0 ^
|
||||
--env APACHE_ADDITIONAL_NETWORK="" ^
|
||||
|
||||
Reference in New Issue
Block a user