diff --git a/.docker/scripts/nextcloud-entrypoint.sh b/.docker/scripts/nextcloud-entrypoint.sh index 29ea2d1..693f015 100644 --- a/.docker/scripts/nextcloud-entrypoint.sh +++ b/.docker/scripts/nextcloud-entrypoint.sh @@ -145,10 +145,19 @@ if ! occ status | grep -q 'installed: true'; then fi if [[ -n "${NEXTCLOUD_HOST:-}" ]]; then - echo "🔧 Setting trusted domain and overwritehost to ${NEXTCLOUD_HOST} ..." + nextcloud_protocol="${NEXTCLOUD_PROTOCOL:-https}" + case "${nextcloud_protocol}" in + http|https) ;; + *) + echo "❌ Unsupported NEXTCLOUD_PROTOCOL: ${nextcloud_protocol}" >&2 + exit 1 + ;; + esac + + echo "🔧 Setting canonical Nextcloud URL to ${nextcloud_protocol}://${NEXTCLOUD_HOST} ..." occ config:system:set trusted_domains 1 --value "${NEXTCLOUD_HOST}" occ config:system:set overwritehost --value "${NEXTCLOUD_HOST}" - occ config:system:set overwriteprotocol --value https + occ config:system:set overwriteprotocol --value "${nextcloud_protocol}" fi # Run cron diff --git a/.docker/scripts/proxy/services.sh b/.docker/scripts/proxy/services.sh index a2494b8..4a7724e 100644 --- a/.docker/scripts/proxy/services.sh +++ b/.docker/scripts/proxy/services.sh @@ -39,7 +39,7 @@ disconnect_proxy_from_project_network() { report_environment_ready() { set -- \ - -e ENV_NEXTCLOUD_URL="https://${PROJECT_NAME:-}.localhost" \ + -e ENV_NEXTCLOUD_URL="${NEXTCLOUD_PROTOCOL:-https}://${NEXTCLOUD_HOST:-${PROJECT_NAME:-}.localhost}" \ -e ENV_ADMIN_USER="${NEXTCLOUD_ADMIN_USER:-admin}" \ -e ENV_ADMIN_PASSWORD="${NEXTCLOUD_ADMIN_PASSWORD:-admin}" \ -e ENV_NEXTCLOUD_BRANCH="${VERSION_NEXTCLOUD:-master}" diff --git a/dev-worker b/dev-worker index 2c0f2fc..2c6273b 100644 --- a/dev-worker +++ b/dev-worker @@ -25,6 +25,8 @@ Environment: DB_SQL_MODE= Optional global SQL mode for MySQL-compatible backends PHP_VERSION= Existing PHP image selector VERSION_NEXTCLOUD= Existing Nextcloud ref selector + NEXTCLOUD_HOST= Public hostname (default: .localhost) + NEXTCLOUD_PROTOCOL=http|https Public protocol (default: https) NCDD_WORKSPACE= Optional directory mounted as /var/www/html/apps-extra WORKER_READY_TIMEOUT=180 Seconds to wait for a clean installation EOF @@ -57,7 +59,6 @@ esac repo_root="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" db_type="${DB_TYPE:-mysql}" workspace="${NCDD_WORKSPACE:-}" - if [ -n "$workspace" ]; then [ -d "$workspace" ] || { echo "NCDD_WORKSPACE is not a directory: $workspace" >&2 @@ -111,7 +112,8 @@ compose() { --file "$repo_root/docker-compose.yml" \ --file "$repo_root/.docker/workspace.yml" "$@" else - docker compose --project-directory "$repo_root" --file "$repo_root/docker-compose.yml" "$@" + docker compose --project-directory "$repo_root" \ + --file "$repo_root/docker-compose.yml" "$@" fi } @@ -193,7 +195,7 @@ case "$command" in compose exec -T nextcloud occ status ;; urls) - printf 'Nextcloud: https://%s.localhost\n' "$COMPOSE_PROJECT_NAME" + printf 'Nextcloud: %s://%s\n' "${NEXTCLOUD_PROTOCOL:-https}" "${NEXTCLOUD_HOST:-$COMPOSE_PROJECT_NAME.localhost}" printf 'Mailpit: https://%s-mailpit.localhost\n' "$COMPOSE_PROJECT_NAME" ;; db-exec) diff --git a/docker-compose.yml b/docker-compose.yml index 99d1054..131043b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -37,7 +37,8 @@ services: - MAIL_SMTPPORT=${MAIL_SMTPPORT:-1025} - MAIL_SMTPHOST=${MAIL_SMTPHOST:-mailpit} - VERSION_NEXTCLOUD=${VERSION_NEXTCLOUD:-master} - - NEXTCLOUD_HOST=${COMPOSE_PROJECT_NAME}.localhost + - NEXTCLOUD_HOST=${NEXTCLOUD_HOST:-${COMPOSE_PROJECT_NAME}.localhost} + - NEXTCLOUD_PROTOCOL=${NEXTCLOUD_PROTOCOL:-https} - AUTOINSTALL=${AUTOINSTALL:-1} - XDEBUG_CONFIG - XDEBUG_MODE @@ -57,9 +58,9 @@ services: - ${WORKER_VOLUMES_DIR:-./volumes}/nginx/includes:/etc/nginx/conf.d/includes/ - ${WORKER_VOLUMES_DIR:-./volumes}/nginx/certs:/certs environment: - - VIRTUAL_HOST=${COMPOSE_PROJECT_NAME}.localhost + - VIRTUAL_HOST=${NEXTCLOUD_HOST:-${COMPOSE_PROJECT_NAME}.localhost} - VIRTUAL_PORT=80 - - SELF_SIGNED_HOST=${COMPOSE_PROJECT_NAME}.localhost + - SELF_SIGNED_HOST=${NEXTCLOUD_HOST:-${COMPOSE_PROJECT_NAME}.localhost} proxy-coordinator: image: docker:29.8.1-cli@sha256:018edbc908e08fcc9dbf029c812c34251e9b4719e6f71ca0e5eae2a987d014ca entrypoint: ["/bin/sh", "/usr/local/lib/librecode/proxy-coordinator.sh"] @@ -77,6 +78,8 @@ services: - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER:-admin} - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD:-admin} - VERSION_NEXTCLOUD=${VERSION_NEXTCLOUD:-master} + - NEXTCLOUD_HOST=${NEXTCLOUD_HOST:-${COMPOSE_PROJECT_NAME}.localhost} + - NEXTCLOUD_PROTOCOL=${NEXTCLOUD_PROTOCOL:-https} healthcheck: test: ["CMD-SHELL", "test -f /tmp/librecode-proxy-ready"] interval: 1s @@ -120,7 +123,7 @@ services: - ${WORKER_VOLUMES_DIR:-./volumes}/nextcloud:/var/www/html working_dir: /var/www/html environment: - - PLAYWRIGHT_BASE_URL=${PLAYWRIGHT_BASE_URL:-https://${COMPOSE_PROJECT_NAME}.localhost} + - PLAYWRIGHT_BASE_URL=${PLAYWRIGHT_BASE_URL:-https://${NEXTCLOUD_HOST:-${COMPOSE_PROJECT_NAME}.localhost}} - NODE_ENV=test - CI=${CI:-false} - VIRTUAL_HOST=${COMPOSE_PROJECT_NAME}-playwright.localhost diff --git a/docs/advanced-setup.md b/docs/advanced-setup.md index dbddf12..410ff6f 100644 --- a/docs/advanced-setup.md +++ b/docs/advanced-setup.md @@ -114,6 +114,28 @@ docker compose \ up ``` +## Public Nextcloud URL + +By default, each environment is available through the shared proxy at +`https://.localhost`. + +Remote development platforms may expose the proxy through a different public +hostname. Set `NEXTCLOUD_HOST` and, when needed, `NEXTCLOUD_PROTOCOL` so the +proxy routing and Nextcloud canonical URL stay consistent: + +```bash +NEXTCLOUD_HOST=example.dev NEXTCLOUD_PROTOCOL=https docker compose up +``` + +These values configure the routed host, Nextcloud `trusted_domains`, +`overwritehost`, `overwriteprotocol`, diagnostics and the default Playwright +base URL. + +For remote platforms, forward the shared proxy's HTTPS port and set the public +hostname to the hostname assigned by that platform. The proxy remains the only +HTTP entry point; individual workers do not publish their nginx service on +separate host ports. + ## Multiple environments Multiple checkouts can run at the same time. Each checkout keeps its own Compose network, while the shared development proxy connects to the active project networks. diff --git a/tests/worker/contract.bats b/tests/worker/contract.bats index 02181f0..b1ab07c 100644 --- a/tests/worker/contract.bats +++ b/tests/worker/contract.bats @@ -102,3 +102,13 @@ setup() { workflow="$REPO_ROOT/.github/workflows/worker-tests.yml" ! grep -Eq "matrix\.mariadb ==|MARIADB_VERSION\" = \"[0-9]|maria-[0-9]+-[0-9]+" "$workflow" } + + +@test "worker accepts an explicit public Nextcloud URL" { + run env DB_TYPE=sqlite NEXTCLOUD_HOST=example.test NEXTCLOUD_PROTOCOL=https sh "$WORKER" public-url config + [ "$status" -eq 0 ] + [[ "$output" == *"NEXTCLOUD_HOST: example.test"* ]] + [[ "$output" == *"NEXTCLOUD_PROTOCOL: https"* ]] + [[ "$output" == *"VIRTUAL_HOST: example.test"* ]] +} +