mirror of
https://github.com/nextcloud/all-in-one.git
synced 2026-05-21 10:50:10 +00:00
Compare commits
7 Commits
c60861d79c
...
8925baf12f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8925baf12f | ||
|
|
b3f66b4c50 | ||
|
|
e1e85c5ca9 | ||
|
|
1ee3db8195 | ||
|
|
56afde115d | ||
|
|
b205e46976 | ||
|
|
e077aea86d |
@@ -1101,6 +1101,49 @@ if [ "$WINDMILL_ENABLED" = 'yes' ]; then
|
||||
fi
|
||||
php /var/www/html/occ config:app:set windmill windmill_url --value="https://$NC_DOMAIN/windmill"
|
||||
php /var/www/html/occ config:app:set windmill windmill_instance_url --value="http://$WINDMILL_HOST:8000"
|
||||
# Create an NC OAuth2 client for Windmill (idempotent: reuse stored credentials if already created)
|
||||
WINDMILL_NC_OAUTH_CLIENT_ID="$(php /var/www/html/occ config:app:get windmill nc_oauth_client_id 2>/dev/null)"
|
||||
WINDMILL_NC_OAUTH_CLIENT_SECRET="$(php /var/www/html/occ config:app:get windmill nc_oauth_client_secret 2>/dev/null)"
|
||||
if [ -z "$WINDMILL_NC_OAUTH_CLIENT_ID" ] || [ -z "$WINDMILL_NC_OAUTH_CLIENT_SECRET" ]; then
|
||||
WINDMILL_NC_REDIRECT_URI="https://$NC_DOMAIN/windmill/user/login_callback/nextcloud"
|
||||
# Bootstrap NC to create the oauth2 client using NC's own DI container
|
||||
WINDMILL_OAUTH_JSON="$(php -r "
|
||||
define('OC_CONSOLE', 1);
|
||||
require_once '/var/www/html/lib/base.php';
|
||||
\OC_App::loadApp('oauth2');
|
||||
\$container = \OC::getContainer();
|
||||
\$mapper = \$container->get(\OCA\OAuth2\Db\ClientMapper::class);
|
||||
\$crypto = \$container->get(\OCP\Security\ICrypto::class);
|
||||
\$random = \$container->get(\OCP\Security\ISecureRandom::class);
|
||||
\$redirectUri = '${WINDMILL_NC_REDIRECT_URI}';
|
||||
// Delete any stale 'Windmill' client that might have lost its secret
|
||||
foreach (\$mapper->getClients() as \$c) {
|
||||
if (\$c->getName() === 'Windmill') { \$mapper->delete(\$c); }
|
||||
}
|
||||
\$client = new \OCA\OAuth2\Db\Client();
|
||||
\$client->setName('Windmill');
|
||||
\$client->setRedirectUri(\$redirectUri);
|
||||
\$secret = \$random->generate(64, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
|
||||
\$hashedSecret = bin2hex(\$crypto->calculateHMAC(\$secret));
|
||||
\$client->setSecret(\$hashedSecret);
|
||||
\$clientId = \$random->generate(64, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
|
||||
\$client->setClientIdentifier(\$clientId);
|
||||
\$mapper->insert(\$client);
|
||||
echo json_encode(['client_id' => \$clientId, 'client_secret' => \$secret]);
|
||||
" 2>/dev/null)"
|
||||
WINDMILL_NC_OAUTH_CLIENT_ID="$(echo "$WINDMILL_OAUTH_JSON" | php -r "echo json_decode(stream_get_contents(STDIN))->client_id;")"
|
||||
WINDMILL_NC_OAUTH_CLIENT_SECRET="$(echo "$WINDMILL_OAUTH_JSON" | php -r "echo json_decode(stream_get_contents(STDIN))->client_secret;")"
|
||||
php /var/www/html/occ config:app:set windmill nc_oauth_client_id --value="$WINDMILL_NC_OAUTH_CLIENT_ID"
|
||||
php /var/www/html/occ config:app:set windmill nc_oauth_client_secret --value="$WINDMILL_NC_OAUTH_CLIENT_SECRET"
|
||||
fi
|
||||
# Configure Windmill to use NC as OAuth SSO provider
|
||||
WINDMILL_OAUTH_BODY="{\"value\":{\"nextcloud\":{\"id\":\"$WINDMILL_NC_OAUTH_CLIENT_ID\",\"secret\":\"$WINDMILL_NC_OAUTH_CLIENT_SECRET\",\"login_config\":{\"auth_url\":\"https://$NC_DOMAIN/apps/oauth2/authorize\",\"token_url\":\"https://$NC_DOMAIN/apps/oauth2/api/v1/token\",\"userinfo_url\":\"https://$NC_DOMAIN/ocs/v2.php/cloud/user?format=json\",\"scopes\":[]}}}}"
|
||||
WINDMILL_OAUTH_RESPONSE="$(curl -s -w '\n%{http_code}' -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $WINDMILL_SECRET" -d "$WINDMILL_OAUTH_BODY" "http://$WINDMILL_HOST:8000/api/settings/global/oauths")"
|
||||
WINDMILL_OAUTH_STATUS="$(echo "$WINDMILL_OAUTH_RESPONSE" | tail -1)"
|
||||
if [ "$WINDMILL_OAUTH_STATUS" != "200" ]; then
|
||||
echo "Failed to configure Windmill OAuth against http://$WINDMILL_HOST:8000 (HTTP $WINDMILL_OAUTH_STATUS). Response: $(echo "$WINDMILL_OAUTH_RESPONSE" | head -1). Exiting!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if [ "$REMOVE_DISABLED_APPS" = yes ] && [ -d "/var/www/html/custom_apps/windmill" ]; then
|
||||
php /var/www/html/occ app:remove windmill
|
||||
|
||||
@@ -47,11 +47,13 @@ RUN set -ex; \
|
||||
# pre-installed runtimes would create a huge and unnecessary image layer.
|
||||
mkdir -p \
|
||||
/var/lib/postgresql/data \
|
||||
/var/lib/windmill-dump \
|
||||
/var/run/postgresql \
|
||||
/var/log/supervisord \
|
||||
/var/run/supervisord; \
|
||||
chown -R windmill:windmill \
|
||||
/var/lib/postgresql \
|
||||
/var/lib/windmill-dump \
|
||||
/var/run/postgresql \
|
||||
/var/log/supervisord \
|
||||
/var/run/supervisord; \
|
||||
@@ -94,7 +96,7 @@ ENV UV_TOOL_BIN_DIR=/tmp/windmill/cache/uv/bin \
|
||||
REQUESTS_CA_BUNDLE=/etc/ssl/ca-bundle.crt \
|
||||
NODE_EXTRA_CA_CERTS=/etc/ssl/ca-bundle.crt
|
||||
|
||||
VOLUME ["/var/lib/postgresql/data", "/tmp/windmill/cache"]
|
||||
VOLUME ["/var/lib/postgresql/data", "/var/lib/windmill-dump", "/tmp/windmill/cache"]
|
||||
|
||||
# Use the pre-existing windmill user (uid=1000) from the base image
|
||||
USER 1000
|
||||
|
||||
@@ -29,20 +29,26 @@ if [ -f "$IMAGE_EPOCH_FILE" ]; then
|
||||
fi
|
||||
|
||||
PGDATA="/var/lib/postgresql/data"
|
||||
DUMP_FILE="$PGDATA/windmill-db-dump.sql"
|
||||
|
||||
# The dump and its sentinel/log files live on a dedicated Docker volume that is
|
||||
# separate from the postgres data directory. This means the dump survives a
|
||||
# complete PGDATA wipe (which happens during a major-version upgrade) and there
|
||||
# is no need for a staging subdirectory or complex file exclusion logic.
|
||||
DUMP_DIR="/var/lib/windmill-dump"
|
||||
DUMP_FILE="$DUMP_DIR/windmill-db-dump.sql"
|
||||
|
||||
# Current PG major version as shipped in this image
|
||||
CURRENT_PG_MAJOR=$(cat /etc/postgres-major-version 2>/dev/null)
|
||||
|
||||
# ── Don't start if previous import failed ────────────────────────────────────
|
||||
if [ -f "$PGDATA/import.failed" ]; then
|
||||
if [ -f "$DUMP_DIR/import.failed" ]; then
|
||||
echo "The database import failed the last time. Please restore a backup and try again."
|
||||
echo "For further clues on what went wrong, look at the logs above."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Don't start if previous export failed ────────────────────────────────────
|
||||
if [ -f "$PGDATA/export.failed" ]; then
|
||||
if [ -f "$DUMP_DIR/export.failed" ]; then
|
||||
echo "Database export failed the last time. Most likely was the export time not high enough."
|
||||
echo "Please report this to https://github.com/nextcloud/all-in-one/issues. Thanks!"
|
||||
exit 1
|
||||
@@ -54,10 +60,9 @@ configure_pg() {
|
||||
cat > "$datadir/pg_hba.conf" << 'HBAEOF'
|
||||
# TYPE DATABASE USER ADDRESS METHOD
|
||||
local all all trust
|
||||
host all all 127.0.0.1/32 trust
|
||||
host all all ::1/128 trust
|
||||
HBAEOF
|
||||
echo "listen_addresses = 'localhost'" >> "$datadir/postgresql.conf"
|
||||
# Disable TCP entirely; all communication uses the Unix socket.
|
||||
echo "listen_addresses = ''" >> "$datadir/postgresql.conf"
|
||||
}
|
||||
|
||||
# ── PostgreSQL major-version upgrade via dump/restore ────────────────────────
|
||||
@@ -80,25 +85,22 @@ if [ -f "$PGDATA/PG_VERSION" ]; then
|
||||
fi
|
||||
|
||||
# Write output to logfile so the import can be inspected later
|
||||
exec > >(tee -i "$PGDATA/database-import.log")
|
||||
exec > >(tee -i "$DUMP_DIR/database-import.log")
|
||||
exec 2>&1
|
||||
|
||||
echo "Restoring database from dump into new PostgreSQL $CURRENT_PG_MAJOR cluster."
|
||||
|
||||
# Copy dump out of PGDATA before wiping it
|
||||
cp "$DUMP_FILE" /tmp/windmill-db-dump.sql
|
||||
|
||||
# Mark import as in-progress
|
||||
# (written to /tmp because PGDATA is about to be wiped)
|
||||
IMPORT_FAILED_TMP=/tmp/windmill-import.failed
|
||||
touch "$IMPORT_FAILED_TMP"
|
||||
# Set the sentinel BEFORE any destructive operation so that a crash at
|
||||
# any point leaves the guard in place and blocks the next start.
|
||||
# The sentinel lives on the dump volume and therefore survives the PGDATA wipe.
|
||||
touch "$DUMP_DIR/import.failed"
|
||||
|
||||
set -ex
|
||||
|
||||
# Remove old data directory
|
||||
# Wipe the old cluster and initialise a fresh one.
|
||||
# The dump file is on a separate volume and is not affected.
|
||||
rm -rf "${PGDATA:?}/"*
|
||||
|
||||
# Initialise a fresh cluster for the new major version
|
||||
initdb -D "$PGDATA" \
|
||||
--username=windmill \
|
||||
--auth-local=trust \
|
||||
@@ -107,37 +109,33 @@ if [ -f "$PGDATA/PG_VERSION" ]; then
|
||||
|
||||
configure_pg "$PGDATA"
|
||||
|
||||
# Mark import as in-progress inside the new data dir
|
||||
touch "$PGDATA/import.failed"
|
||||
|
||||
# Start postgres temporarily on an alternate TCP port so we can import
|
||||
export PGPORT=11000
|
||||
postgres -D "$PGDATA" -h 127.0.0.1 -p 11000 &
|
||||
# Start postgres temporarily on a socket in /tmp so we can import.
|
||||
# No TCP port is needed since we connect via the socket.
|
||||
postgres -D "$PGDATA" -k /tmp -h "" &
|
||||
TEMP_PG_PID=$!
|
||||
|
||||
# Wait until postgres accepts connections
|
||||
while ! psql -h 127.0.0.1 -p 11000 -U windmill -d postgres -c "select now()" > /dev/null 2>&1; do
|
||||
while ! psql -h /tmp -U windmill -d postgres -c "select now()" > /dev/null 2>&1; do
|
||||
echo "Waiting for the temporary database to start..."
|
||||
sleep 5
|
||||
done
|
||||
|
||||
# Create the windmill database
|
||||
psql -h 127.0.0.1 -p 11000 -U windmill -d postgres \
|
||||
psql -h /tmp -U windmill -d postgres \
|
||||
-c "CREATE DATABASE windmill OWNER windmill;"
|
||||
|
||||
# Restore from dump
|
||||
echo "Restoring the database from dump..."
|
||||
psql -h 127.0.0.1 -p 11000 -U windmill -d windmill < /tmp/windmill-db-dump.sql
|
||||
psql -h /tmp -U windmill -d windmill < "$DUMP_FILE"
|
||||
|
||||
# Stop the temporary postgres cleanly
|
||||
pg_ctl -D "$PGDATA" stop -m smart -t 1800
|
||||
wait "$TEMP_PG_PID" 2>/dev/null || true
|
||||
unset PGPORT
|
||||
|
||||
set +ex
|
||||
|
||||
# Remove sentinel files
|
||||
rm -f "$PGDATA/import.failed" "$IMPORT_FAILED_TMP"
|
||||
# Remove the sentinel only after the restore has fully completed
|
||||
rm "$DUMP_DIR/import.failed"
|
||||
echo "PostgreSQL upgrade to $CURRENT_PG_MAJOR complete."
|
||||
fi
|
||||
fi
|
||||
@@ -167,17 +165,30 @@ fi
|
||||
|
||||
# ── Dump database and shut down on container stop ────────────────────────────
|
||||
do_database_dump() {
|
||||
# pg_dump uses a consistent transaction snapshot, so it is safe to run
|
||||
# while Windmill is still connected — no need to stop it beforehand.
|
||||
|
||||
# Verify postgres is still accepting connections before attempting the dump.
|
||||
if ! pg_isready -h /var/run/postgresql -U windmill -q; then
|
||||
echo "WARNING: postgres is not ready; skipping dump."
|
||||
kill "$SUPERVISORD_PID" 2>/dev/null || true
|
||||
wait "$SUPERVISORD_PID" 2>/dev/null || true
|
||||
return
|
||||
fi
|
||||
|
||||
set -x
|
||||
touch "$PGDATA/export.failed"
|
||||
touch "$DUMP_DIR/export.failed"
|
||||
rm -f "$DUMP_FILE.temp"
|
||||
if pg_dump -h /var/run/postgresql -U windmill windmill > "$DUMP_FILE.temp"; then
|
||||
mv "$DUMP_FILE.temp" "$DUMP_FILE"
|
||||
rm "$PGDATA/export.failed"
|
||||
rm "$DUMP_DIR/export.failed"
|
||||
echo "Database dump successful!"
|
||||
else
|
||||
rm -f "$DUMP_FILE.temp"
|
||||
echo "Database dump unsuccessful!"
|
||||
fi
|
||||
set +x
|
||||
|
||||
# Stop supervisord (which stops postgres and windmill)
|
||||
kill "$SUPERVISORD_PID" 2>/dev/null || true
|
||||
wait "$SUPERVISORD_PID" 2>/dev/null || true
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Wait for PostgreSQL to accept connections
|
||||
until pg_isready -h localhost -q 2>/dev/null; do
|
||||
until pg_isready -h /var/run/postgresql -q 2>/dev/null; do
|
||||
echo "Waiting for PostgreSQL to be ready..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
@@ -178,7 +178,8 @@
|
||||
"FULLTEXTSEARCH_PASSWORD",
|
||||
"IMAGINARY_SECRET",
|
||||
"WHITEBOARD_SECRET",
|
||||
"HP_SHARED_KEY"
|
||||
"HP_SHARED_KEY",
|
||||
"WINDMILL_SECRET"
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
@@ -268,7 +269,8 @@
|
||||
"HARP_ENABLED=%HARP_ENABLED%",
|
||||
"HP_SHARED_KEY=%HP_SHARED_KEY%",
|
||||
"WINDMILL_ENABLED=%WINDMILL_ENABLED%",
|
||||
"WINDMILL_HOST=nextcloud-aio-windmill"
|
||||
"WINDMILL_HOST=nextcloud-aio-windmill",
|
||||
"WINDMILL_SECRET=%WINDMILL_SECRET%"
|
||||
],
|
||||
"stop_grace_period": 600,
|
||||
"restart": "unless-stopped",
|
||||
@@ -980,7 +982,11 @@
|
||||
"NUM_WORKERS=1",
|
||||
"MODE=standalone",
|
||||
"DISABLE_NSJAIL=true",
|
||||
"DATABASE_URL=postgresql://windmill@localhost/windmill?host=/var/run/postgresql"
|
||||
"DATABASE_URL=postgresql://windmill@localhost/windmill?host=/var/run/postgresql",
|
||||
"SUPERADMIN_SECRET=%WINDMILL_SECRET%"
|
||||
],
|
||||
"secrets": [
|
||||
"WINDMILL_SECRET"
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
@@ -989,13 +995,19 @@
|
||||
"writeable": true
|
||||
},
|
||||
{
|
||||
"source": "nextcloud_aio_windmill",
|
||||
"source": "nextcloud_aio_windmill_dump",
|
||||
"destination": "/var/lib/windmill-dump",
|
||||
"writeable": true
|
||||
},
|
||||
{
|
||||
"source": "nextcloud_aio_windmill_cache",
|
||||
"destination": "/tmp/windmill/cache",
|
||||
"writeable": true
|
||||
}
|
||||
],
|
||||
"backup_volumes": [
|
||||
"nextcloud_aio_windmill_db"
|
||||
"nextcloud_aio_windmill_db",
|
||||
"nextcloud_aio_windmill_dump"
|
||||
],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": 1800,
|
||||
|
||||
Reference in New Issue
Block a user