From 4b27d6954fba2a0f46a07e66cb470b9d199441bc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Apr 2026 01:58:39 +0000 Subject: [PATCH] WIP: implementing windmill container changes Agent-Logs-Url: https://github.com/nextcloud/all-in-one/sessions/6f198732-63c3-41b7-8b2e-1b5fa565ee21 Co-authored-by: szaimen <42591237+szaimen@users.noreply.github.com> --- Containers/apache/start.sh | 10 +++ Containers/nextcloud/entrypoint.sh | 17 +++++ php/containers.json | 63 +++++++++++++++++-- php/public/index.php | 1 + php/src/ContainerDefinitionFetcher.php | 8 +++ .../Controller/ConfigurationController.php | 1 + php/src/Data/ConfigurationManager.php | 7 +++ .../includes/optional-containers.twig | 14 +++++ 8 files changed, 116 insertions(+), 5 deletions(-) diff --git a/Containers/apache/start.sh b/Containers/apache/start.sh index 02a2f2ad..403eeda1 100644 --- a/Containers/apache/start.sh +++ b/Containers/apache/start.sh @@ -60,6 +60,16 @@ if [ -z "$ADDITIONAL_TRUSTED_DOMAIN" ]; then fi echo "$CADDYFILE" > /tmp/Caddyfile +# Add windmill site if windmill is enabled +if [ "$WINDMILL_ENABLED" = "yes" ]; then + cat >> /tmp/Caddyfile << 'WINDMILL_EOF' + +https://{$NC_DOMAIN}:3100 { + reverse_proxy {$WINDMILL_HOST}:8000 +} +WINDMILL_EOF +fi + # Fix the Caddyfile format caddy fmt --overwrite /tmp/Caddyfile diff --git a/Containers/nextcloud/entrypoint.sh b/Containers/nextcloud/entrypoint.sh index 3c6f2c30..ced43f22 100644 --- a/Containers/nextcloud/entrypoint.sh +++ b/Containers/nextcloud/entrypoint.sh @@ -1090,5 +1090,22 @@ else fi fi +# Windmill app +if [ "$WINDMILL_ENABLED" = 'yes' ]; then + if ! [ -d "/var/www/html/custom_apps/windmill" ]; then + php /var/www/html/occ app:install windmill + elif [ "$(php /var/www/html/occ config:app:get windmill enabled)" != "yes" ]; then + php /var/www/html/occ app:enable windmill + elif [ "$SKIP_UPDATE" != 1 ]; then + php /var/www/html/occ app:update windmill + fi + php /var/www/html/occ config:app:set windmill windmill_url --value="https://$NC_DOMAIN:3100" + php /var/www/html/occ config:app:set windmill windmill_instance_url --value="http://$WINDMILL_HOST:8000" +else + if [ "$REMOVE_DISABLED_APPS" = yes ] && [ -d "/var/www/html/custom_apps/windmill" ]; then + php /var/www/html/occ app:remove windmill + fi +fi + # Remove the update skip file always rm -f "$NEXTCLOUD_DATA_DIR"/skip.update diff --git a/php/containers.json b/php/containers.json index dcf3bed7..7e751754 100644 --- a/php/containers.json +++ b/php/containers.json @@ -11,6 +11,7 @@ "nextcloud-aio-notify-push", "nextcloud-aio-whiteboard", "nextcloud-aio-harp", + "nextcloud-aio-windmill", "nextcloud-aio-nextcloud" ], "display_name": "Apache & Caddy", @@ -35,6 +36,11 @@ "ip_binding": "%APACHE_IP_BINDING%", "port_number": "%APACHE_PORT%", "protocol": "udp" + }, + { + "ip_binding": "%APACHE_IP_BINDING%", + "port_number": "3100", + "protocol": "tcp" } ], "internal_port": "%APACHE_PORT%", @@ -51,7 +57,9 @@ "APACHE_MAX_TIME=%NEXTCLOUD_MAX_TIME%", "NOTIFY_PUSH_HOST=nextcloud-aio-notify-push", "WHITEBOARD_HOST=nextcloud-aio-whiteboard", - "HARP_HOST=nextcloud-aio-harp" + "HARP_HOST=nextcloud-aio-harp", + "WINDMILL_ENABLED=%WINDMILL_ENABLED%", + "WINDMILL_HOST=nextcloud-aio-windmill" ], "volumes": [ { @@ -102,7 +110,8 @@ ], "internal_port": "5432", "secrets": [ - "DATABASE_PASSWORD" + "DATABASE_PASSWORD", + "WINDMILL_DB_PASSWORD" ], "volumes": [ { @@ -121,7 +130,9 @@ "POSTGRES_DB=nextcloud_database", "POSTGRES_USER=nextcloud", "TZ=%TIMEZONE%", - "PGTZ=%TIMEZONE%" + "PGTZ=%TIMEZONE%", + "WINDMILL_DB_PASSWORD=%WINDMILL_DB_PASSWORD%", + "WINDMILL_ENABLED=%WINDMILL_ENABLED%" ], "stop_grace_period": 1800, "restart": "unless-stopped", @@ -148,7 +159,8 @@ "nextcloud-aio-fulltextsearch", "nextcloud-aio-talk-recording", "nextcloud-aio-imaginary", - "nextcloud-aio-docker-socket-proxy" + "nextcloud-aio-docker-socket-proxy", + "nextcloud-aio-windmill" ], "display_name": "Nextcloud", "image": "ghcr.io/nextcloud-releases/aio-nextcloud", @@ -263,7 +275,9 @@ "WHITEBOARD_SECRET=%WHITEBOARD_SECRET%", "WHITEBOARD_ENABLED=%WHITEBOARD_ENABLED%", "HARP_ENABLED=%HARP_ENABLED%", - "HP_SHARED_KEY=%HP_SHARED_KEY%" + "HP_SHARED_KEY=%HP_SHARED_KEY%", + "WINDMILL_ENABLED=%WINDMILL_ENABLED%", + "WINDMILL_HOST=nextcloud-aio-windmill" ], "stop_grace_period": 600, "restart": "unless-stopped", @@ -949,6 +963,45 @@ "cap_drop": [ "NET_RAW" ] + }, + { + "container_name": "nextcloud-aio-windmill", + "image_tag": "main", + "display_name": "Windmill", + "image": "ghcr.io/windmill-labs/windmill", + "init": true, + "depends_on": [ + "nextcloud-aio-database" + ], + "internal_port": "8000", + "expose": [ + "8000" + ], + "secrets": [ + "WINDMILL_DB_PASSWORD" + ], + "environment": [ + "DATABASE_URL=postgresql://windmill:%WINDMILL_DB_PASSWORD%@nextcloud-aio-database/windmill", + "WM_BASE_URL=https://%NC_DOMAIN%:3100", + "TZ=%TIMEZONE%", + "NUM_WORKERS=1", + "MODE=standalone", + "DISABLE_NSJAIL=true" + ], + "volumes": [ + { + "source": "nextcloud_aio_windmill", + "destination": "/tmp/windmill/cache", + "writeable": true + } + ], + "restart": "unless-stopped", + "profiles": [ + "windmill" + ], + "cap_drop": [ + "NET_RAW" + ] } ] } diff --git a/php/public/index.php b/php/public/index.php index 5d706c2d..421bfed7 100644 --- a/php/public/index.php +++ b/php/public/index.php @@ -177,6 +177,7 @@ $app->get('/containers', function (Request $request, Response $response, array $ 'is_docker_socket_proxy_enabled' => $configurationManager->isDockerSocketProxyEnabled, 'is_harp_enabled' => $configurationManager->isHarpEnabled, 'is_whiteboard_enabled' => $configurationManager->isWhiteboardEnabled, + 'is_windmill_enabled' => $configurationManager->isWindmillEnabled, 'community_containers' => $configurationManager->listAvailableCommunityContainers(), 'community_containers_enabled' => $configurationManager->aioCommunityContainers, 'bypass_container_update' => $bypass_container_update, diff --git a/php/src/ContainerDefinitionFetcher.php b/php/src/ContainerDefinitionFetcher.php index e4625a24..983fb56f 100644 --- a/php/src/ContainerDefinitionFetcher.php +++ b/php/src/ContainerDefinitionFetcher.php @@ -109,6 +109,10 @@ readonly class ContainerDefinitionFetcher { if (!$this->configurationManager->isWhiteboardEnabled) { continue; } + } elseif ($entry['container_name'] === 'nextcloud-aio-windmill') { + if (!$this->configurationManager->isWindmillEnabled) { + continue; + } } $ports = new ContainerPorts(); @@ -222,6 +226,10 @@ readonly class ContainerDefinitionFetcher { if (!$this->configurationManager->isWhiteboardEnabled) { continue; } + } elseif ($value === 'nextcloud-aio-windmill') { + if (!$this->configurationManager->isWindmillEnabled) { + continue; + } } else { // Skip dependencies on community containers that are not currently enabled. // Only apply this when the current entry is itself a community container, diff --git a/php/src/Controller/ConfigurationController.php b/php/src/Controller/ConfigurationController.php index 4dbe3ae2..8b35a573 100644 --- a/php/src/Controller/ConfigurationController.php +++ b/php/src/Controller/ConfigurationController.php @@ -98,6 +98,7 @@ readonly class ConfigurationController { $this->configurationManager->isDockerSocketProxyEnabled = isset($request->getParsedBody()['docker-socket-proxy']); $this->configurationManager->isHarpEnabled = isset($request->getParsedBody()['harp']); $this->configurationManager->isWhiteboardEnabled = isset($request->getParsedBody()['whiteboard']); + $this->configurationManager->isWindmillEnabled = isset($request->getParsedBody()['windmill']); } if (isset($request->getParsedBody()['community-form'])) { diff --git a/php/src/Data/ConfigurationManager.php b/php/src/Data/ConfigurationManager.php index b226a139..448c32fe 100644 --- a/php/src/Data/ConfigurationManager.php +++ b/php/src/Data/ConfigurationManager.php @@ -45,6 +45,12 @@ class ConfigurationManager set { $this->set('isWhiteboardEnabled', $value); } } + public bool $isWindmillEnabled { + // Type-cast because old configs could have 1/0 for this key. + get => (bool) $this->get('isWindmillEnabled', false); + set { $this->set('isWindmillEnabled', $value); } + } + public bool $restoreExcludePreviews { // Type-cast because old configs could have '1'/'' for this key. get => (bool) $this->get('restore-exclude-previews', false); @@ -1108,6 +1114,7 @@ class ConfigurationManager // Allow to get local ip-address of caddy container and add it to trusted proxies automatically 'CADDY_IP_ADDRESS' => in_array('caddy', $this->aioCommunityContainers, true) ? gethostbyname('nextcloud-aio-caddy') : '', 'WHITEBOARD_ENABLED' => $this->isWhiteboardEnabled ? 'yes' : '', + 'WINDMILL_ENABLED' => $this->isWindmillEnabled ? 'yes' : '', 'AIO_VERSION' => $this->getAioVersion(), default => $this->getRegisteredSecret($placeholder), }; diff --git a/php/templates/includes/optional-containers.twig b/php/templates/includes/optional-containers.twig index b93ef57f..8932b3a2 100644 --- a/php/templates/includes/optional-containers.twig +++ b/php/templates/includes/optional-containers.twig @@ -220,6 +220,20 @@ >

+

+ + +

Minimal system requirements: When any optional container is enabled, at least 2GB RAM, a dual-core CPU and 40GB system storage are required. When enabling ClamAV, Nextcloud Talk Recording-server or Fulltextsearch, at least 3GB RAM are required. For Talk Recording-server additional 2 vCPUs are required. When enabling everything, at least 5GB RAM and a quad-core CPU are required. Recommended are at least 1GB more RAM than the minimal requirement. For further advice and recommendations see this documentation