diff --git a/.env.development.example b/.env.development.example index ba0213f58..3023a21a6 100644 --- a/.env.development.example +++ b/.env.development.example @@ -6,13 +6,7 @@ APP_KEY= APP_URL=http://localhost APP_PORT=8000 APP_DEBUG=true -MUX_ENABLED=false - -# Enable Laravel Telescope for debugging -TELESCOPE_ENABLED=false - -# Selenium Driver URL for Dusk -DUSK_DRIVER_URL=http://selenium:4444 +SSH_MUX_ENABLED=false # PostgreSQL Database Configuration DB_DATABASE=coolify @@ -27,6 +21,16 @@ RAY_ENABLED=false # Set custom ray port RAY_PORT= +# Clockwork Configuration +CLOCKWORK_ENABLED=false +CLOCKWORK_QUEUE_COLLECT=true + +# Enable Laravel Telescope for debugging +TELESCOPE_ENABLED=false + +# Selenium Driver URL for Dusk +DUSK_DRIVER_URL=http://selenium:4444 + # Special Keys for Andras # For cache purging BUNNY_API_KEY= diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index cf2fae8f3..d7a680170 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -16,6 +16,12 @@ env: jobs: amd64: runs-on: ubuntu-latest + permissions: + contents: read + packages: write + attestations: write + id-token: write + actions: write steps: - uses: actions/checkout@v4 - name: Login to ghcr.io @@ -37,6 +43,9 @@ jobs: permissions: contents: read packages: write + attestations: write + id-token: write + actions: write steps: - uses: actions/checkout@v4 - name: Login to ghcr.io @@ -58,6 +67,9 @@ jobs: permissions: contents: read packages: write + attestations: write + id-token: write + actions: write needs: [amd64, aarch64] steps: - name: Checkout diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9618bfae5..590360ddb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,17 +1,27 @@ -# Contributing +# Contributing to Coolify > "First, thanks for considering contributing to my project. It really means a lot!" - [@andrasbacsai](https://github.com/andrasbacsai) You can ask for guidance anytime on our [Discord server](https://coollabs.io/discord) in the `#contribute` channel. +## Table of Contents -## Code Contribution +1. [Setup Development Environment](#1-setup-development-environment) +2. [Verify Installation](#2-verify-installation-optional) +3. [Fork and Setup Local Repository](#3-fork-and-setup-local-repository) +4. [Set up Environment Variables](#4-set-up-environment-variables) +5. [Start Coolify](#5-start-coolify) +6. [Start Development](#6-start-development) +7. [Development Notes](#7-development-notes) +8. [Create a Pull Request](#8-create-a-pull-request) +9. [Additional Contribution Guidelines](#additional-contribution-guidelines) -## 1. Setup your development environment +## 1. Setup Development Environment Follow the steps below for your operating system: -### Windows +
+Windows 1. Install `docker-ce`, Docker Desktop (or similar): - Docker CE (recommended): @@ -25,7 +35,10 @@ Follow the steps below for your operating system: 2. Install Spin: - Follow the instructions to install Spin on Windows from the [Spin documentation](https://serversideup.net/open-source/spin/docs/installation/install-windows#download-and-install-spin-into-wsl2) -### MacOS +
+ +
+MacOS 1. Install Orbstack, Docker Desktop (or similar): - Orbstack (recommended, as it is a faster and lighter alternative to Docker Desktop): @@ -36,7 +49,10 @@ Follow the steps below for your operating system: 2. Install Spin: - Follow the instructions to install Spin on MacOS from the [Spin documentation](https://serversideup.net/open-source/spin/docs/installation/install-macos/#download-and-install-spin) -### Linux +
+ +
+Linux 1. Install Docker Engine, Docker Desktop (or similar): - Docker Engine (recommended, as there is no VM overhead): @@ -47,8 +63,9 @@ Follow the steps below for your operating system: 2. Install Spin: - Follow the instructions to install Spin on Linux from the [Spin documentation](https://serversideup.net/open-source/spin/docs/installation/install-linux#configure-docker-permissions) +
-## 2. Verify installation (optional) +## 2. Verify Installation (Optional) After installing Docker (or Orbstack) and Spin, verify the installation: @@ -60,25 +77,20 @@ After installing Docker (or Orbstack) and Spin, verify the installation: ``` You should see version information for both Docker and Spin. - -## 3. Fork the Coolify repository and setup your local repository +## 3. Fork and Setup Local Repository 1. Fork the [Coolify](https://github.com/coollabsio/coolify) repository to your GitHub account. -2. Install a code editor on your machine (below are some popular choices, choose one): +2. Install a code editor on your machine (choose one): - - Visual Studio Code (recommended free): - - Windows/macOS/Linux: Download and install from [https://code.visualstudio.com/download](https://code.visualstudio.com/download) - - - Cursor (recommended but paid for getting the full benefits): - - Windows/macOS/Linux: Download and install from [https://www.cursor.com/](https://www.cursor.com/) - - - Zed (very fast code editor): - - macOS/Linux: Download and install from [https://zed.dev/download](https://zed.dev/download) - - Windows: Not available yet + | Editor | Platform | Download Link | + |--------|----------|---------------| + | Visual Studio Code (recommended free) | Windows/macOS/Linux | [Download](https://code.visualstudio.com/download) | + | Cursor (recommended but paid) | Windows/macOS/Linux | [Download](https://www.cursor.com/) | + | Zed (very fast) | macOS/Linux | [Download](https://zed.dev/download) | 3. Clone the Coolify Repository from your fork to your local machine - - Use `git clone` in the command line + - Use `git clone` in the command line, or - Use GitHub Desktop (recommended): - Download and install from [https://desktop.github.com/](https://desktop.github.com/) - Open GitHub Desktop and login with your GitHub account @@ -86,37 +98,32 @@ After installing Docker (or Orbstack) and Spin, verify the installation: 4. Open the cloned Coolify Repository in your chosen code editor. - ## 4. Set up Environment Variables 1. In the Code Editor, locate the `.env.development.example` file in the root directory of your local Coolify repository. - 2. Duplicate the `.env.development.example` file and rename the copy to `.env`. - 3. Open the new `.env` file and review its contents. Adjust any environment variables as needed for your development setup. - 4. If you encounter errors during database migrations, update the database connection settings in your `.env` file. Use the IP address or hostname of your PostgreSQL database container. You can find this information by running `docker ps` after executing `spin up`. - 5. Save the changes to your `.env` file. - ## 5. Start Coolify 1. Open a terminal in the local Coolify directory. - 2. Run the following command in the terminal (leave that terminal open): - ``` + ```bash spin up ``` - Note: You may see some errors, but don't worry; this is expected. + +> [!NOTE] +> You may see some errors, but don't worry; this is expected. 3. If you encounter permission errors, especially on macOS, use: - ``` + ```bash sudo spin up ``` -Note: If you change environment variables afterwards or anything seems broken, press Ctrl + C to stop the process and run `spin up` again. - +> [!NOTE] +> If you change environment variables afterwards or anything seems broken, press Ctrl + C to stop the process and run `spin up` again. ## 6. Start Development @@ -126,15 +133,17 @@ Note: If you change environment variables afterwards or anything seems broken, p - Password: `password` 2. Additional development tools: - - Laravel Horizon (scheduler): `http://localhost:8000/horizon` - Note: Only accessible when logged in as root user - - Mailpit (email catcher): `http://localhost:8025` - - Telescope (debugging tool): `http://localhost:8000/telescope` - Note: Disabled by default (so the database is not overloaded), enable by adding the following environment variable to your `.env` file: - ```env - TELESCOPE_ENABLED=true - ``` + | Tool | URL | Note | + |------|-----|------| + | Laravel Horizon (scheduler) | `http://localhost:8000/horizon` | Only accessible when logged in as root user | + | Mailpit (email catcher) | `http://localhost:8025` | | + | Telescope (debugging tool) | `http://localhost:8000/telescope` | Disabled by default | +> [!NOTE] +> To enable Telescope, add the following to your `.env` file: +> ```env +> TELESCOPE_ENABLED=true +> ``` ## 7. Development Notes @@ -150,18 +159,12 @@ When working on Coolify, keep the following in mind: docker exec -it coolify php artisan migrate:fresh --seed ``` -3. **Troubleshooting**: If you encounter unexpected behavior, ensure your database is up-to-date with the latest migrations and if possible reset the development setup to eliminate any envrionement specific issues. +3. **Troubleshooting**: If you encounter unexpected behavior, ensure your database is up-to-date with the latest migrations and if possible reset the development setup to eliminate any environment-specific issues. -Remember, forgetting to migrate the database can cause problems, so make it a habit to run migrations after pulling changes or switching branches. +> [!IMPORTANT] +> Forgetting to migrate the database can cause problems, so make it a habit to run migrations after pulling changes or switching branches. - -## 8. Contributing a New Service - -To add a new service to Coolify, please refer to our documentation: -[Adding a New Service](https://coolify.io/docs/knowledge-base/add-a-service) - - -## 9. Create a Pull Request +## 8. Create a Pull Request 1. After making changes or adding a new service: - Commit your changes to your forked repository. @@ -179,11 +182,26 @@ To add a new service to Coolify, please refer to our documentation: - In the description, explain the changes you've made. - Reference any related issues by using keywords like "Fixes #123" or "Closes #456". -4. Important note: - Always set the base branch for your PR to the `next` branch of the Coolify repository, not the `main` branch. +> [!IMPORTANT] +> Always set the base branch for your PR to the `next` branch of the Coolify repository, not the `main` branch. -5. Submit your PR: +4. Submit your PR: - Review your changes one last time. - Click "Create pull request" to submit. +> [!NOTE] +> Make sure your PR is out of draft mode as soon as it's ready for review. PRs that are in draft mode for a long time may be closed by maintainers. + After submission, maintainers will review your PR and may request changes or provide feedback. + +## Additional Contribution Guidelines + +### Contributing a New Service + +To add a new service to Coolify, please refer to our documentation: +[Adding a New Service](https://coolify.io/docs/knowledge-base/contribute/service) + +### Contributing to Documentation + +To contribute to the Coolify documentation, please refer to this guide: +[Contributing to the Coolify Documentation](https://github.com/coollabsio/documentation-coolify/blob/main/CONTRIBUTING.md) diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 000000000..2cb96b72b --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,45 @@ +# Coolify Release Guide + +This guide outlines the release process for Coolify, intended for developers and those interested in understanding how releases are managed and deployed. + +## Release Process + +1. **Development on `next` or separate branches** + - Changes, fixes and new features are developed on the `next` or even separate branches. + +2. **Merging to `main`** + - Once changes are ready, they are merged from `next` into the `main` branch. + +3. **Building the release** + - After merging to `main`, a new release is built. + - Note: A push to `main` does not automatically mean a new version is released. + +4. **Creating a GitHub release** + - A new release is created on GitHub with the new version details. + +5. **Updating the CDN** + - The final step is updating the version information on the CDN: + [https://cdn.coollabs.io/coolify/versions.json](https://cdn.coollabs.io/coolify/versions.json) + +> [!NOTE] +> The CDN update may not occur immediately after the GitHub release. It can happen hours or even days later due to additional testing, stability checks, or potential hotfixes. + + +## Version Availability + +It's important to understand that a new version released on GitHub may not immediately become available for users to update (through manual or auto-update). + +> [!IMPORTANT] +> If you see a new release on GitHub but haven't received the update, it's likely because the CDN hasn't been updated yet. This is intentional and ensures stability and allows for hotfixes before the new version is officially released. + +## Manually Update to Specific Versions + +> [!CAUTION] +> Updating to unreleased versions is not recommended and may cause issues. Use at your own risk! + +To update your Coolify instance to a specific (unreleased) version, use the following command: + +```bash +curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash -s +``` +-> Replace `` with the version you want to update to (for example `4.0.0-beta.332`). diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 718cea639..c6dd2e5f4 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -919,10 +919,10 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue } if ($this->application->build_pack !== 'dockercompose' || $this->application->compose_parsing_version === '1' || $this->application->compose_parsing_version === '2') { if ($this->application->environment_variables_preview->where('key', 'COOLIFY_BRANCH')->isEmpty()) { - $envs->push("COOLIFY_BRANCH={$local_branch}"); + $envs->push("COOLIFY_BRANCH=\"{$local_branch}\""); } if ($this->application->environment_variables_preview->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) { - $envs->push("COOLIFY_CONTAINER_NAME={$this->container_name}"); + $envs->push("COOLIFY_CONTAINER_NAME=\"{$this->container_name}\""); } } @@ -978,10 +978,10 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue } if ($this->application->build_pack !== 'dockercompose' || $this->application->compose_parsing_version === '1' || $this->application->compose_parsing_version === '2') { if ($this->application->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) { - $envs->push("COOLIFY_BRANCH={$local_branch}"); + $envs->push("COOLIFY_BRANCH=\"{$local_branch}\""); } if ($this->application->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) { - $envs->push("COOLIFY_CONTAINER_NAME={$this->container_name}"); + $envs->push("COOLIFY_CONTAINER_NAME=\"{$this->container_name}\""); } } diff --git a/app/Jobs/DatabaseBackupJob.php b/app/Jobs/DatabaseBackupJob.php index 5d481199b..e6fa05b55 100644 --- a/app/Jobs/DatabaseBackupJob.php +++ b/app/Jobs/DatabaseBackupJob.php @@ -25,7 +25,7 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Middleware\WithoutOverlapping; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Str; -use App\Models\InstanceSettings; +use Visus\Cuid2\Cuid2; class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue { @@ -399,6 +399,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue $backupCommand .= " $this->container_name pg_dump --format=custom --no-acl --no-owner --username {$this->database->postgres_user} $database > $this->backup_location"; $commands[] = $backupCommand; + ray($commands); $this->backup_output = instant_remote_process($commands, $this->server); $this->backup_output = trim($this->backup_output); if ($this->backup_output === '') { @@ -480,6 +481,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue private function upload_to_s3(): void { try { + ray($this->backup_location); if (is_null($this->s3)) { return; } @@ -489,62 +491,20 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue $bucket = $this->s3->bucket; $endpoint = $this->s3->endpoint; $this->s3->testConnection(shouldSave: true); - if (data_get($this->backup, 'database_type') === 'App\Models\ServiceDatabase') { - $network = $this->database->service->destination->network; - } else { - $network = $this->database->destination->network; - } + $configName = new Cuid2; - $this->ensureHelperImageAvailable(); - - $fullImageName = $this->getFullImageName(); - $commands[] = "docker run -d --network {$network} --name backup-of-{$this->backup->uuid} --rm -v $this->backup_location:$this->backup_location:ro {$fullImageName}"; - $commands[] = "docker exec backup-of-{$this->backup->uuid} mc config host add temporary {$endpoint} $key $secret"; - $commands[] = "docker exec backup-of-{$this->backup->uuid} mc cp $this->backup_location temporary/$bucket{$this->backup_dir}/"; + $s3_copy_dir = str($this->backup_location)->replace(backup_dir(), '/var/www/html/storage/app/backups/'); + $commands[] = "docker exec coolify bash -c 'mc config host add {$configName} {$endpoint} $key $secret'"; + $commands[] = "docker exec coolify bash -c 'mc cp $s3_copy_dir {$configName}/{$bucket}{$this->backup_dir}/'"; instant_remote_process($commands, $this->server); $this->add_to_backup_output('Uploaded to S3.'); } catch (\Throwable $e) { $this->add_to_backup_output($e->getMessage()); throw $e; } finally { - $command = "docker rm -f backup-of-{$this->backup->uuid}"; - instant_remote_process([$command], $this->server); + $removeConfigCommands[] = "docker exec coolify bash -c 'mc config remove {$configName}'"; + $removeConfigCommands[] = "docker exec coolify bash -c 'mc alias rm {$configName}'"; + instant_remote_process($removeConfigCommands, $this->server, false); } } - - private function ensureHelperImageAvailable(): void - { - $fullImageName = $this->getFullImageName(); - - $imageExists = $this->checkImageExists($fullImageName); - - if (!$imageExists) { - $this->pullHelperImage($fullImageName); - } - } - - private function checkImageExists(string $fullImageName): bool - { - $result = instant_remote_process(["docker image inspect {$fullImageName} >/dev/null 2>&1 && echo 'exists' || echo 'not exists'"], $this->server, false); - return trim($result) === 'exists'; - } - - private function pullHelperImage(string $fullImageName): void - { - try { - instant_remote_process(["docker pull {$fullImageName}"], $this->server); - } catch (\Exception $e) { - $errorMessage = "Failed to pull helper image: " . $e->getMessage(); - $this->add_to_backup_output($errorMessage); - throw new \RuntimeException($errorMessage); - } - } - - private function getFullImageName(): string - { - $settings = InstanceSettings::get(); - $helperImage = config('coolify.helper_image'); - $latestVersion = $settings->helper_version; - return "{$helperImage}:{$latestVersion}"; - } } diff --git a/app/Jobs/ServerCheckJob.php b/app/Jobs/ServerCheckJob.php index f7b54cd80..540085385 100644 --- a/app/Jobs/ServerCheckJob.php +++ b/app/Jobs/ServerCheckJob.php @@ -47,12 +47,12 @@ class ServerCheckJob implements ShouldBeEncrypted, ShouldQueue public function middleware(): array { - return [(new WithoutOverlapping($this->server->uuid))]; + return [(new WithoutOverlapping($this->server->id))]; } public function uniqueId(): int { - return $this->server->uuid; + return $this->server->id; } public function handle() diff --git a/app/Livewire/Boarding/Index.php b/app/Livewire/Boarding/Index.php index 0bfcaf729..af05ad767 100644 --- a/app/Livewire/Boarding/Index.php +++ b/app/Livewire/Boarding/Index.php @@ -282,7 +282,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== public function validateServer() { try { - config()->set('coolify.mux_enabled', false); + config()->set('constants.ssh.mux_enabled', false); // EC2 does not have `uptime` command, lol instant_remote_process(['ls /'], $this->createdServer, true); diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php index 8a4efb21d..3b3747a81 100644 --- a/app/Livewire/Server/Form.php +++ b/app/Livewire/Server/Form.php @@ -24,7 +24,11 @@ class Form extends Component public $timezones; - protected $listeners = ['serverInstalled', 'revalidate' => '$refresh']; + protected $listeners = [ + 'serverInstalled', + 'refreshServerShow' => 'serverInstalled', + 'revalidate' => '$refresh', + ]; protected $rules = [ 'server.name' => 'required', diff --git a/app/Livewire/Server/New/ByIp.php b/app/Livewire/Server/New/ByIp.php index 5f69835d7..f80152435 100644 --- a/app/Livewire/Server/New/ByIp.php +++ b/app/Livewire/Server/New/ByIp.php @@ -2,10 +2,10 @@ namespace App\Livewire\Server\New; -use App\Enums\ProxyStatus; use App\Enums\ProxyTypes; use App\Models\Server; use App\Models\Team; +use Illuminate\Support\Collection; use Livewire\Component; class ByIp extends Component @@ -40,7 +40,7 @@ class ByIp extends Component public bool $is_build_server = false; - public $swarm_managers = []; + public Collection $swarm_managers; protected $rules = [ 'name' => 'required|string', @@ -102,11 +102,6 @@ class ByIp extends Component 'port' => $this->port, 'team_id' => currentTeam()->id, 'private_key_id' => $this->private_key_id, - 'proxy' => [ - // set default proxy type to traefik v2 - 'type' => ProxyTypes::TRAEFIK->value, - 'status' => ProxyStatus::EXITED->value, - ], ]; if ($this->is_swarm_worker) { $payload['swarm_cluster'] = $this->selected_swarm_cluster; @@ -115,6 +110,9 @@ class ByIp extends Component data_forget($payload, 'proxy'); } $server = Server::create($payload); + $server->proxy->set('status', 'exited'); + $server->proxy->set('type', ProxyTypes::TRAEFIK->value); + $server->save(); if ($this->is_build_server) { $this->is_swarm_manager = false; $this->is_swarm_worker = false; diff --git a/app/Livewire/Server/Show.php b/app/Livewire/Server/Show.php index 0751b186e..a5e94a19a 100644 --- a/app/Livewire/Server/Show.php +++ b/app/Livewire/Server/Show.php @@ -14,7 +14,7 @@ class Show extends Component public $parameters = []; - protected $listeners = ['refreshServerShow' => '$refresh']; + protected $listeners = ['refreshServerShow']; public function mount() { @@ -29,6 +29,12 @@ class Show extends Component } } + public function refreshServerShow() + { + $this->server->refresh(); + $this->dispatch('$refresh'); + } + public function submit() { $this->dispatch('serverRefresh', false); diff --git a/app/Models/Server.php b/app/Models/Server.php index 033006eda..1f173604d 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -996,7 +996,7 @@ $schema://$host { public function validateConnection() { - config()->set('coolify.mux_enabled', false); + config()->set('constants.ssh.mux_enabled', false); $server = Server::find($this->id); if (! $server) { diff --git a/app/Models/Service.php b/app/Models/Service.php index 967e7d076..d8def6663 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -667,7 +667,7 @@ class Service extends BaseModel } $data = $data->merge([ 'Root User' => [ - 'key' => 'N/A', + 'key' => 'GITLAB_ROOT_USER', 'value' => 'root', 'rules' => 'required', 'isPassword' => true, diff --git a/app/Models/StandaloneKeydb.php b/app/Models/StandaloneKeydb.php index 607cacade..7ecb00348 100644 --- a/app/Models/StandaloneKeydb.php +++ b/app/Models/StandaloneKeydb.php @@ -209,7 +209,7 @@ class StandaloneKeydb extends BaseModel protected function internalDbUrl(): Attribute { return new Attribute( - get: fn () => "redis://{$this->keydb_password}@{$this->uuid}:6379/0", + get: fn () => "redis://:{$this->keydb_password}@{$this->uuid}:6379/0", ); } @@ -218,7 +218,7 @@ class StandaloneKeydb extends BaseModel return new Attribute( get: function () { if ($this->is_public && $this->public_port) { - return "redis://{$this->keydb_password}@{$this->destination->server->getIp}:{$this->public_port}/0"; + return "redis://:{$this->keydb_password}@{$this->destination->server->getIp}:{$this->public_port}/0"; } return null; diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index f6cf9fbe5..4ba378e67 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -98,12 +98,10 @@ function generateScpCommand(Server $server, string $source, string $dest) $muxPersistTime = config('constants.ssh.mux_persist_time'); $scp_command = "timeout $timeout scp "; - // Check if multiplexing is enabled - $muxEnabled = config('constants.ssh.mux_enabled', true); + $muxEnabled = config('constants.ssh.mux_enabled', true) && config('coolify.is_windows_docker_desktop') == false; // ray('SSH Multiplexing Enabled:', $muxEnabled)->blue(); if ($muxEnabled) { - // Always use multiplexing when enabled $muxSocket = "/var/www/html/storage/app/ssh/mux/{$server->muxFilename()}"; $scp_command .= "-o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} "; ensureMultiplexedConnection($server); @@ -163,10 +161,8 @@ function generateSshCommand(Server $server, string $command) $ssh_command = "timeout $timeout ssh "; - // Check if multiplexing is enabled - $muxEnabled = config('constants.ssh.mux_enabled', true); + $muxEnabled = config('constants.ssh.mux_enabled') && config('coolify.is_windows_docker_desktop') == false; // ray('SSH Multiplexing Enabled:', $muxEnabled)->blue(); - if ($muxEnabled) { // Always use multiplexing when enabled $muxSocket = "/var/www/html/storage/app/ssh/mux/{$server->muxFilename()}"; @@ -201,6 +197,10 @@ function generateSshCommand(Server $server, string $command) function ensureMultiplexedConnection(Server $server) { + if (! (config('constants.ssh.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { + return; + } + static $ensuredConnections = []; if (isset($ensuredConnections[$server->id])) { @@ -212,7 +212,11 @@ function ensureMultiplexedConnection(Server $server) } $muxSocket = "/var/www/html/storage/app/ssh/mux/{$server->muxFilename()}"; - $checkCommand = "ssh -O check -o ControlPath=$muxSocket {$server->user}@{$server->ip} 2>/dev/null"; + $checkCommand = "ssh -O check -o ControlPath=$muxSocket "; + if (data_get($server, 'settings.is_cloudflare_tunnel')) { + $checkCommand .= '-o ProxyCommand="/usr/local/bin/cloudflared access ssh --hostname %h" '; + } + $checkCommand .= " {$server->user}@{$server->ip}"; $process = Process::run($checkCommand); @@ -233,8 +237,12 @@ function ensureMultiplexedConnection(Server $server) $serverInterval = config('constants.ssh.server_interval'); $muxPersistTime = config('constants.ssh.mux_persist_time'); - $establishCommand = "ssh -fNM -o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} " - ."-i {$privateKeyLocation} " + $establishCommand = "ssh -fNM -o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} "; + + if (data_get($server, 'settings.is_cloudflare_tunnel')) { + $establishCommand .= '-o ProxyCommand="/usr/local/bin/cloudflared access ssh --hostname %h" '; + } + $establishCommand .= "-i {$privateKeyLocation} " .'-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ' .'-o PasswordAuthentication=no ' ."-o ConnectTimeout=$connectionTimeout " @@ -260,6 +268,10 @@ function ensureMultiplexedConnection(Server $server) function shouldResetMultiplexedConnection(Server $server) { + if (! (config('constants.ssh.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { + return false; + } + static $ensuredConnections = []; if (! isset($ensuredConnections[$server->id])) { @@ -275,6 +287,10 @@ function shouldResetMultiplexedConnection(Server $server) function resetMultiplexedConnection(Server $server) { + if (! (config('constants.ssh.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { + return; + } + static $ensuredConnections = []; if (isset($ensuredConnections[$server->id])) { diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 028d20f33..4b81fc997 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -786,7 +786,7 @@ function replaceLocalSource(Stringable $source, Stringable $replacedWith) if ($source->startsWith('..')) { $source = $source->replaceFirst('..', $replacedWith->value()); } - if ($source->endsWith('/')) { + if ($source->endsWith('/') && $source->value() !== '/') { $source = $source->replaceLast('/', ''); } @@ -2100,16 +2100,16 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal // TODO: move this in a shared function if (! $parsedServiceVariables->has('COOLIFY_APP_NAME')) { - $parsedServiceVariables->put('COOLIFY_APP_NAME', $resource->name); + $parsedServiceVariables->put('COOLIFY_APP_NAME', "\"{$resource->name}\""); } if (! $parsedServiceVariables->has('COOLIFY_SERVER_IP')) { - $parsedServiceVariables->put('COOLIFY_SERVER_IP', $resource->destination->server->ip); + $parsedServiceVariables->put('COOLIFY_SERVER_IP', "\"{$resource->destination->server->ip}\""); } if (! $parsedServiceVariables->has('COOLIFY_ENVIRONMENT_NAME')) { - $parsedServiceVariables->put('COOLIFY_ENVIRONMENT_NAME', $resource->environment->name); + $parsedServiceVariables->put('COOLIFY_ENVIRONMENT_NAME', "\"{$resource->environment->name}\""); } if (! $parsedServiceVariables->has('COOLIFY_PROJECT_NAME')) { - $parsedServiceVariables->put('COOLIFY_PROJECT_NAME', $resource->project()->name); + $parsedServiceVariables->put('COOLIFY_PROJECT_NAME', "\"{$resource->project()->name}\""); } $parsedServiceVariables = $parsedServiceVariables->map(function ($value, $key) use ($envs_from_coolify) { @@ -3229,7 +3229,6 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int if ($isApplication && $isPullRequest) { $source = $source."-pr-$pullRequestId"; } - LocalFileVolume::updateOrCreate( [ 'mount_path' => $target, @@ -3469,13 +3468,13 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int $branch = "pull/{$pullRequestId}/head"; } if ($originalResource->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) { - $coolifyEnvironments->put('COOLIFY_BRANCH', $branch); + $coolifyEnvironments->put('COOLIFY_BRANCH', "\"{$branch}\""); } } // Add COOLIFY_CONTAINER_NAME to environment if ($resource->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) { - $coolifyEnvironments->put('COOLIFY_CONTAINER_NAME', $containerName); + $coolifyEnvironments->put('COOLIFY_CONTAINER_NAME', "\"{$containerName}\""); } if ($isApplication) { @@ -3548,7 +3547,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int if ($isApplication) { $shouldGenerateLabelsExactly = $resource->destination->server->settings->generate_exact_labels; $uuid = $resource->uuid; - $network = $resource->destination->network; + $network = data_get($resource, 'destination.network'); if ($isPullRequest) { $uuid = "{$resource->uuid}-{$pullRequestId}"; } @@ -3558,7 +3557,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int } else { $shouldGenerateLabelsExactly = $resource->server->settings->generate_exact_labels; $uuid = $resource->uuid; - $network = $resource->destination->network; + $network = data_get($resource, 'destination.network'); } if ($shouldGenerateLabelsExactly) { switch ($server->proxyType()) { @@ -3723,30 +3722,30 @@ function add_coolify_default_environment_variables(StandaloneRedis|StandalonePos } if ($where_to_check != null && $where_to_check->where('key', 'COOLIFY_APP_NAME')->isEmpty()) { if ($isAssociativeArray) { - $where_to_add->put('COOLIFY_APP_NAME', $resource->name); + $where_to_add->put('COOLIFY_APP_NAME', "\"{$resource->name}\""); } else { - $where_to_add->push("COOLIFY_APP_NAME={$resource->name}"); + $where_to_add->push("COOLIFY_APP_NAME=\"{$resource->name}\""); } } if ($where_to_check != null && $where_to_check->where('key', 'COOLIFY_SERVER_IP')->isEmpty()) { if ($isAssociativeArray) { - $where_to_add->put('COOLIFY_SERVER_IP', $ip); + $where_to_add->put('COOLIFY_SERVER_IP', "\"{$ip}\""); } else { - $where_to_add->push("COOLIFY_SERVER_IP={$ip}"); + $where_to_add->push("COOLIFY_SERVER_IP=\"{$ip}\""); } } if ($where_to_check != null && $where_to_check->where('key', 'COOLIFY_ENVIRONMENT_NAME')->isEmpty()) { if ($isAssociativeArray) { - $where_to_add->put('COOLIFY_ENVIRONMENT_NAME', $resource->environment->name); + $where_to_add->put('COOLIFY_ENVIRONMENT_NAME', "\"{$resource->environment->name}\""); } else { - $where_to_add->push("COOLIFY_ENVIRONMENT_NAME={$resource->environment->name}"); + $where_to_add->push("COOLIFY_ENVIRONMENT_NAME=\"{$resource->environment->name}\""); } } if ($where_to_check != null && $where_to_check->where('key', 'COOLIFY_PROJECT_NAME')->isEmpty()) { if ($isAssociativeArray) { - $where_to_add->put('COOLIFY_PROJECT_NAME', $resource->project()->name); + $where_to_add->put('COOLIFY_PROJECT_NAME', "\"{$resource->project()->name}\""); } else { - $where_to_add->push("COOLIFY_PROJECT_NAME={$resource->project()->name}"); + $where_to_add->push("COOLIFY_PROJECT_NAME=\"{$resource->project()->name}\""); } } } diff --git a/composer.json b/composer.json index 7ca65babe..e8b46105d 100644 --- a/composer.json +++ b/composer.json @@ -110,4 +110,4 @@ }, "minimum-stability": "stable", "prefer-stable": true -} \ No newline at end of file +} diff --git a/composer.lock b/composer.lock index 4deaa42de..fffb320d3 100644 --- a/composer.lock +++ b/composer.lock @@ -921,16 +921,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.321.2", + "version": "3.321.9", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "c04f8f30891cee8480c132778cd4cc486467e77a" + "reference": "5de5099cfe0e17cb3eb2fe51de0101c99bc9442a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c04f8f30891cee8480c132778cd4cc486467e77a", - "reference": "c04f8f30891cee8480c132778cd4cc486467e77a", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5de5099cfe0e17cb3eb2fe51de0101c99bc9442a", + "reference": "5de5099cfe0e17cb3eb2fe51de0101c99bc9442a", "shasum": "" }, "require": { @@ -1013,9 +1013,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.321.2" + "source": "https://github.com/aws/aws-sdk-php/tree/3.321.9" }, - "time": "2024-08-30T18:14:40+00:00" + "time": "2024-09-11T18:15:49+00:00" }, { "name": "bacon/bacon-qr-code", @@ -1518,16 +1518,16 @@ }, { "name": "doctrine/dbal", - "version": "3.9.0", + "version": "3.9.1", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "d8f68ea6cc00912e5313237130b8c8decf4d28c6" + "reference": "d7dc08f98cba352b2bab5d32c5e58f7e745c11a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/d8f68ea6cc00912e5313237130b8c8decf4d28c6", - "reference": "d8f68ea6cc00912e5313237130b8c8decf4d28c6", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/d7dc08f98cba352b2bab5d32c5e58f7e745c11a7", + "reference": "d7dc08f98cba352b2bab5d32c5e58f7e745c11a7", "shasum": "" }, "require": { @@ -1543,7 +1543,7 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.11.7", + "phpstan/phpstan": "1.12.0", "phpstan/phpstan-strict-rules": "^1.6", "phpunit/phpunit": "9.6.20", "psalm/plugin-phpunit": "0.18.4", @@ -1611,7 +1611,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.9.0" + "source": "https://github.com/doctrine/dbal/tree/3.9.1" }, "funding": [ { @@ -1627,7 +1627,7 @@ "type": "tidelift" } ], - "time": "2024-08-15T07:34:42+00:00" + "time": "2024-09-01T13:49:23+00:00" }, { "name": "doctrine/deprecations", @@ -2789,16 +2789,16 @@ }, { "name": "laravel/fortify", - "version": "v1.24.0", + "version": "v1.24.1", "source": { "type": "git", "url": "https://github.com/laravel/fortify.git", - "reference": "fbe67f018c1fe26d00913de56a6d60589b4be9b2" + "reference": "8158ba0960bb5f4aae509d01d74a95e16e30de20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/fortify/zipball/fbe67f018c1fe26d00913de56a6d60589b4be9b2", - "reference": "fbe67f018c1fe26d00913de56a6d60589b4be9b2", + "url": "https://api.github.com/repos/laravel/fortify/zipball/8158ba0960bb5f4aae509d01d74a95e16e30de20", + "reference": "8158ba0960bb5f4aae509d01d74a95e16e30de20", "shasum": "" }, "require": { @@ -2850,20 +2850,20 @@ "issues": "https://github.com/laravel/fortify/issues", "source": "https://github.com/laravel/fortify" }, - "time": "2024-08-20T14:43:56+00:00" + "time": "2024-09-03T10:02:14+00:00" }, { "name": "laravel/framework", - "version": "v11.21.0", + "version": "v11.23.2", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "9d9d36708d56665b12185493f684abce38ad2d30" + "reference": "d38bf0fd3a8936e1cb9ca8eb8d7304a564f790f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/9d9d36708d56665b12185493f684abce38ad2d30", - "reference": "9d9d36708d56665b12185493f684abce38ad2d30", + "url": "https://api.github.com/repos/laravel/framework/zipball/d38bf0fd3a8936e1cb9ca8eb8d7304a564f790f3", + "reference": "d38bf0fd3a8936e1cb9ca8eb8d7304a564f790f3", "shasum": "" }, "require": { @@ -2925,6 +2925,7 @@ "illuminate/bus": "self.version", "illuminate/cache": "self.version", "illuminate/collections": "self.version", + "illuminate/concurrency": "self.version", "illuminate/conditionable": "self.version", "illuminate/config": "self.version", "illuminate/console": "self.version", @@ -2967,7 +2968,7 @@ "league/flysystem-sftp-v3": "^3.0", "mockery/mockery": "^1.6", "nyholm/psr7": "^1.2", - "orchestra/testbench-core": "^9.1.5", + "orchestra/testbench-core": "^9.4.0", "pda/pheanstalk": "^5.0", "phpstan/phpstan": "^1.11.5", "phpunit/phpunit": "^10.5|^11.0", @@ -3025,6 +3026,7 @@ "src/Illuminate/Events/functions.php", "src/Illuminate/Filesystem/functions.php", "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Log/functions.php", "src/Illuminate/Support/helpers.php" ], "psr-4": { @@ -3056,20 +3058,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-08-20T15:00:52+00:00" + "time": "2024-09-11T21:59:23+00:00" }, { "name": "laravel/horizon", - "version": "v5.27.1", + "version": "v5.28.1", "source": { "type": "git", "url": "https://github.com/laravel/horizon.git", - "reference": "184449be3eb296ab16c13a69ce22049f32d0fc2c" + "reference": "9d2c4eaeb11408384401f8a7d1b0ea4c76554f3f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/horizon/zipball/184449be3eb296ab16c13a69ce22049f32d0fc2c", - "reference": "184449be3eb296ab16c13a69ce22049f32d0fc2c", + "url": "https://api.github.com/repos/laravel/horizon/zipball/9d2c4eaeb11408384401f8a7d1b0ea4c76554f3f", + "reference": "9d2c4eaeb11408384401f8a7d1b0ea4c76554f3f", "shasum": "" }, "require": { @@ -3133,9 +3135,9 @@ ], "support": { "issues": "https://github.com/laravel/horizon/issues", - "source": "https://github.com/laravel/horizon/tree/v5.27.1" + "source": "https://github.com/laravel/horizon/tree/v5.28.1" }, - "time": "2024-08-05T14:23:30+00:00" + "time": "2024-09-04T14:06:50+00:00" }, { "name": "laravel/prompts", @@ -3322,16 +3324,16 @@ }, { "name": "laravel/socialite", - "version": "v5.15.1", + "version": "v5.16.0", "source": { "type": "git", "url": "https://github.com/laravel/socialite.git", - "reference": "cc02625f0bd1f95dc3688eb041cce0f1e709d029" + "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/socialite/zipball/cc02625f0bd1f95dc3688eb041cce0f1e709d029", - "reference": "cc02625f0bd1f95dc3688eb041cce0f1e709d029", + "url": "https://api.github.com/repos/laravel/socialite/zipball/40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf", + "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf", "shasum": "" }, "require": { @@ -3390,7 +3392,7 @@ "issues": "https://github.com/laravel/socialite/issues", "source": "https://github.com/laravel/socialite" }, - "time": "2024-06-28T20:09:34+00:00" + "time": "2024-09-03T09:46:57+00:00" }, { "name": "laravel/telescope", @@ -4532,16 +4534,16 @@ }, { "name": "lorisleiva/laravel-actions", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/lorisleiva/laravel-actions.git", - "reference": "4507d5bc7b28d168881a799081e60c245b3449db" + "reference": "5a168bfdd3b75dd6ff259019d4aeef784bbd5403" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lorisleiva/laravel-actions/zipball/4507d5bc7b28d168881a799081e60c245b3449db", - "reference": "4507d5bc7b28d168881a799081e60c245b3449db", + "url": "https://api.github.com/repos/lorisleiva/laravel-actions/zipball/5a168bfdd3b75dd6ff259019d4aeef784bbd5403", + "reference": "5a168bfdd3b75dd6ff259019d4aeef784bbd5403", "shasum": "" }, "require": { @@ -4596,7 +4598,7 @@ ], "support": { "issues": "https://github.com/lorisleiva/laravel-actions/issues", - "source": "https://github.com/lorisleiva/laravel-actions/tree/v2.8.3" + "source": "https://github.com/lorisleiva/laravel-actions/tree/v2.8.4" }, "funding": [ { @@ -4604,7 +4606,7 @@ "type": "github" } ], - "time": "2024-08-20T17:08:48+00:00" + "time": "2024-09-10T09:57:29+00:00" }, { "name": "lorisleiva/lody", @@ -4781,16 +4783,16 @@ }, { "name": "mtdowling/jmespath.php", - "version": "2.7.0", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/jmespath/jmespath.php.git", - "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b" + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/bbb69a935c2cbb0c03d7f481a238027430f6440b", - "reference": "bbb69a935c2cbb0c03d7f481a238027430f6440b", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc", "shasum": "" }, "require": { @@ -4807,7 +4809,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -4841,9 +4843,9 @@ ], "support": { "issues": "https://github.com/jmespath/jmespath.php/issues", - "source": "https://github.com/jmespath/jmespath.php/tree/2.7.0" + "source": "https://github.com/jmespath/jmespath.php/tree/2.8.0" }, - "time": "2023-08-25T10:54:48+00:00" + "time": "2024-09-04T18:46:31+00:00" }, { "name": "nesbot/carbon", @@ -5212,16 +5214,16 @@ }, { "name": "nunomaduro/termwind", - "version": "v2.0.1", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/termwind.git", - "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a" + "reference": "e5f21eade88689536c0cdad4c3cd75f3ed26e01a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/58c4c58cf23df7f498daeb97092e34f5259feb6a", - "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/e5f21eade88689536c0cdad4c3cd75f3ed26e01a", + "reference": "e5f21eade88689536c0cdad4c3cd75f3ed26e01a", "shasum": "" }, "require": { @@ -5231,11 +5233,11 @@ }, "require-dev": { "ergebnis/phpstan-rules": "^2.2.0", - "illuminate/console": "^11.0.0", - "laravel/pint": "^1.14.0", - "mockery/mockery": "^1.6.7", - "pestphp/pest": "^2.34.1", - "phpstan/phpstan": "^1.10.59", + "illuminate/console": "^11.1.1", + "laravel/pint": "^1.15.0", + "mockery/mockery": "^1.6.11", + "pestphp/pest": "^2.34.6", + "phpstan/phpstan": "^1.10.66", "phpstan/phpstan-strict-rules": "^1.5.2", "symfony/var-dumper": "^7.0.4", "thecodingmachine/phpstan-strict-rules": "^1.0.0" @@ -5280,7 +5282,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.0.1" + "source": "https://github.com/nunomaduro/termwind/tree/v2.1.0" }, "funding": [ { @@ -5296,20 +5298,20 @@ "type": "github" } ], - "time": "2024-03-06T16:17:14+00:00" + "time": "2024-09-05T15:25:50+00:00" }, { "name": "nyholm/psr7", - "version": "1.8.1", + "version": "1.8.2", "source": { "type": "git", "url": "https://github.com/Nyholm/psr7.git", - "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e" + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/aa5fc277a4f5508013d571341ade0c3886d4d00e", - "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3", "shasum": "" }, "require": { @@ -5362,7 +5364,7 @@ ], "support": { "issues": "https://github.com/Nyholm/psr7/issues", - "source": "https://github.com/Nyholm/psr7/tree/1.8.1" + "source": "https://github.com/Nyholm/psr7/tree/1.8.2" }, "funding": [ { @@ -5374,28 +5376,28 @@ "type": "github" } ], - "time": "2023-11-13T09:31:12+00:00" + "time": "2024-09-09T07:06:30+00:00" }, { "name": "paragonie/constant_time_encoding", - "version": "v2.7.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105" + "reference": "df1e7fde177501eee2037dd159cf04f5f301a512" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/52a0d99e69f56b9ec27ace92ba56897fe6993105", - "reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/df1e7fde177501eee2037dd159cf04f5f301a512", + "reference": "df1e7fde177501eee2037dd159cf04f5f301a512", "shasum": "" }, "require": { - "php": "^7|^8" + "php": "^8" }, "require-dev": { - "phpunit/phpunit": "^6|^7|^8|^9", - "vimeo/psalm": "^1|^2|^3|^4" + "phpunit/phpunit": "^9", + "vimeo/psalm": "^4|^5" }, "type": "library", "autoload": { @@ -5441,7 +5443,7 @@ "issues": "https://github.com/paragonie/constant_time_encoding/issues", "source": "https://github.com/paragonie/constant_time_encoding" }, - "time": "2024-05-08T12:18:48+00:00" + "time": "2024-05-08T12:36:18+00:00" }, { "name": "paragonie/random_compat", @@ -6005,16 +6007,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.30.0", + "version": "1.30.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f" + "reference": "51b95ec8670af41009e2b2b56873bad96682413e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/5ceb0e384997db59f38774bf79c2a6134252c08f", - "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/51b95ec8670af41009e2b2b56873bad96682413e", + "reference": "51b95ec8670af41009e2b2b56873bad96682413e", "shasum": "" }, "require": { @@ -6046,22 +6048,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.1" }, - "time": "2024-08-29T09:54:52+00:00" + "time": "2024-09-07T20:13:05+00:00" }, { "name": "phpstan/phpstan", - "version": "1.12.0", + "version": "1.12.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "384af967d35b2162f69526c7276acadce534d0e1" + "reference": "0fcbf194ab63d8159bb70d9aa3e1350051632009" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/384af967d35b2162f69526c7276acadce534d0e1", - "reference": "384af967d35b2162f69526c7276acadce534d0e1", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0fcbf194ab63d8159bb70d9aa3e1350051632009", + "reference": "0fcbf194ab63d8159bb70d9aa3e1350051632009", "shasum": "" }, "require": { @@ -6106,7 +6108,7 @@ "type": "github" } ], - "time": "2024-08-27T09:18:05+00:00" + "time": "2024-09-09T08:10:35+00:00" }, { "name": "pion/laravel-chunk-upload", @@ -6220,24 +6222,24 @@ }, { "name": "pragmarx/google2fa", - "version": "v8.0.1", + "version": "v8.0.3", "source": { "type": "git", "url": "https://github.com/antonioribeiro/google2fa.git", - "reference": "80c3d801b31fe165f8fe99ea085e0a37834e1be3" + "reference": "6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/80c3d801b31fe165f8fe99ea085e0a37834e1be3", - "reference": "80c3d801b31fe165f8fe99ea085e0a37834e1be3", + "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad", + "reference": "6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad", "shasum": "" }, "require": { - "paragonie/constant_time_encoding": "^1.0|^2.0", + "paragonie/constant_time_encoding": "^1.0|^2.0|^3.0", "php": "^7.1|^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.18", + "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^7.5.15|^8.5|^9.0" }, "type": "library", @@ -6266,9 +6268,9 @@ ], "support": { "issues": "https://github.com/antonioribeiro/google2fa/issues", - "source": "https://github.com/antonioribeiro/google2fa/tree/v8.0.1" + "source": "https://github.com/antonioribeiro/google2fa/tree/v8.0.3" }, - "time": "2022-06-13T21:57:56+00:00" + "time": "2024-09-05T11:56:40+00:00" }, { "name": "psr/cache", @@ -6632,16 +6634,16 @@ }, { "name": "psr/log", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "79dff0b268932c640297f5208d6298f71855c03e" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e", - "reference": "79dff0b268932c640297f5208d6298f71855c03e", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { @@ -6676,9 +6678,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.1" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "time": "2024-08-21T13:31:24+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { "name": "psr/simple-cache", @@ -7146,21 +7148,21 @@ }, { "name": "rector/rector", - "version": "1.2.4", + "version": "1.2.5", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "42a4aa23b48b4cfc8ebfeac2b570364e27744381" + "reference": "e98aa793ca3fcd17e893cfaf9103ac049775d339" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/42a4aa23b48b4cfc8ebfeac2b570364e27744381", - "reference": "42a4aa23b48b4cfc8ebfeac2b570364e27744381", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/e98aa793ca3fcd17e893cfaf9103ac049775d339", + "reference": "e98aa793ca3fcd17e893cfaf9103ac049775d339", "shasum": "" }, "require": { "php": "^7.2|^8.0", - "phpstan/phpstan": "^1.11.11" + "phpstan/phpstan": "^1.12.2" }, "conflict": { "rector/rector-doctrine": "*", @@ -7193,7 +7195,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/1.2.4" + "source": "https://github.com/rectorphp/rector/tree/1.2.5" }, "funding": [ { @@ -7201,7 +7203,7 @@ "type": "github" } ], - "time": "2024-08-23T09:03:01+00:00" + "time": "2024-09-08T17:43:24+00:00" }, { "name": "resend/resend-laravel", @@ -9520,20 +9522,20 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "0424dff1c58f028c451efff2045f5d92410bd540" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", - "reference": "0424dff1c58f028c451efff2045f5d92410bd540", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -9579,7 +9581,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { @@ -9595,24 +9597,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "c027e6a3c6aee334663ec21f5852e89738abc805" + "reference": "48becf00c920479ca2e910c22a5a39e5d47ca956" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/c027e6a3c6aee334663ec21f5852e89738abc805", - "reference": "c027e6a3c6aee334663ec21f5852e89738abc805", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/48becf00c920479ca2e910c22a5a39e5d47ca956", + "reference": "48becf00c920479ca2e910c22a5a39e5d47ca956", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-iconv": "*" @@ -9659,7 +9661,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.31.0" }, "funding": [ { @@ -9675,24 +9677,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a", - "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -9737,7 +9739,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { @@ -9753,26 +9755,25 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c" + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a6e83bdeb3c84391d1dfe16f42e40727ce524a5c", - "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, "suggest": { "ext-intl": "For best performance" @@ -9821,7 +9822,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0" }, "funding": [ { @@ -9837,24 +9838,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb", - "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -9902,7 +9903,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -9918,24 +9919,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", - "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -9982,7 +9983,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -9998,97 +9999,24 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:30:46+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.30.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "10112722600777e02d2745716b70c5db4ca70442" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/10112722600777e02d2745716b70c5db4ca70442", - "reference": "10112722600777e02d2745716b70c5db4ca70442", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.30.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-06-19T12:30:46+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -10135,7 +10063,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -10151,24 +10079,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9" + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9", - "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -10211,7 +10139,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" }, "funding": [ { @@ -10227,24 +10155,24 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:35:24+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-uuid", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9" + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/2ba1f33797470debcda07fe9dce20a0003df18e9", - "reference": "2ba1f33797470debcda07fe9dce20a0003df18e9", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-uuid": "*" @@ -10290,7 +10218,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.31.0" }, "funding": [ { @@ -10306,7 +10234,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/process", @@ -12309,16 +12237,16 @@ }, { "name": "laravel/pint", - "version": "v1.17.2", + "version": "v1.17.3", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110" + "reference": "9d77be916e145864f10788bb94531d03e1f7b482" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/e8a88130a25e3f9d4d5785e6a1afca98268ab110", - "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110", + "url": "https://api.github.com/repos/laravel/pint/zipball/9d77be916e145864f10788bb94531d03e1f7b482", + "reference": "9d77be916e145864f10788bb94531d03e1f7b482", "shasum": "" }, "require": { @@ -12329,13 +12257,13 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.61.1", - "illuminate/view": "^10.48.18", + "friendsofphp/php-cs-fixer": "^3.64.0", + "illuminate/view": "^10.48.20", "larastan/larastan": "^2.9.8", "laravel-zero/framework": "^10.4.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^1.15.1", - "pestphp/pest": "^2.35.0" + "pestphp/pest": "^2.35.1" }, "bin": [ "builds/pint" @@ -12371,7 +12299,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-08-06T15:11:54+00:00" + "time": "2024-09-03T15:00:28+00:00" }, { "name": "mockery/mockery", diff --git a/config/clockwork.php b/config/clockwork.php new file mode 100644 index 000000000..ce880464a --- /dev/null +++ b/config/clockwork.php @@ -0,0 +1,424 @@ + env('CLOCKWORK_ENABLE', null), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Features + |------------------------------------------------------------------------------------------------------------------ + | + | You can enable or disable various Clockwork features here. Some features have additional settings (eg. slow query + | threshold for database queries). + | + */ + + 'features' => [ + + // Cache usage stats and cache queries including results + 'cache' => [ + 'enabled' => env('CLOCKWORK_CACHE_ENABLED', true), + + // Collect cache queries + 'collect_queries' => env('CLOCKWORK_CACHE_QUERIES', true), + + // Collect values from cache queries (high performance impact with a very high number of queries) + 'collect_values' => env('CLOCKWORK_CACHE_COLLECT_VALUES', false) + ], + + // Database usage stats and queries + 'database' => [ + 'enabled' => env('CLOCKWORK_DATABASE_ENABLED', true), + + // Collect database queries (high performance impact with a very high number of queries) + 'collect_queries' => env('CLOCKWORK_DATABASE_COLLECT_QUERIES', true), + + // Collect details of models updates (high performance impact with a lot of model updates) + 'collect_models_actions' => env('CLOCKWORK_DATABASE_COLLECT_MODELS_ACTIONS', true), + + // Collect details of retrieved models (very high performance impact with a lot of models retrieved) + 'collect_models_retrieved' => env('CLOCKWORK_DATABASE_COLLECT_MODELS_RETRIEVED', false), + + // Query execution time threshold in milliseconds after which the query will be marked as slow + 'slow_threshold' => env('CLOCKWORK_DATABASE_SLOW_THRESHOLD'), + + // Collect only slow database queries + 'slow_only' => env('CLOCKWORK_DATABASE_SLOW_ONLY', false), + + // Detect and report duplicate queries + 'detect_duplicate_queries' => env('CLOCKWORK_DATABASE_DETECT_DUPLICATE_QUERIES', false) + ], + + // Dispatched events + 'events' => [ + 'enabled' => env('CLOCKWORK_EVENTS_ENABLED', true), + + // Ignored events (framework events are ignored by default) + 'ignored_events' => [ + // App\Events\UserRegistered::class, + // 'user.registered' + ], + ], + + // Laravel log (you can still log directly to Clockwork with laravel log disabled) + 'log' => [ + 'enabled' => env('CLOCKWORK_LOG_ENABLED', true) + ], + + // Sent notifications + 'notifications' => [ + 'enabled' => env('CLOCKWORK_NOTIFICATIONS_ENABLED', true), + ], + + // Performance metrics + 'performance' => [ + // Allow collecting of client metrics. Requires separate clockwork-browser npm package. + 'client_metrics' => env('CLOCKWORK_PERFORMANCE_CLIENT_METRICS', true) + ], + + // Dispatched queue jobs + 'queue' => [ + 'enabled' => env('CLOCKWORK_QUEUE_ENABLED', true) + ], + + // Redis commands + 'redis' => [ + 'enabled' => env('CLOCKWORK_REDIS_ENABLED', true) + ], + + // Routes list + 'routes' => [ + 'enabled' => env('CLOCKWORK_ROUTES_ENABLED', false), + + // Collect only routes from particular namespaces (only application routes by default) + 'only_namespaces' => [ 'App' ] + ], + + // Rendered views + 'views' => [ + 'enabled' => env('CLOCKWORK_VIEWS_ENABLED', true), + + // Collect views including view data (high performance impact with a high number of views) + 'collect_data' => env('CLOCKWORK_VIEWS_COLLECT_DATA', false), + + // Use Twig profiler instead of Laravel events for apps using laravel-twigbridge (more precise, but does + // not support collecting view data) + 'use_twig_profiler' => env('CLOCKWORK_VIEWS_USE_TWIG_PROFILER', false) + ] + + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Enable web UI + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork comes with a web UI accessible via http://your.app/clockwork. Here you can enable or disable this + | feature. You can also set a custom path for the web UI. + | + */ + + 'web' => env('CLOCKWORK_WEB', true), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Enable toolbar + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can show a toolbar with basic metrics on all responses. Here you can enable or disable this feature. + | Requires a separate clockwork-browser npm library. + | For installation instructions see https://underground.works/clockwork/#docs-viewing-data + | + */ + + 'toolbar' => env('CLOCKWORK_TOOLBAR', true), + + /* + |------------------------------------------------------------------------------------------------------------------ + | HTTP requests collection + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork collects data about HTTP requests to your app. Here you can choose which requests should be collected. + | + */ + + 'requests' => [ + // With on-demand mode enabled, Clockwork will only profile requests when the browser extension is open or you + // manually pass a "clockwork-profile" cookie or get/post data key. + // Optionally you can specify a "secret" that has to be passed as the value to enable profiling. + 'on_demand' => env('CLOCKWORK_REQUESTS_ON_DEMAND', false), + + // Collect only errors (requests with HTTP 4xx and 5xx responses) + 'errors_only' => env('CLOCKWORK_REQUESTS_ERRORS_ONLY', false), + + // Response time threshold in milliseconds after which the request will be marked as slow + 'slow_threshold' => env('CLOCKWORK_REQUESTS_SLOW_THRESHOLD'), + + // Collect only slow requests + 'slow_only' => env('CLOCKWORK_REQUESTS_SLOW_ONLY', false), + + // Sample the collected requests (e.g. set to 100 to collect only 1 in 100 requests) + 'sample' => env('CLOCKWORK_REQUESTS_SAMPLE', false), + + // List of URIs that should not be collected + 'except' => [ + '/horizon/.*', // Laravel Horizon requests + '/telescope/.*', // Laravel Telescope requests + '/_tt/.*', // Laravel Telescope toolbar + '/_debugbar/.*', // Laravel DebugBar requests + ], + + // List of URIs that should be collected, any other URI will not be collected if not empty + 'only' => [ + // '/api/.*' + ], + + // Don't collect OPTIONS requests, mostly used in the CSRF pre-flight requests and are rarely of interest + 'except_preflight' => env('CLOCKWORK_REQUESTS_EXCEPT_PREFLIGHT', true) + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Artisan commands collection + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can collect data about executed artisan commands. Here you can enable and configure which commands + | should be collected. + | + */ + + 'artisan' => [ + // Enable or disable collection of executed Artisan commands + 'collect' => env('CLOCKWORK_ARTISAN_COLLECT', false), + + // List of commands that should not be collected (built-in commands are not collected by default) + 'except' => [ + // 'inspire' + ], + + // List of commands that should be collected, any other command will not be collected if not empty + 'only' => [ + // 'inspire' + ], + + // Enable or disable collection of command output + 'collect_output' => env('CLOCKWORK_ARTISAN_COLLECT_OUTPUT', false), + + // Enable or disable collection of built-in Laravel commands + 'except_laravel_commands' => env('CLOCKWORK_ARTISAN_EXCEPT_LARAVEL_COMMANDS', true) + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Queue jobs collection + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can collect data about executed queue jobs. Here you can enable and configure which queue jobs should + | be collected. + | + */ + + 'queue' => [ + // Enable or disable collection of executed queue jobs + 'collect' => env('CLOCKWORK_QUEUE_COLLECT', false), + + // List of queue jobs that should not be collected + 'except' => [ + // App\Jobs\ExpensiveJob::class + ], + + // List of queue jobs that should be collected, any other queue job will not be collected if not empty + 'only' => [ + // App\Jobs\BuggyJob::class + ] + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Tests collection + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can collect data about executed tests. Here you can enable and configure which tests should be + | collected. + | + */ + + 'tests' => [ + // Enable or disable collection of ran tests + 'collect' => env('CLOCKWORK_TESTS_COLLECT', false), + + // List of tests that should not be collected + 'except' => [ + // Tests\Unit\ExampleTest::class + ] + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Enable data collection when Clockwork is disabled + |------------------------------------------------------------------------------------------------------------------ + | + | You can enable this setting to collect data even when Clockwork is disabled, e.g. for future analysis. + | + */ + + 'collect_data_always' => env('CLOCKWORK_COLLECT_DATA_ALWAYS', false), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Metadata storage + |------------------------------------------------------------------------------------------------------------------ + | + | Configure how is the metadata collected by Clockwork stored. Three options are available: + | - files - A simple fast storage implementation storing data in one-per-request files. + | - sql - Stores requests in a sql database. Supports MySQL, PostgreSQL and SQLite. Requires PDO. + | - redis - Stores requests in redis. Requires phpredis. + */ + + 'storage' => env('CLOCKWORK_STORAGE', 'files'), + + // Path where the Clockwork metadata is stored + 'storage_files_path' => env('CLOCKWORK_STORAGE_FILES_PATH', storage_path('clockwork')), + + // Compress the metadata files using gzip, trading a little bit of performance for lower disk usage + 'storage_files_compress' => env('CLOCKWORK_STORAGE_FILES_COMPRESS', false), + + // SQL database to use, can be a name of database configured in database.php or a path to a SQLite file + 'storage_sql_database' => env('CLOCKWORK_STORAGE_SQL_DATABASE', storage_path('clockwork.sqlite')), + + // SQL table name to use, the table is automatically created and updated when needed + 'storage_sql_table' => env('CLOCKWORK_STORAGE_SQL_TABLE', 'clockwork'), + + // Redis connection, name of redis connection or cluster configured in database.php + 'storage_redis' => env('CLOCKWORK_STORAGE_REDIS', 'default'), + + // Redis prefix for Clockwork keys ("clockwork" if not set) + 'storage_redis_prefix' => env('CLOCKWORK_STORAGE_REDIS_PREFIX', 'clockwork'), + + // Maximum lifetime of collected metadata in minutes, older requests will automatically be deleted, false to disable + 'storage_expiration' => env('CLOCKWORK_STORAGE_EXPIRATION', 60 * 24 * 7), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Authentication + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can be configured to require authentication before allowing access to the collected data. This might be + | useful when the application is publicly accessible. Setting to true will enable a simple authentication with a + | pre-configured password. You can also pass a class name of a custom implementation. + | + */ + + 'authentication' => env('CLOCKWORK_AUTHENTICATION', false), + + // Password for the simple authentication + 'authentication_password' => env('CLOCKWORK_AUTHENTICATION_PASSWORD', 'VerySecretPassword'), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Stack traces collection + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork can collect stack traces for log messages and certain data like database queries. Here you can set + | whether to collect stack traces, limit the number of collected frames and set further configuration. Collecting + | long stack traces considerably increases metadata size. + | + */ + + 'stack_traces' => [ + // Enable or disable collecting of stack traces + 'enabled' => env('CLOCKWORK_STACK_TRACES_ENABLED', true), + + // Limit the number of frames to be collected + 'limit' => env('CLOCKWORK_STACK_TRACES_LIMIT', 10), + + // List of vendor names to skip when determining caller, common vendors are automatically added + 'skip_vendors' => [ + // 'phpunit' + ], + + // List of namespaces to skip when determining caller + 'skip_namespaces' => [ + // 'Laravel' + ], + + // List of class names to skip when determining caller + 'skip_classes' => [ + // App\CustomLog::class + ] + + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Serialization + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork serializes the collected data to json for storage and transfer. Here you can configure certain aspects + | of serialization. Serialization has a large effect on the cpu time and memory usage. + | + */ + + // Maximum depth of serialized multi-level arrays and objects + 'serialization_depth' => env('CLOCKWORK_SERIALIZATION_DEPTH', 10), + + // A list of classes that will never be serialized (e.g. a common service container class) + 'serialization_blackbox' => [ + \Illuminate\Container\Container::class, + \Illuminate\Foundation\Application::class, + \Laravel\Lumen\Application::class + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Register helpers + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork comes with a "clock" global helper function. You can use this helper to quickly log something and to + | access the Clockwork instance. + | + */ + + 'register_helpers' => env('CLOCKWORK_REGISTER_HELPERS', true), + + /* + |------------------------------------------------------------------------------------------------------------------ + | Send headers for AJAX request + |------------------------------------------------------------------------------------------------------------------ + | + | When trying to collect data, the AJAX method can sometimes fail if it is missing required headers. For example, an + | API might require a version number using Accept headers to route the HTTP request to the correct codebase. + | + */ + + 'headers' => [ + // 'Accept' => 'application/vnd.com.whatever.v1+json', + ], + + /* + |------------------------------------------------------------------------------------------------------------------ + | Server timing + |------------------------------------------------------------------------------------------------------------------ + | + | Clockwork supports the W3C Server Timing specification, which allows for collecting a simple performance metrics + | in a cross-browser way. E.g. in Chrome, your app, database and timeline event timings will be shown in the Dev + | Tools network tab. This setting specifies the max number of timeline events that will be sent. Setting to false + | will disable the feature. + | + */ + + 'server_timing' => env('CLOCKWORK_SERVER_TIMING', 10) + +]; diff --git a/config/constants.php b/config/constants.php index c223e6418..906ef3ba2 100644 --- a/config/constants.php +++ b/config/constants.php @@ -6,7 +6,8 @@ return [ 'contact' => 'https://coolify.io/docs/contact', ], 'ssh' => [ - 'mux_enabled' => env('SSH_MUX_ENABLED', true), + // Using MUX + 'mux_enabled' => env('MUX_ENABLED', env('SSH_MUX_ENABLED', true), true), 'mux_persist_time' => env('SSH_MUX_PERSIST_TIME', '1h'), 'connection_timeout' => 10, 'server_interval' => 20, diff --git a/config/coolify.php b/config/coolify.php index 6e284fe9e..f9878fff7 100644 --- a/config/coolify.php +++ b/config/coolify.php @@ -7,7 +7,6 @@ return [ 'self_hosted' => env('SELF_HOSTED', true), 'waitlist' => env('WAITLIST', false), 'license_url' => 'https://licenses.coollabs.io', - 'mux_enabled' => env('MUX_ENABLED', true), 'dev_webhook' => env('SERVEO_URL'), 'is_windows_docker_desktop' => env('IS_WINDOWS_DOCKER_DESKTOP', false), 'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'), diff --git a/config/sentry.php b/config/sentry.php index eb0a3a508..bae81659a 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.333', + 'release' => '4.0.0-beta.336', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index c3c14e32b..bab78d59c 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ /etc/php/current_version/cli/conf.d/upload-limits.ini + +COPY --from=minio/mc:RELEASE.2024-09-09T07-53-10Z /usr/bin/mc /usr/bin/mc +RUN chmod +x /usr/bin/mc diff --git a/resources/views/components/navbar.blade.php b/resources/views/components/navbar.blade.php index 7da619377..a7a3c2109 100644 --- a/resources/views/components/navbar.blade.php +++ b/resources/views/components/navbar.blade.php @@ -1,7 +1,7 @@