diff --git a/.env.windows-docker-desktop.example b/.env.windows-docker-desktop.example deleted file mode 100644 index e97249505d..0000000000 --- a/.env.windows-docker-desktop.example +++ /dev/null @@ -1,14 +0,0 @@ -IS_WINDOWS_DOCKER_DESKTOP=true - -APP_ID=coolify-windows-docker-desktop -APP_NAME=Coolify -APP_KEY=base64:ssTlCmrIE/q7whnKMvT6DwURikg69COzGsAwFVROm80= - -DB_USERNAME=coolify -DB_PASSWORD=coolify -REDIS_PASSWORD=coolify - -PUSHER_APP_ID=coolify -PUSHER_APP_KEY=coolify -PUSHER_APP_SECRET=coolify -PUSHER_BACKEND_PORT=6001 diff --git a/.github/workflows/coolify-testing-host.yml b/.github/workflows/coolify-testing-host.yml deleted file mode 100644 index 7f5fa156fb..0000000000 --- a/.github/workflows/coolify-testing-host.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: Coolify Testing Host - -on: - push: - branches: [ "next" ] - paths: - - .github/workflows/coolify-testing-host.yml - - docker/testing-host/Dockerfile - -permissions: - contents: read - -env: - DOCKER_REGISTRY: docker.io - IMAGE_NAME: "coollabsio/coolify-testing-host" - -jobs: - build-push: - strategy: - matrix: - include: - - arch: amd64 - platform: linux/amd64 - runner: ubuntu-24.04 - - arch: aarch64 - platform: linux/aarch64 - runner: ubuntu-24.04-arm - runs-on: ${{ matrix.runner }} - steps: - - uses: actions/checkout@v5 - with: - persist-credentials: false - - - name: Login to ${{ env.DOCKER_REGISTRY }} - uses: docker/login-action@v3 - with: - registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and Push Image (${{ matrix.arch }}) - uses: docker/build-push-action@v6 - with: - context: . - file: docker/testing-host/Dockerfile - platforms: ${{ matrix.platform }} - push: true - tags: | - ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-${{ matrix.arch }} - labels: | - coolify.managed=true - - merge-manifest: - runs-on: ubuntu-24.04 - needs: build-push - steps: - - uses: actions/checkout@v5 - with: - persist-credentials: false - - - uses: docker/setup-buildx-action@v3 - - - name: Login to ${{ env.DOCKER_REGISTRY }} - uses: docker/login-action@v3 - with: - registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} - run: | - docker buildx imagetools create \ - ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-amd64 \ - ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 \ - --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest - - - uses: sarisia/actions-status-discord@v1 - if: always() - with: - webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index cd63d3502f..92e8cf88a3 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -51,7 +51,7 @@ class Kernel extends ConsoleKernel $this->scheduleInstance->call(fn () => app(CleanupStaleMultiplexedConnections::class)->handle()) ->name('cleanup:ssh-mux') ->hourly() - ->when(fn () => config('constants.ssh.mux_enabled') && ! config('constants.coolify.is_windows_docker_desktop')); + ->when(fn () => config('constants.ssh.mux_enabled')); // Every cloud node reads its own versions.json, so each node refreshes it (no onOneServer). $this->scheduleInstance->call(fn () => refresh_versions_file()) ->name('versions:refresh-local') diff --git a/app/Helpers/SshMultiplexingHelper.php b/app/Helpers/SshMultiplexingHelper.php index f873446407..ffa3c96310 100644 --- a/app/Helpers/SshMultiplexingHelper.php +++ b/app/Helpers/SshMultiplexingHelper.php @@ -463,7 +463,7 @@ class SshMultiplexingHelper private static function isMultiplexingEnabled(): bool { - return config('constants.ssh.mux_enabled') && ! config('constants.coolify.is_windows_docker_desktop'); + return config('constants.ssh.mux_enabled'); } private static function validateSshKey(PrivateKey $privateKey): void diff --git a/config/constants.php b/config/constants.php index 38c7ee287a..4217921652 100644 --- a/config/constants.php +++ b/config/constants.php @@ -22,7 +22,6 @@ return [ 'dev_seed_ip' => env('DEV_SEED_IP') ?: '127.0.0.1', 'registry_url' => env('REGISTRY_URL', 'docker.io'), 'helper_image' => env('HELPER_IMAGE', env('REGISTRY_URL', 'docker.io').'/coollabsio/coolify-helper'), - 'is_windows_docker_desktop' => env('IS_WINDOWS_DOCKER_DESKTOP', false), 'cdn_url' => env('CDN_URL', 'https://cdn.coollabs.io'), 'versions_url' => env('VERSIONS_URL', env('CDN_URL', 'https://cdn.coollabs.io').'/coolify/versions.json'), 'upgrade_script_url' => env('UPGRADE_SCRIPT_URL', env('CDN_URL', 'https://cdn.coollabs.io').'/coolify/upgrade.sh'), diff --git a/database/seeders/ProductionSeeder.php b/database/seeders/ProductionSeeder.php index f1c1848b53..324b209d94 100644 --- a/database/seeders/ProductionSeeder.php +++ b/database/seeders/ProductionSeeder.php @@ -82,7 +82,7 @@ class ProductionSeeder extends Seeder ]); } - if (! isCloud() && config('constants.coolify.is_windows_docker_desktop') == false) { + if (! isCloud()) { $coolify_key_name = '@host.docker.internal'; $ssh_keys_directory = Storage::disk('ssh-keys')->files(); $coolify_key = collect($ssh_keys_directory)->firstWhere(fn ($item) => str($item)->contains($coolify_key_name)); @@ -156,63 +156,6 @@ class ProductionSeeder extends Seeder } } - if (config('constants.coolify.is_windows_docker_desktop')) { - PrivateKey::updateOrCreate( - [ - 'id' => 0, - 'team_id' => 0, - ], - [ - 'name' => 'Testing-host', - 'description' => 'This is a a docker container with SSH access', - 'private_key' => '-----BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW -QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk -hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA -AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV -uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== ------END OPENSSH PRIVATE KEY----- -', - ] - ); - if (Server::find(0) == null) { - $server_details = [ - 'id' => 0, - 'uuid' => 'coolify-testing-host', - 'name' => 'localhost', - 'description' => "This is the server where Coolify is running on. Don't delete this!", - 'user' => 'root', - 'ip' => 'coolify-testing-host', - 'team_id' => 0, - 'private_key_id' => 0, - ]; - $server_details['proxy'] = ServerMetadata::from([ - 'type' => ProxyTypes::TRAEFIK->value, - 'status' => ProxyStatus::EXITED->value, - 'last_saved_settings' => null, - 'last_applied_settings' => null, - ]); - $server = Server::create($server_details); - $server->settings->is_reachable = true; - $server->settings->is_usable = true; - $server->settings->save(); - } else { - $server = Server::find(0); - $server->settings->is_reachable = true; - $server->settings->is_usable = true; - $server->settings->save(); - } - - if (StandaloneDocker::find(0) == null) { - StandaloneDocker::create([ - 'id' => 0, - 'name' => 'localhost-coolify', - 'network' => 'coolify', - 'server_id' => 0, - ]); - } - } - get_public_ips(); $this->call(OauthSettingSeeder::class); diff --git a/docker-compose.windows.yml b/docker-compose.windows.yml deleted file mode 100644 index 347495424f..0000000000 --- a/docker-compose.windows.yml +++ /dev/null @@ -1,110 +0,0 @@ -services: - coolify-testing-host: - init: true - image: "docker.io/coollabsio/coolify-testing-host:latest" - pull_policy: always - container_name: coolify-testing-host - volumes: - - //var/run/docker.sock://var/run/docker.sock - - ./:/data/coolify - coolify: - image: "docker.io/coollabsio/coolify:latest" - pull_policy: always - container_name: coolify - restart: always - working_dir: /var/www/html - extra_hosts: - - 'host.docker.internal:host-gateway' - volumes: - - type: bind - source: .env - target: /var/www/html/.env - read_only: true - - ./ssh:/var/www/html/storage/app/ssh - - ./applications:/var/www/html/storage/app/applications - - ./databases:/var/www/html/storage/app/databases - - ./services:/var/www/html/storage/app/services - - ./backups:/var/www/html/storage/app/backups - - ./images:/var/www/html/storage/app/images - env_file: - - .env - environment: - - APP_ID - - APP_ENV=production - - APP_NAME - - APP_KEY - - DB_PASSWORD - - REDIS_PASSWORD - - SSL_MODE=off - - PHP_PM_CONTROL=dynamic - - PHP_PM_START_SERVERS=1 - - PHP_PM_MIN_SPARE_SERVERS=1 - - PHP_PM_MAX_SPARE_SERVERS=10 - - PUSHER_APP_ID - - PUSHER_APP_KEY - - PUSHER_APP_SECRET - - PUSHER_PORT - - PUSHER_BACKEND_PORT - - AUTOUPDATE=true - - SELF_HOSTED=true - - SSH_MUX_ENABLED=false - - IS_WINDOWS_DOCKER_DESKTOP=true - ports: - - "${APP_PORT:-8000}:8080" - - "${REVERB_PORT:-${SOKETI_PORT:-6001}}:6001" - - "6002:6002" - expose: - - "${APP_PORT:-8000}" - - "6001" - - "6002" - healthcheck: - test: curl --fail http://localhost:8080/api/health && curl --fail http://localhost:${PUSHER_BACKEND_PORT:-6001}/up || exit 1 - interval: 5s - retries: 10 - timeout: 2s - depends_on: - postgres: - condition: service_healthy - redis: - condition: service_healthy - postgres: - image: postgres:15-alpine - pull_policy: always - container_name: coolify-db - restart: always - env_file: - - .env - volumes: - - coolify-db:/var/lib/postgresql/data - environment: - POSTGRES_USER: "${DB_USERNAME}" - POSTGRES_PASSWORD: "${DB_PASSWORD}" - POSTGRES_DB: "${DB_DATABASE:-coolify}" - healthcheck: - test: [ "CMD-SHELL", "pg_isready -U ${DB_USERNAME}", "-d", "${DB_DATABASE:-coolify}" ] - interval: 5s - retries: 10 - timeout: 2s - redis: - image: redis:7-alpine - pull_policy: always - container_name: coolify-redis - restart: always - command: redis-server --save 20 1 --loglevel warning --requirepass ${REDIS_PASSWORD} - env_file: - - .env - environment: - REDIS_PASSWORD: "${REDIS_PASSWORD}" - volumes: - - coolify-redis:/data - healthcheck: - test: redis-cli ping - interval: 5s - retries: 10 - timeout: 2s - -volumes: - coolify-db: - name: coolify-db - coolify-redis: - name: coolify-redis diff --git a/tests/Feature/PersistentImageStorageTest.php b/tests/Feature/PersistentImageStorageTest.php index 1439f00302..e3e94b8e17 100644 --- a/tests/Feature/PersistentImageStorageTest.php +++ b/tests/Feature/PersistentImageStorageTest.php @@ -16,11 +16,6 @@ it('persists images in stable and nightly production compose files', function (s 'stable' => 'docker-compose.prod.yml', ]); -it('persists images in the Windows compose file', function () { - expect(file_get_contents(base_path('docker-compose.windows.yml'))) - ->toContain('./images:/var/www/html/storage/app/images'); -}); - it('creates the persistent image directory during installation and upgrades', function (string $script) { expect(file_get_contents(base_path($script))) ->toContain('/data/coolify/images'); diff --git a/tests/Feature/ReverbAndTerminalPackagingTest.php b/tests/Feature/ReverbAndTerminalPackagingTest.php index ef8f39684c..185108a66a 100644 --- a/tests/Feature/ReverbAndTerminalPackagingTest.php +++ b/tests/Feature/ReverbAndTerminalPackagingTest.php @@ -81,7 +81,6 @@ it('includes Reverb but not the terminal server in the Coolify container healthc ->not->toContain('6002/ready'); })->with([ 'production compose' => ['docker-compose.prod.yml'], - 'windows compose' => ['docker-compose.windows.yml'], ]); it('removes the legacy realtime container during upgrades', function (string $script) { @@ -142,7 +141,6 @@ it('removes the dedicated realtime service from bundled compose files', function 'development compose' => ['docker-compose.dev.yml', true], 'maxio development compose' => ['docker-compose-maxio.dev.yml', true], 'multi-instance development compose' => ['docker-compose.dev-multi.yml', true], - 'windows compose' => ['docker-compose.windows.yml', true], ]); it('keeps the internal Reverb listen port separate from the public Pusher port', function () { @@ -184,11 +182,9 @@ it('proxies Reverb and terminal websocket traffic to the Coolify app container', it('uses Pusher environment keys for self-hosted Reverb compatibility', function () { $files = [ '.env.production', - '.env.windows-docker-desktop.example', 'docker-compose.prod.yml', 'docker-compose.dev.yml', 'docker-compose-maxio.dev.yml', - 'docker-compose.windows.yml', 'scripts/install.sh', 'scripts/upgrade.sh', ]; @@ -204,9 +200,6 @@ it('keeps the public websocket port adaptive and configures only the internal Re expect(file_get_contents(base_path('.env.production'))) ->not->toContain('PUSHER_PORT=') ->not->toContain('PUSHER_BACKEND_PORT=') - ->and(file_get_contents(base_path('.env.windows-docker-desktop.example'))) - ->not->toContain('PUSHER_PORT=') - ->toContain('PUSHER_BACKEND_PORT=6001') ->and(file_get_contents(base_path('scripts/install.sh'))) ->not->toContain('update_env_var "PUSHER_PORT"') ->toContain('update_env_var "PUSHER_BACKEND_PORT" "6001"') @@ -221,7 +214,6 @@ it('does not use the browser websocket port as the Docker host port', function ( ->not->toContain('"${PUSHER_PORT:-6001}:6001"'); })->with([ 'production compose' => ['docker-compose.prod.yml'], - 'windows compose' => ['docker-compose.windows.yml'], ]); it('preserves existing public websocket port overrides during install and upgrade', function (string $script) { @@ -264,15 +256,6 @@ it('keeps 4.3.23 realtime setups working with the production compose files', fun 'production compose' => ['docker-compose.prod.yml'], ]); -it('keeps TERMINAL_PORT browser-only in the Windows compose files', function (string $composeFile) { - $coolify = Yaml::parseFile(base_path($composeFile))['services']['coolify']; - - expect($coolify['ports'])->toContain('6002:6002') - ->and(implode("\n", [...$coolify['ports'], ...$coolify['expose']]))->not->toContain('TERMINAL_PORT'); -})->with([ - 'windows compose' => ['docker-compose.windows.yml'], -]); - it('resolves the browser websocket port like 4.3.23', function (string $pageUrl, ?string $pusherPort, ?string $expectedPort) { config()->set('constants.pusher.port', $pusherPort); RequestFacade::swap(Request::create($pageUrl)); diff --git a/tests/Unit/ProductionImageWorkflowTest.php b/tests/Unit/ProductionImageWorkflowTest.php index 9885faa5ec..5f6e12b206 100644 --- a/tests/Unit/ProductionImageWorkflowTest.php +++ b/tests/Unit/ProductionImageWorkflowTest.php @@ -13,21 +13,10 @@ it('builds the development helper image from the coolify-helper repository', fun expect(file_get_contents(dirname(__DIR__, 2)."/{$file}"))->toContain('https://github.com/coollabsio/coolify-helper.git#main:src'); })->with(['scripts/dev-helper', 'docker-compose.dev.yml', 'docker-compose.dev-multi.yml']); -it('publishes the testing host only to Docker Hub', function () { - $workflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/coolify-testing-host.yml'); - $cleanupWorkflow = file_get_contents(dirname(__DIR__, 2).'/.github/workflows/cleanup-ghcr-untagged.yml'); - $windowsCompose = file_get_contents(dirname(__DIR__, 2).'/docker-compose.windows.yml'); +it('builds the testing host only for local development', function () { $developmentCompose = file_get_contents(dirname(__DIR__, 2).'/docker-compose.dev.yml'); - expect($workflow) - ->toContain('DOCKER_REGISTRY: docker.io') - ->toContain('IMAGE_NAME: "coollabsio/coolify-testing-host"') - ->toContain('docker/testing-host/Dockerfile') - ->not->toContain('ghcr.io') - ->not->toContain('GITHUB_REGISTRY') - ->and($cleanupWorkflow)->not->toContain('coolify-testing-host') - ->and($windowsCompose)->toContain('docker.io/coollabsio/coolify-testing-host:latest') - ->and($developmentCompose)->toContain('image: coolify-testing-host:dev') + expect($developmentCompose)->toContain('image: coolify-testing-host:dev') ->toContain('dockerfile: ./docker/testing-host/Dockerfile'); });