mirror of
https://github.com/coollabsio/coolify.git
synced 2026-06-14 03:19:51 +00:00
feat(realtime): replace Soketi image with bundled Reverb
Run Laravel Reverb and the terminal server inside the Coolify container instead of shipping a separate coolify-realtime image. Update compose files, proxy routing, cleanup behavior, and packaging tests for the embedded realtime services.
This commit is contained in:
+1
-1
@@ -23,7 +23,7 @@ yarn-error.log
|
||||
/.ssh
|
||||
.ignition.json
|
||||
.env.dusk.local
|
||||
docker/coolify-realtime/node_modules
|
||||
docker/coolify-terminal/node_modules
|
||||
|
||||
/storage/*.key
|
||||
/storage/app/backups
|
||||
|
||||
@@ -10,6 +10,8 @@ REDIS_PASSWORD=
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_PORT=6001
|
||||
PUSHER_BACKEND_PORT=6001
|
||||
|
||||
ROOT_USERNAME=
|
||||
ROOT_USER_EMAIL=
|
||||
|
||||
@@ -11,3 +11,5 @@ REDIS_PASSWORD=coolify
|
||||
PUSHER_APP_ID=coolify
|
||||
PUSHER_APP_KEY=coolify
|
||||
PUSHER_APP_SECRET=coolify
|
||||
PUSHER_PORT=6001
|
||||
PUSHER_BACKEND_PORT=6001
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
package: ['coolify', 'coolify-helper', 'coolify-realtime', 'coolify-testing-host']
|
||||
package: ['coolify', 'coolify-helper', 'coolify-testing-host']
|
||||
steps:
|
||||
- name: Delete untagged ${{ matrix.package }} images
|
||||
uses: actions/delete-package-versions@v5
|
||||
|
||||
@@ -6,11 +6,8 @@ on:
|
||||
paths-ignore:
|
||||
- .github/workflows/coolify-helper.yml
|
||||
- .github/workflows/coolify-helper-next.yml
|
||||
- .github/workflows/coolify-realtime.yml
|
||||
- .github/workflows/coolify-realtime-next.yml
|
||||
- .github/workflows/pr-quality.yaml
|
||||
- docker/coolify-helper/Dockerfile
|
||||
- docker/coolify-realtime/Dockerfile
|
||||
- docker/testing-host/Dockerfile
|
||||
- templates/**
|
||||
- CHANGELOG.md
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
name: Coolify Realtime Development
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "next" ]
|
||||
paths:
|
||||
- .github/workflows/coolify-realtime-next.yml
|
||||
- docker/coolify-realtime/Dockerfile
|
||||
- docker/coolify-realtime/terminal-server.js
|
||||
- docker/coolify-realtime/package.json
|
||||
- docker/coolify-realtime/package-lock.json
|
||||
- docker/coolify-realtime/soketi-entrypoint.sh
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
env:
|
||||
GITHUB_REGISTRY: ghcr.io
|
||||
DOCKER_REGISTRY: docker.io
|
||||
IMAGE_NAME: "coollabsio/coolify-realtime"
|
||||
|
||||
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.GITHUB_REGISTRY }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.GITHUB_REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- 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: Get Version
|
||||
id: version
|
||||
run: |
|
||||
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getRealtimeVersion.php)"|xargs >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build and Push Image (${{ matrix.arch }})
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docker/coolify-realtime/Dockerfile
|
||||
platforms: ${{ matrix.platform }}
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-${{ matrix.arch }}
|
||||
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-${{ 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.GITHUB_REGISTRY }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.GITHUB_REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- 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: Get Version
|
||||
id: version
|
||||
run: |
|
||||
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getRealtimeVersion.php)"|xargs >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-amd64 \
|
||||
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
|
||||
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \
|
||||
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next
|
||||
|
||||
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-amd64 \
|
||||
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \
|
||||
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \
|
||||
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next
|
||||
|
||||
- uses: sarisia/actions-status-discord@v1
|
||||
if: always()
|
||||
with:
|
||||
webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }}
|
||||
@@ -1,120 +0,0 @@
|
||||
name: Coolify Realtime
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "v4.x" ]
|
||||
paths:
|
||||
- .github/workflows/coolify-realtime.yml
|
||||
- docker/coolify-realtime/Dockerfile
|
||||
- docker/coolify-realtime/terminal-server.js
|
||||
- docker/coolify-realtime/package.json
|
||||
- docker/coolify-realtime/package-lock.json
|
||||
- docker/coolify-realtime/soketi-entrypoint.sh
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
env:
|
||||
GITHUB_REGISTRY: ghcr.io
|
||||
DOCKER_REGISTRY: docker.io
|
||||
IMAGE_NAME: "coollabsio/coolify-realtime"
|
||||
|
||||
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.GITHUB_REGISTRY }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.GITHUB_REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- 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: Get Version
|
||||
id: version
|
||||
run: |
|
||||
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getRealtimeVersion.php)"|xargs >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build and Push Image (${{ matrix.arch }})
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docker/coolify-realtime/Dockerfile
|
||||
platforms: ${{ matrix.platform }}
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-${{ matrix.arch }}
|
||||
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-${{ 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.GITHUB_REGISTRY }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.GITHUB_REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- 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: Get Version
|
||||
id: version
|
||||
run: |
|
||||
echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getRealtimeVersion.php)"|xargs >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }}
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-amd64 \
|
||||
${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
|
||||
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
|
||||
--tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||
|
||||
- name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }}
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-amd64 \
|
||||
${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \
|
||||
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \
|
||||
--tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||
|
||||
- uses: sarisia/actions-status-discord@v1
|
||||
if: always()
|
||||
with:
|
||||
webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }}
|
||||
@@ -9,11 +9,8 @@ on:
|
||||
paths-ignore:
|
||||
- .github/workflows/coolify-helper.yml
|
||||
- .github/workflows/coolify-helper-next.yml
|
||||
- .github/workflows/coolify-realtime.yml
|
||||
- .github/workflows/coolify-realtime-next.yml
|
||||
- .github/workflows/pr-quality.yaml
|
||||
- docker/coolify-helper/Dockerfile
|
||||
- docker/coolify-realtime/Dockerfile
|
||||
- docker/testing-host/Dockerfile
|
||||
- templates/**
|
||||
- CHANGELOG.md
|
||||
|
||||
@@ -6,8 +6,6 @@ on:
|
||||
paths-ignore:
|
||||
- .github/workflows/coolify-helper.yml
|
||||
- .github/workflows/coolify-helper-next.yml
|
||||
- .github/workflows/coolify-realtime.yml
|
||||
- .github/workflows/coolify-realtime-next.yml
|
||||
- .github/workflows/pr-quality.yaml
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ _ide_helper_models.php
|
||||
scripts/load-test/*
|
||||
.ignition.json
|
||||
.env.dusk.local
|
||||
docker/coolify-realtime/node_modules
|
||||
docker/coolify-terminal/node_modules
|
||||
.DS_Store
|
||||
CHANGELOG.md
|
||||
/.workspaces
|
||||
|
||||
+1
-1
@@ -248,7 +248,7 @@ If you encounter issues or break your database or something else, follow these s
|
||||
|
||||
2. Remove all Coolify containers:
|
||||
```bash
|
||||
docker rm coolify coolify-db coolify-redis coolify-realtime coolify-testing-host coolify-minio coolify-vite-1 coolify-mail
|
||||
docker rm coolify coolify-db coolify-redis coolify-testing-host coolify-minio coolify-vite-1 coolify-mail
|
||||
```
|
||||
|
||||
3. Remove Coolify volumes (it is possible that the volumes have no `coolify` prefix on your machine, in that case remove the prefix from the command):
|
||||
|
||||
@@ -13,12 +13,6 @@ class CleanupDocker
|
||||
|
||||
public function handle(Server $server, bool $deleteUnusedVolumes = false, bool $deleteUnusedNetworks = false)
|
||||
{
|
||||
$realtimeImage = config('constants.coolify.realtime_image');
|
||||
$realtimeImageVersion = config('constants.coolify.realtime_version');
|
||||
$realtimeImageWithVersion = "$realtimeImage:$realtimeImageVersion";
|
||||
$realtimeImageWithoutPrefix = 'coollabsio/coolify-realtime';
|
||||
$realtimeImageWithoutPrefixVersion = "coollabsio/coolify-realtime:$realtimeImageVersion";
|
||||
|
||||
$helperImageVersion = getHelperVersion();
|
||||
$helperImage = config('constants.coolify.helper_image');
|
||||
$helperImageWithVersion = "$helperImage:$helperImageVersion";
|
||||
@@ -38,13 +32,12 @@ class CleanupDocker
|
||||
$cleanupLog = array_merge($cleanupLog, $applicationCleanupLog);
|
||||
|
||||
// Build image prune command that excludes application images and current Coolify infrastructure images
|
||||
// This ensures we clean up non-Coolify images while preserving rollback images and current helper/realtime images
|
||||
// This ensures we clean up non-Coolify images while preserving rollback images and current helper image
|
||||
// Note: Only the current version is protected; old versions will be cleaned up by explicit commands below
|
||||
// We pass the version strings so all registry variants are protected (ghcr.io, docker.io, no prefix)
|
||||
$imagePruneCmd = $this->buildImagePruneCommand(
|
||||
$applicationImageRepos,
|
||||
$helperImageVersion,
|
||||
$realtimeImageVersion
|
||||
$helperImageVersion
|
||||
);
|
||||
|
||||
$commands = [
|
||||
@@ -53,9 +46,7 @@ class CleanupDocker
|
||||
'docker builder prune -af',
|
||||
"docker run --rm -v \$HOME/.docker/buildx:/root/.docker/buildx -v /var/run/docker.sock:/var/run/docker.sock {$helperImageWithVersion} docker buildx prune --builder coolify-railpack -af 2>/dev/null || true",
|
||||
"docker images --filter before=$helperImageWithVersion --filter reference=$helperImage | grep $helperImage | awk '{print $3}' | xargs -r docker rmi -f",
|
||||
"docker images --filter before=$realtimeImageWithVersion --filter reference=$realtimeImage | grep $realtimeImage | awk '{print $3}' | xargs -r docker rmi -f",
|
||||
"docker images --filter before=$helperImageWithoutPrefixVersion --filter reference=$helperImageWithoutPrefix | grep $helperImageWithoutPrefix | awk '{print $3}' | xargs -r docker rmi -f",
|
||||
"docker images --filter before=$realtimeImageWithoutPrefixVersion --filter reference=$realtimeImageWithoutPrefix | grep $realtimeImageWithoutPrefix | awk '{print $3}' | xargs -r docker rmi -f",
|
||||
];
|
||||
|
||||
if ($deleteUnusedVolumes) {
|
||||
@@ -87,8 +78,7 @@ class CleanupDocker
|
||||
*/
|
||||
private function buildImagePruneCommand(
|
||||
$applicationImageRepos,
|
||||
string $helperImageVersion,
|
||||
string $realtimeImageVersion
|
||||
string $helperImageVersion
|
||||
): string {
|
||||
// Step 1: Always prune dangling images (untagged)
|
||||
$commands = ['docker image prune -f'];
|
||||
@@ -105,14 +95,13 @@ class CleanupDocker
|
||||
// - ghcr.io/coollabsio/coolify-helper:1.0.12
|
||||
// - docker.io/coollabsio/coolify-helper:1.0.12
|
||||
// - coollabsio/coolify-helper:1.0.12
|
||||
// Pattern: (^|/)coollabsio/coolify-(helper|realtime):VERSION$
|
||||
// Pattern: (^|/)coollabsio/coolify-helper:VERSION$
|
||||
$escapedHelperVersion = preg_replace('/([.\\\\+*?\[\]^$(){}|])/', '\\\\$1', $helperImageVersion);
|
||||
$escapedRealtimeVersion = preg_replace('/([.\\\\+*?\[\]^$(){}|])/', '\\\\$1', $realtimeImageVersion);
|
||||
$infraExcludePattern = "(^|/)coollabsio/coolify-helper:{$escapedHelperVersion}$|(^|/)coollabsio/coolify-realtime:{$escapedRealtimeVersion}$";
|
||||
$infraExcludePattern = "(^|/)coollabsio/coolify-helper:{$escapedHelperVersion}$";
|
||||
|
||||
// Delete unused images that:
|
||||
// - Are not application images (don't match app repos)
|
||||
// - Are not current Coolify infrastructure images (any registry)
|
||||
// - Are not current Coolify helper image (any registry)
|
||||
// - Don't have coolify.managed=true label
|
||||
// Images in use by containers will fail silently with docker rmi
|
||||
// Pattern matches both uuid:tag and uuid_servicename:tag (Docker Compose with build)
|
||||
|
||||
+29
-9
@@ -481,13 +481,20 @@ class Server extends BaseModel
|
||||
'service' => 'coolify',
|
||||
'rule' => "Host(`{$host}`)",
|
||||
],
|
||||
'coolify-realtime-ws' => [
|
||||
'coolify-reverb-ws' => [
|
||||
'entryPoints' => [
|
||||
0 => 'http',
|
||||
],
|
||||
'service' => 'coolify-realtime',
|
||||
'service' => 'coolify-reverb',
|
||||
'rule' => "Host(`{$host}`) && PathPrefix(`/app`)",
|
||||
],
|
||||
'coolify-reverb-api' => [
|
||||
'entryPoints' => [
|
||||
0 => 'http',
|
||||
],
|
||||
'service' => 'coolify-reverb',
|
||||
'rule' => "Host(`{$host}`) && PathPrefix(`/apps`)",
|
||||
],
|
||||
'coolify-terminal-ws' => [
|
||||
'entryPoints' => [
|
||||
0 => 'http',
|
||||
@@ -506,11 +513,11 @@ class Server extends BaseModel
|
||||
],
|
||||
],
|
||||
],
|
||||
'coolify-realtime' => [
|
||||
'coolify-reverb' => [
|
||||
'loadBalancer' => [
|
||||
'servers' => [
|
||||
0 => [
|
||||
'url' => 'http://coolify-realtime:6001',
|
||||
'url' => 'http://coolify:6001',
|
||||
],
|
||||
],
|
||||
],
|
||||
@@ -519,7 +526,7 @@ class Server extends BaseModel
|
||||
'loadBalancer' => [
|
||||
'servers' => [
|
||||
0 => [
|
||||
'url' => 'http://coolify-realtime:6002',
|
||||
'url' => 'http://coolify:6002',
|
||||
],
|
||||
],
|
||||
],
|
||||
@@ -543,16 +550,26 @@ class Server extends BaseModel
|
||||
'certresolver' => 'letsencrypt',
|
||||
],
|
||||
];
|
||||
$traefik_dynamic_conf['http']['routers']['coolify-realtime-wss'] = [
|
||||
$traefik_dynamic_conf['http']['routers']['coolify-reverb-wss'] = [
|
||||
'entryPoints' => [
|
||||
0 => 'https',
|
||||
],
|
||||
'service' => 'coolify-realtime',
|
||||
'service' => 'coolify-reverb',
|
||||
'rule' => "Host(`{$host}`) && PathPrefix(`/app`)",
|
||||
'tls' => [
|
||||
'certresolver' => 'letsencrypt',
|
||||
],
|
||||
];
|
||||
$traefik_dynamic_conf['http']['routers']['coolify-reverb-api-https'] = [
|
||||
'entryPoints' => [
|
||||
0 => 'https',
|
||||
],
|
||||
'service' => 'coolify-reverb',
|
||||
'rule' => "Host(`{$host}`) && PathPrefix(`/apps`)",
|
||||
'tls' => [
|
||||
'certresolver' => 'letsencrypt',
|
||||
],
|
||||
];
|
||||
$traefik_dynamic_conf['http']['routers']['coolify-terminal-wss'] = [
|
||||
'entryPoints' => [
|
||||
0 => 'https',
|
||||
@@ -590,10 +607,13 @@ class Server extends BaseModel
|
||||
$caddy_file = "
|
||||
$schema://$host {
|
||||
handle /app/* {
|
||||
reverse_proxy coolify-realtime:6001
|
||||
reverse_proxy coolify:6001
|
||||
}
|
||||
handle /apps* {
|
||||
reverse_proxy coolify:6001
|
||||
}
|
||||
handle /terminal/ws {
|
||||
reverse_proxy coolify-realtime:6002
|
||||
reverse_proxy coolify:6002
|
||||
}
|
||||
reverse_proxy coolify:8080
|
||||
}";
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
// To prevent github actions from failing
|
||||
function env()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$version = include 'config/constants.php';
|
||||
echo $version['coolify']['realtime_version'] ?: 'unknown';
|
||||
@@ -22,6 +22,7 @@
|
||||
"laravel/nightwatch": "^1.24",
|
||||
"laravel/pail": "^1.2.4",
|
||||
"laravel/prompts": "^0.3.11|^0.3.11|^0.3.11",
|
||||
"laravel/reverb": "^1.10",
|
||||
"laravel/sanctum": "^4.3.0",
|
||||
"laravel/socialite": "^5.24.2",
|
||||
"laravel/tinker": "^2.11.0",
|
||||
|
||||
Generated
+846
-1
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "64b77285a7140ce68e83db2659e9a21d",
|
||||
"content-hash": "31bd5f70ceaa27f7153302600b5cd453",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aws/aws-crt-php",
|
||||
@@ -341,6 +341,136 @@
|
||||
],
|
||||
"time": "2024-02-09T16:56:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "clue/redis-protocol",
|
||||
"version": "v0.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/clue/redis-protocol.git",
|
||||
"reference": "6f565332f5531b7722d1e9c445314b91862f6d6c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/clue/redis-protocol/zipball/6f565332f5531b7722d1e9c445314b91862f6d6c",
|
||||
"reference": "6f565332f5531b7722d1e9c445314b91862f6d6c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Clue\\Redis\\Protocol\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@lueck.tv"
|
||||
}
|
||||
],
|
||||
"description": "A streaming Redis protocol (RESP) parser and serializer written in pure PHP.",
|
||||
"homepage": "https://github.com/clue/redis-protocol",
|
||||
"keywords": [
|
||||
"parser",
|
||||
"protocol",
|
||||
"redis",
|
||||
"resp",
|
||||
"serializer",
|
||||
"streaming"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/clue/redis-protocol/issues",
|
||||
"source": "https://github.com/clue/redis-protocol/tree/v0.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://clue.engineering/support",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/clue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-08-07T11:06:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "clue/redis-react",
|
||||
"version": "v2.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/clue/reactphp-redis.git",
|
||||
"reference": "84569198dfd5564977d2ae6a32de4beb5a24bdca"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/clue/reactphp-redis/zipball/84569198dfd5564977d2ae6a32de4beb5a24bdca",
|
||||
"reference": "84569198dfd5564977d2ae6a32de4beb5a24bdca",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"clue/redis-protocol": "^0.3.2",
|
||||
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
|
||||
"php": ">=5.3",
|
||||
"react/event-loop": "^1.2",
|
||||
"react/promise": "^3.2 || ^2.0 || ^1.1",
|
||||
"react/promise-timer": "^1.11",
|
||||
"react/socket": "^1.16"
|
||||
},
|
||||
"require-dev": {
|
||||
"clue/block-react": "^1.5",
|
||||
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Clue\\React\\Redis\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering"
|
||||
}
|
||||
],
|
||||
"description": "Async Redis client implementation, built on top of ReactPHP.",
|
||||
"homepage": "https://github.com/clue/reactphp-redis",
|
||||
"keywords": [
|
||||
"async",
|
||||
"client",
|
||||
"database",
|
||||
"reactphp",
|
||||
"redis"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/clue/reactphp-redis/issues",
|
||||
"source": "https://github.com/clue/reactphp-redis/tree/v2.8.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://clue.engineering/support",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/clue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-01-03T16:18:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "danharrin/livewire-rate-limiting",
|
||||
"version": "v2.2.0",
|
||||
@@ -972,6 +1102,53 @@
|
||||
],
|
||||
"time": "2025-03-06T22:45:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "evenement/evenement",
|
||||
"version": "v3.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/igorw/evenement.git",
|
||||
"reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc",
|
||||
"reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9 || ^6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Evenement\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Igor Wiedler",
|
||||
"email": "igor@wiedler.ch"
|
||||
}
|
||||
],
|
||||
"description": "Événement is a very simple event dispatching library for PHP",
|
||||
"keywords": [
|
||||
"event-dispatcher",
|
||||
"event-emitter"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/igorw/evenement/issues",
|
||||
"source": "https://github.com/igorw/evenement/tree/v3.0.2"
|
||||
},
|
||||
"time": "2023-08-08T05:53:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ezyang/htmlpurifier",
|
||||
"version": "v4.19.0",
|
||||
@@ -2443,6 +2620,85 @@
|
||||
},
|
||||
"time": "2026-05-19T00:47:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/reverb",
|
||||
"version": "v1.10.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/reverb.git",
|
||||
"reference": "43a5c0a99b1aaba33dc32f97fcf51f182dd8c8ac"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/reverb/zipball/43a5c0a99b1aaba33dc32f97fcf51f182dd8c8ac",
|
||||
"reference": "43a5c0a99b1aaba33dc32f97fcf51f182dd8c8ac",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"clue/redis-react": "^2.6",
|
||||
"guzzlehttp/psr7": "^2.6",
|
||||
"illuminate/console": "^10.47|^11.0|^12.0|^13.0",
|
||||
"illuminate/contracts": "^10.47|^11.0|^12.0|^13.0",
|
||||
"illuminate/http": "^10.47|^11.0|^12.0|^13.0",
|
||||
"illuminate/support": "^10.47|^11.0|^12.0|^13.0",
|
||||
"laravel/prompts": "^0.1.15|^0.2.0|^0.3.0",
|
||||
"php": "^8.2",
|
||||
"pusher/pusher-php-server": "^7.2",
|
||||
"ratchet/rfc6455": "^0.4",
|
||||
"react/promise-timer": "^1.10",
|
||||
"react/socket": "^1.14",
|
||||
"symfony/console": "^6.0|^7.0|^8.0",
|
||||
"symfony/http-foundation": "^6.3|^7.0|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^8.36|^9.15|^10.8|^11.0",
|
||||
"pestphp/pest": "^2.0|^3.0|^4.0",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"ratchet/pawl": "^0.4.1",
|
||||
"react/async": "^4.2",
|
||||
"react/http": "^1.9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Reverb\\ApplicationManagerServiceProvider",
|
||||
"Laravel\\Reverb\\ReverbServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Reverb\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
},
|
||||
{
|
||||
"name": "Joe Dixon",
|
||||
"email": "joe@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "Laravel Reverb provides a real-time WebSocket communication backend for Laravel applications.",
|
||||
"keywords": [
|
||||
"WebSockets",
|
||||
"laravel",
|
||||
"real-time",
|
||||
"websocket"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/reverb/issues",
|
||||
"source": "https://github.com/laravel/reverb/tree/v1.10.2"
|
||||
},
|
||||
"time": "2026-05-10T15:47:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/sanctum",
|
||||
"version": "v4.3.2",
|
||||
@@ -6293,6 +6549,595 @@
|
||||
},
|
||||
"time": "2025-12-14T04:43:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ratchet/rfc6455",
|
||||
"version": "v0.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ratchetphp/RFC6455.git",
|
||||
"reference": "859d95f85dda0912c6d5b936d036d044e3af47ef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/859d95f85dda0912c6d5b936d036d044e3af47ef",
|
||||
"reference": "859d95f85dda0912c6d5b936d036d044e3af47ef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"psr/http-factory-implementation": "^1.0",
|
||||
"symfony/polyfill-php80": "^1.15"
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/psr7": "^2.7",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"react/socket": "^1.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Ratchet\\RFC6455\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Matt Bonneau",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "RFC6455 WebSocket protocol handler",
|
||||
"homepage": "http://socketo.me",
|
||||
"keywords": [
|
||||
"WebSockets",
|
||||
"rfc6455",
|
||||
"websocket"
|
||||
],
|
||||
"support": {
|
||||
"chat": "https://gitter.im/reactphp/reactphp",
|
||||
"issues": "https://github.com/ratchetphp/RFC6455/issues",
|
||||
"source": "https://github.com/ratchetphp/RFC6455/tree/v0.4.0"
|
||||
},
|
||||
"time": "2025-02-24T01:18:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/cache",
|
||||
"version": "v1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/cache.git",
|
||||
"reference": "d47c472b64aa5608225f47965a484b75c7817d5b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b",
|
||||
"reference": "d47c472b64aa5608225f47965a484b75c7817d5b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"react/promise": "^3.0 || ^2.0 || ^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Cache\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "Async, Promise-based cache interface for ReactPHP",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching",
|
||||
"promise",
|
||||
"reactphp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/cache/issues",
|
||||
"source": "https://github.com/reactphp/cache/tree/v1.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/reactphp",
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-30T15:59:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/dns",
|
||||
"version": "v1.14.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/dns.git",
|
||||
"reference": "7562c05391f42701c1fccf189c8225fece1cd7c3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/dns/zipball/7562c05391f42701c1fccf189c8225fece1cd7c3",
|
||||
"reference": "7562c05391f42701c1fccf189c8225fece1cd7c3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"react/cache": "^1.0 || ^0.6 || ^0.5",
|
||||
"react/event-loop": "^1.2",
|
||||
"react/promise": "^3.2 || ^2.7 || ^1.2.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
|
||||
"react/async": "^4.3 || ^3 || ^2",
|
||||
"react/promise-timer": "^1.11"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Dns\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "Async DNS resolver for ReactPHP",
|
||||
"keywords": [
|
||||
"async",
|
||||
"dns",
|
||||
"dns-resolver",
|
||||
"reactphp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/dns/issues",
|
||||
"source": "https://github.com/reactphp/dns/tree/v1.14.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/reactphp",
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-18T19:34:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/event-loop",
|
||||
"version": "v1.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/event-loop.git",
|
||||
"reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/event-loop/zipball/ba276bda6083df7e0050fd9b33f66ad7a4ac747a",
|
||||
"reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pcntl": "For signal handling support when using the StreamSelectLoop"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\EventLoop\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.",
|
||||
"keywords": [
|
||||
"asynchronous",
|
||||
"event-loop"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/event-loop/issues",
|
||||
"source": "https://github.com/reactphp/event-loop/tree/v1.6.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/reactphp",
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-17T20:46:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/promise",
|
||||
"version": "v3.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/promise.git",
|
||||
"reference": "23444f53a813a3296c1368bb104793ce8d88f04a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a",
|
||||
"reference": "23444f53a813a3296c1368bb104793ce8d88f04a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.12.28 || 1.4.10",
|
||||
"phpunit/phpunit": "^9.6 || ^7.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"React\\Promise\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
|
||||
"keywords": [
|
||||
"promise",
|
||||
"promises"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/promise/issues",
|
||||
"source": "https://github.com/reactphp/promise/tree/v3.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/reactphp",
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-19T18:57:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/promise-timer",
|
||||
"version": "v1.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/promise-timer.git",
|
||||
"reference": "4f70306ed66b8b44768941ca7f142092600fafc1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/promise-timer/zipball/4f70306ed66b8b44768941ca7f142092600fafc1",
|
||||
"reference": "4f70306ed66b8b44768941ca7f142092600fafc1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3",
|
||||
"react/event-loop": "^1.2",
|
||||
"react/promise": "^3.2 || ^2.7.0 || ^1.2.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"React\\Promise\\Timer\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.",
|
||||
"homepage": "https://github.com/reactphp/promise-timer",
|
||||
"keywords": [
|
||||
"async",
|
||||
"event-loop",
|
||||
"promise",
|
||||
"reactphp",
|
||||
"timeout",
|
||||
"timer"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/promise-timer/issues",
|
||||
"source": "https://github.com/reactphp/promise-timer/tree/v1.11.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/reactphp",
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2024-06-04T14:27:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/socket",
|
||||
"version": "v1.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/socket.git",
|
||||
"reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/socket/zipball/ef5b17b81f6f60504c539313f94f2d826c5faa08",
|
||||
"reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
|
||||
"php": ">=5.3.0",
|
||||
"react/dns": "^1.13",
|
||||
"react/event-loop": "^1.2",
|
||||
"react/promise": "^3.2 || ^2.6 || ^1.2.1",
|
||||
"react/stream": "^1.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
|
||||
"react/async": "^4.3 || ^3.3 || ^2",
|
||||
"react/promise-stream": "^1.4",
|
||||
"react/promise-timer": "^1.11"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Socket\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
|
||||
"keywords": [
|
||||
"Connection",
|
||||
"Socket",
|
||||
"async",
|
||||
"reactphp",
|
||||
"stream"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/socket/issues",
|
||||
"source": "https://github.com/reactphp/socket/tree/v1.17.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/reactphp",
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-19T20:47:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/stream",
|
||||
"version": "v1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/stream.git",
|
||||
"reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d",
|
||||
"reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
|
||||
"php": ">=5.3.8",
|
||||
"react/event-loop": "^1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"clue/stream-filter": "~1.2",
|
||||
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Stream\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP",
|
||||
"keywords": [
|
||||
"event-driven",
|
||||
"io",
|
||||
"non-blocking",
|
||||
"pipe",
|
||||
"reactphp",
|
||||
"readable",
|
||||
"stream",
|
||||
"writable"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/stream/issues",
|
||||
"source": "https://github.com/reactphp/stream/tree/v1.4.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/reactphp",
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2024-06-11T12:45:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "resend/resend-laravel",
|
||||
"version": "v0.20.0",
|
||||
|
||||
+23
-5
@@ -11,11 +11,11 @@ return [
|
||||
| framework when an event needs to be broadcast. You may set this to
|
||||
| any of the connections defined in the "connections" array below.
|
||||
|
|
||||
| Supported: "pusher", "ably", "redis", "log", "null"
|
||||
| Supported: "reverb", "pusher", "ably", "redis", "log", "null"
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('BROADCAST_DRIVER', 'pusher'),
|
||||
'default' => env('BROADCAST_CONNECTION', env('BROADCAST_DRIVER', 'reverb')),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -30,15 +30,33 @@ return [
|
||||
|
||||
'connections' => [
|
||||
|
||||
'reverb' => [
|
||||
'driver' => 'reverb',
|
||||
'key' => env('PUSHER_APP_KEY', 'coolify'),
|
||||
'secret' => env('PUSHER_APP_SECRET', 'coolify'),
|
||||
'app_id' => env('PUSHER_APP_ID', 'coolify'),
|
||||
'options' => [
|
||||
'host' => env('PUSHER_HOST', 'coolify'),
|
||||
'port' => env('PUSHER_BACKEND_PORT', 6001),
|
||||
'scheme' => env('PUSHER_SCHEME', 'http'),
|
||||
'encrypted' => true,
|
||||
'useTLS' => env('PUSHER_SCHEME', 'http') === 'https',
|
||||
'path' => '',
|
||||
],
|
||||
'client_options' => [
|
||||
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
|
||||
],
|
||||
],
|
||||
|
||||
'pusher' => [
|
||||
'driver' => 'pusher',
|
||||
'key' => env('PUSHER_APP_KEY', 'coolify'),
|
||||
'secret' => env('PUSHER_APP_SECRET', 'coolify'),
|
||||
'app_id' => env('PUSHER_APP_ID', 'coolify'),
|
||||
'options' => [
|
||||
'host' => env('PUSHER_BACKEND_HOST', 'coolify-realtime'),
|
||||
'port' => env('PUSHER_BACKEND_PORT', 6001),
|
||||
'scheme' => env('PUSHER_SCHEME', 'http'),
|
||||
'host' => env('PUSHER_HOST'),
|
||||
'port' => env('PUSHER_PORT', 443),
|
||||
'scheme' => env('PUSHER_SCHEME', 'https'),
|
||||
'encrypted' => true,
|
||||
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
|
||||
],
|
||||
|
||||
@@ -4,14 +4,12 @@ return [
|
||||
'coolify' => [
|
||||
'version' => '4.1.2',
|
||||
'helper_version' => '1.0.14',
|
||||
'realtime_version' => '1.0.16',
|
||||
'railpack_version' => '0.23.0',
|
||||
'self_hosted' => env('SELF_HOSTED', true),
|
||||
'autoupdate' => env('AUTOUPDATE'),
|
||||
'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'),
|
||||
'registry_url' => env('REGISTRY_URL', 'ghcr.io'),
|
||||
'helper_image' => env('HELPER_IMAGE', env('REGISTRY_URL', 'ghcr.io').'/coollabsio/coolify-helper'),
|
||||
'realtime_image' => env('REALTIME_IMAGE', env('REGISTRY_URL', 'ghcr.io').'/coollabsio/coolify-realtime'),
|
||||
'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'),
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Reverb Server
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default server used by Reverb to handle
|
||||
| incoming messages as well as broadcasting message to all your
|
||||
| connected clients. At this time only "reverb" is supported.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => 'reverb',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Reverb Servers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define details for each of the supported Reverb servers.
|
||||
| Each server has its own configuration options that are defined in
|
||||
| the array below. You should ensure all the options are present.
|
||||
|
|
||||
*/
|
||||
|
||||
'servers' => [
|
||||
|
||||
'reverb' => [
|
||||
'host' => '0.0.0.0',
|
||||
'port' => env('PUSHER_BACKEND_PORT', 6001),
|
||||
'path' => '',
|
||||
'hostname' => env('PUSHER_HOST'),
|
||||
'options' => [
|
||||
'tls' => [],
|
||||
],
|
||||
'max_request_size' => 10_000,
|
||||
'scaling' => [
|
||||
'enabled' => false,
|
||||
'channel' => 'reverb',
|
||||
'server' => [
|
||||
'url' => env('REDIS_URL'),
|
||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||
'port' => env('REDIS_PORT', '6379'),
|
||||
'username' => env('REDIS_USERNAME'),
|
||||
'password' => env('REDIS_PASSWORD'),
|
||||
'database' => env('REDIS_DB', '0'),
|
||||
'timeout' => env('REDIS_TIMEOUT', 60),
|
||||
],
|
||||
],
|
||||
'pulse_ingest_interval' => 15,
|
||||
'telescope_ingest_interval' => 15,
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Reverb Applications
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define how Reverb applications are managed. If you choose
|
||||
| to use the "config" provider, you may define an array of apps which
|
||||
| your server will support, including their connection credentials.
|
||||
|
|
||||
*/
|
||||
|
||||
'apps' => [
|
||||
|
||||
'provider' => 'config',
|
||||
|
||||
'apps' => [
|
||||
[
|
||||
'key' => env('PUSHER_APP_KEY', 'coolify'),
|
||||
'secret' => env('PUSHER_APP_SECRET', 'coolify'),
|
||||
'app_id' => env('PUSHER_APP_ID', 'coolify'),
|
||||
'options' => [
|
||||
'host' => env('PUSHER_HOST', 'coolify'),
|
||||
'port' => env('PUSHER_PORT', 6001),
|
||||
'scheme' => env('PUSHER_SCHEME', 'http'),
|
||||
'useTLS' => env('PUSHER_SCHEME', 'http') === 'https',
|
||||
],
|
||||
'allowed_origins' => ['*'],
|
||||
'ping_interval' => 60,
|
||||
'activity_timeout' => 30,
|
||||
'max_connections' => null,
|
||||
'max_message_size' => 10_000,
|
||||
'accept_client_events_from' => 'members',
|
||||
'rate_limiting' => [
|
||||
'enabled' => false,
|
||||
'max_attempts' => 60,
|
||||
'decay_seconds' => 60,
|
||||
'terminate_on_limit' => false,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
@@ -10,10 +10,13 @@ services:
|
||||
- GROUP_ID=${GROUPID:-1000}
|
||||
ports:
|
||||
- "${APP_PORT:-8000}:8080"
|
||||
- "${FORWARD_PUSHER_PORT:-6001}:6001"
|
||||
- "6002:6002"
|
||||
environment:
|
||||
AUTORUN_ENABLED: false
|
||||
PUSHER_HOST: "${PUSHER_HOST}"
|
||||
PUSHER_PORT: "${PUSHER_PORT}"
|
||||
PUSHER_HOST: "${PUSHER_HOST:-coolify}"
|
||||
PUSHER_PORT: "${PUSHER_PORT:-6001}"
|
||||
PUSHER_BACKEND_PORT: "${PUSHER_BACKEND_PORT:-6001}"
|
||||
PUSHER_SCHEME: "${PUSHER_SCHEME:-http}"
|
||||
PUSHER_APP_ID: "${PUSHER_APP_ID:-coolify}"
|
||||
PUSHER_APP_KEY: "${PUSHER_APP_KEY:-coolify}"
|
||||
@@ -26,6 +29,8 @@ services:
|
||||
volumes:
|
||||
- .:/var/www/html/:cached
|
||||
- dev_backups_data:/var/www/html/storage/app/backups
|
||||
- ./docker/coolify-terminal/terminal-server.js:/terminal/terminal-server.js
|
||||
- ./docker/coolify-terminal/terminal-utils.js:/terminal/terminal-utils.js
|
||||
networks:
|
||||
- coolify
|
||||
postgres:
|
||||
@@ -59,33 +64,7 @@ services:
|
||||
timeout: 2s
|
||||
volumes:
|
||||
- dev_redis_data:/data
|
||||
soketi:
|
||||
image: coolify-realtime:dev
|
||||
pull_policy: never
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./docker/coolify-realtime/Dockerfile
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "${FORWARD_SOKETI_PORT:-6001}:6001"
|
||||
- "6002:6002"
|
||||
volumes:
|
||||
- ./storage:/var/www/html/storage
|
||||
- ./docker/coolify-realtime/terminal-server.js:/terminal/terminal-server.js
|
||||
- ./docker/coolify-realtime/terminal-utils.js:/terminal/terminal-utils.js
|
||||
environment:
|
||||
SOKETI_DEBUG: "false"
|
||||
SOKETI_DEFAULT_APP_ID: "${PUSHER_APP_ID:-coolify}"
|
||||
SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY:-coolify}"
|
||||
SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET:-coolify}"
|
||||
SOKETI_HOST: "${SOKETI_HOST:-0.0.0.0}"
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "curl -fsS http://127.0.0.1:6001/ready && curl -fsS http://127.0.0.1:6002/ready || exit 1" ]
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
entrypoint: ["/bin/sh", "/soketi-entrypoint.sh"]
|
||||
|
||||
vite:
|
||||
image: node:24-alpine
|
||||
pull_policy: always
|
||||
|
||||
+8
-29
@@ -10,10 +10,13 @@ services:
|
||||
- GROUP_ID=${GROUPID:-1000}
|
||||
ports:
|
||||
- "${APP_PORT:-8000}:8080"
|
||||
- "${FORWARD_PUSHER_PORT:-6001}:6001"
|
||||
- "6002:6002"
|
||||
environment:
|
||||
AUTORUN_ENABLED: false
|
||||
PUSHER_HOST: "${PUSHER_HOST}"
|
||||
PUSHER_PORT: "${PUSHER_PORT}"
|
||||
PUSHER_HOST: "${PUSHER_HOST:-coolify}"
|
||||
PUSHER_PORT: "${PUSHER_PORT:-6001}"
|
||||
PUSHER_BACKEND_PORT: "${PUSHER_BACKEND_PORT:-6001}"
|
||||
PUSHER_SCHEME: "${PUSHER_SCHEME:-http}"
|
||||
PUSHER_APP_ID: "${PUSHER_APP_ID:-coolify}"
|
||||
PUSHER_APP_KEY: "${PUSHER_APP_KEY:-coolify}"
|
||||
@@ -26,6 +29,8 @@ services:
|
||||
volumes:
|
||||
- .:/var/www/html/:cached
|
||||
- dev_backups_data:/var/www/html/storage/app/backups
|
||||
- ./docker/coolify-terminal/terminal-server.js:/terminal/terminal-server.js
|
||||
- ./docker/coolify-terminal/terminal-utils.js:/terminal/terminal-utils.js
|
||||
networks:
|
||||
- coolify
|
||||
postgres:
|
||||
@@ -59,33 +64,7 @@ services:
|
||||
timeout: 2s
|
||||
volumes:
|
||||
- dev_redis_data:/data
|
||||
soketi:
|
||||
image: coolify-realtime:dev
|
||||
pull_policy: never
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./docker/coolify-realtime/Dockerfile
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "${FORWARD_SOKETI_PORT:-6001}:6001"
|
||||
- "6002:6002"
|
||||
volumes:
|
||||
- ./storage:/var/www/html/storage
|
||||
- ./docker/coolify-realtime/terminal-server.js:/terminal/terminal-server.js
|
||||
- ./docker/coolify-realtime/terminal-utils.js:/terminal/terminal-utils.js
|
||||
environment:
|
||||
SOKETI_DEBUG: "false"
|
||||
SOKETI_DEFAULT_APP_ID: "${PUSHER_APP_ID:-coolify}"
|
||||
SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY:-coolify}"
|
||||
SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET:-coolify}"
|
||||
SOKETI_HOST: "${SOKETI_HOST:-0.0.0.0}"
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "curl -fsS http://127.0.0.1:6001/ready && curl -fsS http://127.0.0.1:6002/ready || exit 1" ]
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
entrypoint: ["/bin/sh", "/soketi-entrypoint.sh"]
|
||||
|
||||
vite:
|
||||
image: node:24-alpine
|
||||
pull_policy: always
|
||||
|
||||
+6
-22
@@ -18,12 +18,18 @@ services:
|
||||
- PHP_FPM_PM_START_SERVERS=${PHP_FPM_PM_START_SERVERS:-1}
|
||||
- PHP_FPM_PM_MIN_SPARE_SERVERS=${PHP_FPM_PM_MIN_SPARE_SERVERS:-1}
|
||||
- PHP_FPM_PM_MAX_SPARE_SERVERS=${PHP_FPM_PM_MAX_SPARE_SERVERS:-10}
|
||||
- PUSHER_PORT=${PUSHER_PORT:-6001}
|
||||
- PUSHER_BACKEND_PORT=${PUSHER_BACKEND_PORT:-6001}
|
||||
env_file:
|
||||
- /data/coolify/source/.env
|
||||
ports:
|
||||
- "${APP_PORT:-8000}:8080"
|
||||
- "${PUSHER_PORT:-6001}:6001"
|
||||
- "${TERMINAL_PORT:-6002}:6002"
|
||||
expose:
|
||||
- "${APP_PORT:-8000}"
|
||||
- "${PUSHER_PORT:-6001}"
|
||||
- "${TERMINAL_PORT:-6002}"
|
||||
healthcheck:
|
||||
test: curl --fail http://127.0.0.1:8080/api/health || exit 1
|
||||
interval: 5s
|
||||
@@ -34,8 +40,6 @@ services:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
soketi:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
volumes:
|
||||
- coolify-db:/var/lib/postgresql/data
|
||||
@@ -59,26 +63,6 @@ services:
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
soketi:
|
||||
image: '${REGISTRY_URL:-ghcr.io}/coollabsio/coolify-realtime:1.0.16'
|
||||
ports:
|
||||
- "${SOKETI_PORT:-6001}:6001"
|
||||
- "6002:6002"
|
||||
volumes:
|
||||
- /data/coolify/ssh:/var/www/html/storage/app/ssh
|
||||
environment:
|
||||
APP_NAME: "${APP_NAME:-Coolify}"
|
||||
SOKETI_DEBUG: "${SOKETI_DEBUG:-false}"
|
||||
SOKETI_DEFAULT_APP_ID: "${PUSHER_APP_ID}"
|
||||
SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY}"
|
||||
SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET}"
|
||||
SOKETI_HOST: "${SOKETI_HOST:-0.0.0.0}"
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "wget -qO- http://127.0.0.1:6001/ready && wget -qO- http://127.0.0.1:6002/ready || exit 1" ]
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
|
||||
volumes:
|
||||
coolify-db:
|
||||
name: coolify-db
|
||||
|
||||
@@ -42,14 +42,20 @@ services:
|
||||
- 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"
|
||||
- "${PUSHER_PORT:-6001}:6001"
|
||||
- "${TERMINAL_PORT:-6002}:6002"
|
||||
expose:
|
||||
- "${APP_PORT:-8000}"
|
||||
- "${PUSHER_PORT:-6001}"
|
||||
- "${TERMINAL_PORT:-6002}"
|
||||
healthcheck:
|
||||
test: curl --fail http://localhost:8080/api/health || exit 1
|
||||
interval: 5s
|
||||
@@ -95,30 +101,7 @@ services:
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
soketi:
|
||||
image: 'ghcr.io/coollabsio/coolify-realtime:1.0.16'
|
||||
pull_policy: always
|
||||
container_name: coolify-realtime
|
||||
restart: always
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "${SOKETI_PORT:-6001}:6001"
|
||||
- "6002:6002"
|
||||
volumes:
|
||||
- ./ssh:/var/www/html/storage/app/ssh
|
||||
environment:
|
||||
APP_NAME: "${APP_NAME:-Coolify}"
|
||||
SOKETI_DEBUG: "${SOKETI_DEBUG:-false}"
|
||||
SOKETI_DEFAULT_APP_ID: "${PUSHER_APP_ID}"
|
||||
SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY}"
|
||||
SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET}"
|
||||
SOKETI_HOST: "${SOKETI_HOST:-0.0.0.0}"
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "wget -qO- http://127.0.0.1:6001/ready && wget -qO- http://127.0.0.1:6002/ready || exit 1" ]
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
|
||||
|
||||
volumes:
|
||||
coolify-db:
|
||||
|
||||
+3
-8
@@ -5,12 +5,14 @@ services:
|
||||
working_dir: /var/www/html
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
expose:
|
||||
- "6001"
|
||||
- "6002"
|
||||
networks:
|
||||
- coolify
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
- soketi
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: coolify-db
|
||||
@@ -23,13 +25,6 @@ services:
|
||||
restart: always
|
||||
networks:
|
||||
- coolify
|
||||
soketi:
|
||||
container_name: coolify-realtime
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
restart: always
|
||||
networks:
|
||||
- coolify
|
||||
networks:
|
||||
coolify:
|
||||
name: coolify
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
# Versions
|
||||
# https://github.com/soketi/soketi/releases
|
||||
ARG SOKETI_VERSION=1.6-16-alpine
|
||||
# https://github.com/cloudflare/cloudflared/releases
|
||||
ARG CLOUDFLARED_VERSION=2025.7.0
|
||||
|
||||
FROM quay.io/soketi/soketi:${SOKETI_VERSION}
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
ARG CLOUDFLARED_VERSION
|
||||
|
||||
WORKDIR /terminal
|
||||
RUN apk upgrade --no-cache && \
|
||||
apk add --no-cache openssh-client make g++ python3 curl
|
||||
COPY docker/coolify-realtime/package*.json ./
|
||||
RUN npm ci
|
||||
RUN npm rebuild node-pty --update-binary
|
||||
COPY docker/coolify-realtime/soketi-entrypoint.sh /soketi-entrypoint.sh
|
||||
COPY docker/coolify-realtime/terminal-server.js /terminal/terminal-server.js
|
||||
COPY docker/coolify-realtime/terminal-utils.js /terminal/terminal-utils.js
|
||||
|
||||
# Install Cloudflared based on architecture
|
||||
RUN if [ "${TARGETPLATFORM}" = "linux/amd64" ]; then \
|
||||
curl -sSL "https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-amd64" -o /usr/local/bin/cloudflared; \
|
||||
elif [ "${TARGETPLATFORM}" = "linux/arm64" ]; then \
|
||||
curl -sSL "https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-arm64" -o /usr/local/bin/cloudflared; \
|
||||
fi && \
|
||||
chmod +x /usr/local/bin/cloudflared
|
||||
|
||||
ENTRYPOINT ["/bin/sh", "/soketi-entrypoint.sh"]
|
||||
@@ -1,91 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$1" = "watch" ]; then
|
||||
WATCH_MODE="--watch"
|
||||
else
|
||||
WATCH_MODE=""
|
||||
fi
|
||||
|
||||
log() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') [ENTRYPOINT] $*"
|
||||
}
|
||||
|
||||
start_logger() {
|
||||
prefix="$1"
|
||||
fifo_path="$2"
|
||||
|
||||
while read -r line; do
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') [$prefix] $line"
|
||||
done < "$fifo_path" &
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
rm -f "$TERMINAL_LOG_FIFO" "$SOKETI_LOG_FIFO"
|
||||
}
|
||||
|
||||
TERMINAL_LOG_FIFO="/tmp/coolify-terminal-log.$$"
|
||||
SOKETI_LOG_FIFO="/tmp/coolify-soketi-log.$$"
|
||||
|
||||
rm -f "$TERMINAL_LOG_FIFO" "$SOKETI_LOG_FIFO"
|
||||
mkfifo "$TERMINAL_LOG_FIFO" "$SOKETI_LOG_FIFO"
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
log "Starting realtime container"
|
||||
log "WATCH_MODE=${WATCH_MODE:-off}"
|
||||
log "SOKETI_DEBUG=${SOKETI_DEBUG:-unset}"
|
||||
log "NODE_OPTIONS=${NODE_OPTIONS:-unset}"
|
||||
|
||||
start_logger "TERMINAL" "$TERMINAL_LOG_FIFO"
|
||||
TERMINAL_LOGGER_PID=$!
|
||||
|
||||
start_logger "SOKETI" "$SOKETI_LOG_FIFO"
|
||||
SOKETI_LOGGER_PID=$!
|
||||
|
||||
node $WATCH_MODE /terminal/terminal-server.js > "$TERMINAL_LOG_FIFO" 2>&1 &
|
||||
TERMINAL_PID=$!
|
||||
|
||||
log "Terminal server started pid=$TERMINAL_PID logger_pid=$TERMINAL_LOGGER_PID"
|
||||
|
||||
node /app/bin/server.js start > "$SOKETI_LOG_FIFO" 2>&1 &
|
||||
SOKETI_PID=$!
|
||||
|
||||
log "Soketi started pid=$SOKETI_PID logger_pid=$SOKETI_LOGGER_PID"
|
||||
|
||||
forward_signal() {
|
||||
log "Forwarding signal $1 to terminal=$TERMINAL_PID soketi=$SOKETI_PID"
|
||||
|
||||
kill -"$1" "$TERMINAL_PID" 2>/dev/null || true
|
||||
kill -"$1" "$SOKETI_PID" 2>/dev/null || true
|
||||
}
|
||||
|
||||
trap 'forward_signal TERM' TERM
|
||||
trap 'forward_signal INT' INT
|
||||
|
||||
while true; do
|
||||
if ! kill -0 "$TERMINAL_PID" 2>/dev/null; then
|
||||
wait "$TERMINAL_PID"
|
||||
EXIT_CODE=$?
|
||||
|
||||
log "Terminal server exited code=$EXIT_CODE; stopping soketi pid=$SOKETI_PID"
|
||||
|
||||
kill "$SOKETI_PID" 2>/dev/null || true
|
||||
wait "$SOKETI_PID" 2>/dev/null || true
|
||||
|
||||
exit "$EXIT_CODE"
|
||||
fi
|
||||
|
||||
if ! kill -0 "$SOKETI_PID" 2>/dev/null; then
|
||||
wait "$SOKETI_PID"
|
||||
EXIT_CODE=$?
|
||||
|
||||
log "Soketi exited code=$EXIT_CODE; stopping terminal pid=$TERMINAL_PID"
|
||||
|
||||
kill "$TERMINAL_PID" 2>/dev/null || true
|
||||
wait "$TERMINAL_PID" 2>/dev/null || true
|
||||
|
||||
exit "$EXIT_CODE"
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
done
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "coolify-realtime",
|
||||
"name": "coolify-terminal",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
+1
-1
@@ -15,7 +15,7 @@ import {
|
||||
async function postToCoolify(path, headers) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = http.request({
|
||||
hostname: 'coolify',
|
||||
hostname: process.env.TERMINAL_AUTH_HOST || '127.0.0.1',
|
||||
port: 8080,
|
||||
path,
|
||||
method: 'POST',
|
||||
@@ -57,6 +57,11 @@ RUN apk upgrade --no-cache && \
|
||||
# Install system dependencies
|
||||
RUN apk add --no-cache \
|
||||
postgresql${POSTGRES_VERSION}-client \
|
||||
nodejs \
|
||||
npm \
|
||||
make \
|
||||
g++ \
|
||||
python3 \
|
||||
openssh-client \
|
||||
git \
|
||||
git-lfs \
|
||||
@@ -85,6 +90,14 @@ RUN mkdir -p /usr/local/bin && \
|
||||
COPY docker/development/etc/php/conf.d/zzz-custom-php.ini /usr/local/etc/php/conf.d/zzz-custom-php.ini
|
||||
ENV PHP_OPCACHE_ENABLE=0
|
||||
|
||||
# Install terminal WebSocket server dependencies
|
||||
COPY docker/coolify-terminal/package*.json /terminal/
|
||||
RUN npm ci --prefix /terminal && \
|
||||
npm rebuild node-pty --prefix /terminal --update-binary
|
||||
COPY docker/coolify-terminal/terminal-server.js /terminal/terminal-server.js
|
||||
COPY docker/coolify-terminal/terminal-utils.js /terminal/terminal-utils.js
|
||||
RUN chown -R www-data:www-data /terminal
|
||||
|
||||
# Configure Nginx and S6 overlay
|
||||
COPY docker/development/etc/nginx/conf.d/custom.conf /etc/nginx/conf.d/custom.conf
|
||||
COPY docker/development/etc/nginx/site-opts.d/http.conf /etc/nginx/site-opts.d/http.conf
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd /var/www/html
|
||||
|
||||
if grep -qE '^PUSHER_ENABLED=false' .env 2>/dev/null; then
|
||||
echo " INFO Reverb is disabled, sleeping."
|
||||
exec sleep infinity
|
||||
fi
|
||||
|
||||
echo " INFO Reverb is enabled, starting..."
|
||||
exec php artisan reverb:start --host=0.0.0.0 --port=${PUSHER_BACKEND_PORT:-6001}
|
||||
@@ -0,0 +1 @@
|
||||
longrun
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd /var/www/html
|
||||
|
||||
echo " INFO Terminal WebSocket server is starting..."
|
||||
exec node /terminal/terminal-server.js
|
||||
@@ -0,0 +1 @@
|
||||
longrun
|
||||
@@ -107,6 +107,11 @@ RUN --mount=type=cache,target=/var/cache/apk \
|
||||
apk upgrade && \
|
||||
apk add --no-cache \
|
||||
postgresql${POSTGRES_VERSION}-client \
|
||||
nodejs \
|
||||
npm \
|
||||
make \
|
||||
g++ \
|
||||
python3 \
|
||||
openssh-client \
|
||||
git \
|
||||
git-lfs \
|
||||
@@ -157,6 +162,14 @@ COPY --chown=www-data:www-data changelogs/ ./changelogs/
|
||||
|
||||
RUN composer dump-autoload
|
||||
|
||||
# Install terminal WebSocket server dependencies
|
||||
COPY docker/coolify-terminal/package*.json /terminal/
|
||||
RUN npm ci --prefix /terminal && \
|
||||
npm rebuild node-pty --prefix /terminal --update-binary
|
||||
COPY docker/coolify-terminal/terminal-server.js /terminal/terminal-server.js
|
||||
COPY docker/coolify-terminal/terminal-utils.js /terminal/terminal-utils.js
|
||||
RUN chown -R www-data:www-data /terminal
|
||||
|
||||
# Configure Nginx and S6 overlay
|
||||
COPY docker/production/etc/nginx/conf.d/custom.conf /etc/nginx/conf.d/custom.conf
|
||||
COPY docker/production/etc/nginx/site-opts.d/http.conf /etc/nginx/site-opts.d/http.conf
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd /var/www/html
|
||||
|
||||
if grep -qE '^PUSHER_ENABLED=false' .env 2>/dev/null; then
|
||||
echo " INFO Reverb is disabled, sleeping."
|
||||
exec sleep infinity
|
||||
fi
|
||||
|
||||
echo " INFO Reverb is enabled, starting..."
|
||||
exec php artisan reverb:start --host=0.0.0.0 --port=${PUSHER_BACKEND_PORT:-6001}
|
||||
@@ -0,0 +1 @@
|
||||
longrun
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd /var/www/html
|
||||
|
||||
echo " INFO Terminal WebSocket server is starting..."
|
||||
exec node /terminal/terminal-server.js
|
||||
@@ -0,0 +1 @@
|
||||
longrun
|
||||
@@ -2,7 +2,7 @@
|
||||
"scripts": {
|
||||
"setup": "cp $JEAN_ROOT_PATH/.env . && mkdir -p .claude && cp $JEAN_ROOT_PATH/.claude/settings.local.json .claude/settings.local.json",
|
||||
"teardown": null,
|
||||
"run": "docker rm -f coolify coolify-minio-init coolify-realtime coolify-minio coolify-testing-host coolify-redis coolify-db coolify-mail coolify-vite; spin up; spin down"
|
||||
"run": "docker rm -f coolify coolify-minio-init coolify-minio coolify-testing-host coolify-redis coolify-db coolify-mail coolify-vite; spin up; spin down"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
|
||||
@@ -10,6 +10,8 @@ REDIS_PASSWORD=
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_PORT=6001
|
||||
PUSHER_BACKEND_PORT=6001
|
||||
|
||||
ROOT_USERNAME=
|
||||
ROOT_USER_EMAIL=
|
||||
|
||||
@@ -18,12 +18,18 @@ services:
|
||||
- PHP_FPM_PM_START_SERVERS=${PHP_FPM_PM_START_SERVERS:-1}
|
||||
- PHP_FPM_PM_MIN_SPARE_SERVERS=${PHP_FPM_PM_MIN_SPARE_SERVERS:-1}
|
||||
- PHP_FPM_PM_MAX_SPARE_SERVERS=${PHP_FPM_PM_MAX_SPARE_SERVERS:-10}
|
||||
- PUSHER_PORT=${PUSHER_PORT:-6001}
|
||||
- PUSHER_BACKEND_PORT=${PUSHER_BACKEND_PORT:-6001}
|
||||
env_file:
|
||||
- /data/coolify/source/.env
|
||||
ports:
|
||||
- "${APP_PORT:-8000}:8080"
|
||||
- "${PUSHER_PORT:-6001}:6001"
|
||||
- "${TERMINAL_PORT:-6002}:6002"
|
||||
expose:
|
||||
- "${APP_PORT:-8000}"
|
||||
- "${PUSHER_PORT:-6001}"
|
||||
- "${TERMINAL_PORT:-6002}"
|
||||
healthcheck:
|
||||
test: curl --fail http://127.0.0.1:8080/api/health || exit 1
|
||||
interval: 5s
|
||||
@@ -34,8 +40,6 @@ services:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
soketi:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
volumes:
|
||||
- coolify-db:/var/lib/postgresql/data
|
||||
@@ -59,26 +63,6 @@ services:
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
soketi:
|
||||
image: '${REGISTRY_URL:-ghcr.io}/coollabsio/coolify-realtime:1.0.16'
|
||||
ports:
|
||||
- "${SOKETI_PORT:-6001}:6001"
|
||||
- "6002:6002"
|
||||
volumes:
|
||||
- /data/coolify/ssh:/var/www/html/storage/app/ssh
|
||||
environment:
|
||||
APP_NAME: "${APP_NAME:-Coolify}"
|
||||
SOKETI_DEBUG: "${SOKETI_DEBUG:-false}"
|
||||
SOKETI_DEFAULT_APP_ID: "${PUSHER_APP_ID}"
|
||||
SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY}"
|
||||
SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET}"
|
||||
SOKETI_HOST: "${SOKETI_HOST:-0.0.0.0}"
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "wget -qO- http://127.0.0.1:6001/ready && wget -qO- http://127.0.0.1:6002/ready || exit 1" ]
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
|
||||
volumes:
|
||||
coolify-db:
|
||||
name: coolify-db
|
||||
|
||||
@@ -42,14 +42,20 @@ services:
|
||||
- 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"
|
||||
- "${PUSHER_PORT:-6001}:6001"
|
||||
- "${TERMINAL_PORT:-6002}:6002"
|
||||
expose:
|
||||
- "${APP_PORT:-8000}"
|
||||
- "${PUSHER_PORT:-6001}"
|
||||
- "${TERMINAL_PORT:-6002}"
|
||||
healthcheck:
|
||||
test: curl --fail http://localhost:8080/api/health || exit 1
|
||||
interval: 5s
|
||||
@@ -95,30 +101,7 @@ services:
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
soketi:
|
||||
image: 'ghcr.io/coollabsio/coolify-realtime:1.0.16'
|
||||
pull_policy: always
|
||||
container_name: coolify-realtime
|
||||
restart: always
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "${SOKETI_PORT:-6001}:6001"
|
||||
- "6002:6002"
|
||||
volumes:
|
||||
- ./ssh:/var/www/html/storage/app/ssh
|
||||
environment:
|
||||
APP_NAME: "${APP_NAME:-Coolify}"
|
||||
SOKETI_DEBUG: "${SOKETI_DEBUG:-false}"
|
||||
SOKETI_DEFAULT_APP_ID: "${PUSHER_APP_ID}"
|
||||
SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY}"
|
||||
SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET}"
|
||||
SOKETI_HOST: "${SOKETI_HOST:-0.0.0.0}"
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "wget -qO- http://127.0.0.1:6001/ready && wget -qO- http://127.0.0.1:6002/ready || exit 1" ]
|
||||
interval: 5s
|
||||
retries: 10
|
||||
timeout: 2s
|
||||
|
||||
|
||||
volumes:
|
||||
coolify-db:
|
||||
|
||||
@@ -5,12 +5,14 @@ services:
|
||||
working_dir: /var/www/html
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
expose:
|
||||
- "6001"
|
||||
- "6002"
|
||||
networks:
|
||||
- coolify
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
- soketi
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: coolify-db
|
||||
@@ -23,13 +25,6 @@ services:
|
||||
restart: always
|
||||
networks:
|
||||
- coolify
|
||||
soketi:
|
||||
container_name: coolify-realtime
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
restart: always
|
||||
networks:
|
||||
- coolify
|
||||
networks:
|
||||
coolify:
|
||||
name: coolify
|
||||
|
||||
@@ -838,6 +838,13 @@ update_env_var() {
|
||||
fi
|
||||
}
|
||||
|
||||
normalize_pusher_port() {
|
||||
if grep -q "^PUSHER_PORT=8080$" "$ENV_FILE"; then
|
||||
sed -i "s|^PUSHER_PORT=8080$|PUSHER_PORT=6001|" "$ENV_FILE"
|
||||
echo " - Updated PUSHER_PORT from app HTTP port 8080 to Reverb port 6001"
|
||||
fi
|
||||
}
|
||||
|
||||
update_env_var "APP_ID" "$(openssl rand -hex 16)"
|
||||
update_env_var "APP_KEY" "base64:$(openssl rand -base64 32)"
|
||||
# update_env_var "DB_USERNAME" "$(openssl rand -hex 16)" # Causes issues: database "random-user" does not exist
|
||||
@@ -846,6 +853,9 @@ update_env_var "REDIS_PASSWORD" "$(openssl rand -base64 32)"
|
||||
update_env_var "PUSHER_APP_ID" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_APP_KEY" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_APP_SECRET" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_PORT" "6001"
|
||||
normalize_pusher_port
|
||||
update_env_var "PUSHER_BACKEND_PORT" "6001"
|
||||
|
||||
# Add default root user credentials from environment variables
|
||||
if [ -n "$ROOT_USERNAME" ] && [ -n "$ROOT_USER_EMAIL" ] && [ -n "$ROOT_USER_PASSWORD" ]; then
|
||||
|
||||
@@ -127,10 +127,20 @@ update_env_var() {
|
||||
fi
|
||||
}
|
||||
|
||||
normalize_pusher_port() {
|
||||
if grep -q "^PUSHER_PORT=8080$" "$ENV_FILE"; then
|
||||
sed -i "s|^PUSHER_PORT=8080$|PUSHER_PORT=6001|" "$ENV_FILE"
|
||||
log "Updated PUSHER_PORT from app HTTP port 8080 to Reverb port 6001"
|
||||
fi
|
||||
}
|
||||
|
||||
log "Checking environment variables..."
|
||||
update_env_var "PUSHER_APP_ID" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_APP_KEY" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_APP_SECRET" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_PORT" "6001"
|
||||
normalize_pusher_port
|
||||
update_env_var "PUSHER_BACKEND_PORT" "6001"
|
||||
log "Environment variables check complete"
|
||||
echo " Done."
|
||||
|
||||
@@ -225,7 +235,7 @@ nohup bash -c "
|
||||
}
|
||||
|
||||
# Stop and remove containers
|
||||
for container in coolify coolify-db coolify-redis coolify-realtime; do
|
||||
for container in coolify coolify-db coolify-redis; do
|
||||
if docker ps -a --format '{{.Names}}' | grep -q \"^\${container}\$\"; then
|
||||
log \"Stopping container: \${container}\"
|
||||
docker stop \"\$container\" >>\"\$LOGFILE\" 2>&1 || true
|
||||
|
||||
@@ -9,9 +9,6 @@
|
||||
"helper": {
|
||||
"version": "1.0.14"
|
||||
},
|
||||
"realtime": {
|
||||
"version": "1.0.16"
|
||||
},
|
||||
"sentinel": {
|
||||
"version": "0.0.21"
|
||||
}
|
||||
|
||||
@@ -174,8 +174,7 @@
|
||||
window.Pusher = Pusher;
|
||||
const EchoConstructor = typeof Echo === 'function' ? Echo : Echo.default;
|
||||
window.Echo = new EchoConstructor({
|
||||
broadcaster: 'pusher',
|
||||
cluster: "{{ config('constants.pusher.host') }}" || window.location.hostname,
|
||||
broadcaster: 'reverb',
|
||||
key: "{{ config('constants.pusher.app_key') }}" || 'coolify',
|
||||
wsHost: "{{ config('constants.pusher.host') }}" || window.location.hostname,
|
||||
wsPort: "{{ getRealtime() }}",
|
||||
|
||||
@@ -838,6 +838,13 @@ update_env_var() {
|
||||
fi
|
||||
}
|
||||
|
||||
normalize_pusher_port() {
|
||||
if grep -q "^PUSHER_PORT=8080$" "$ENV_FILE"; then
|
||||
sed -i "s|^PUSHER_PORT=8080$|PUSHER_PORT=6001|" "$ENV_FILE"
|
||||
echo " - Updated PUSHER_PORT from app HTTP port 8080 to Reverb port 6001"
|
||||
fi
|
||||
}
|
||||
|
||||
update_env_var "APP_ID" "$(openssl rand -hex 16)"
|
||||
update_env_var "APP_KEY" "base64:$(openssl rand -base64 32)"
|
||||
# update_env_var "DB_USERNAME" "$(openssl rand -hex 16)" # Causes issues: database "random-user" does not exist
|
||||
@@ -846,6 +853,9 @@ update_env_var "REDIS_PASSWORD" "$(openssl rand -base64 32)"
|
||||
update_env_var "PUSHER_APP_ID" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_APP_KEY" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_APP_SECRET" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_PORT" "6001"
|
||||
normalize_pusher_port
|
||||
update_env_var "PUSHER_BACKEND_PORT" "6001"
|
||||
|
||||
# Add default root user credentials from environment variables
|
||||
if [ -n "$ROOT_USERNAME" ] && [ -n "$ROOT_USER_EMAIL" ] && [ -n "$ROOT_USER_PASSWORD" ]; then
|
||||
|
||||
+11
-1
@@ -127,10 +127,20 @@ update_env_var() {
|
||||
fi
|
||||
}
|
||||
|
||||
normalize_pusher_port() {
|
||||
if grep -q "^PUSHER_PORT=8080$" "$ENV_FILE"; then
|
||||
sed -i "s|^PUSHER_PORT=8080$|PUSHER_PORT=6001|" "$ENV_FILE"
|
||||
log "Updated PUSHER_PORT from app HTTP port 8080 to Reverb port 6001"
|
||||
fi
|
||||
}
|
||||
|
||||
log "Checking environment variables..."
|
||||
update_env_var "PUSHER_APP_ID" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_APP_KEY" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_APP_SECRET" "$(openssl rand -hex 32)"
|
||||
update_env_var "PUSHER_PORT" "6001"
|
||||
normalize_pusher_port
|
||||
update_env_var "PUSHER_BACKEND_PORT" "6001"
|
||||
log "Environment variables check complete"
|
||||
echo " Done."
|
||||
|
||||
@@ -234,7 +244,7 @@ nohup bash -c "
|
||||
}
|
||||
|
||||
# Stop and remove containers
|
||||
for container in coolify coolify-db coolify-redis coolify-realtime; do
|
||||
for container in coolify coolify-db coolify-redis; do
|
||||
if docker ps -a --format '{{.Names}}' | grep -q \"^\${container}\$\"; then
|
||||
log \"Stopping container: \${container}\"
|
||||
docker stop \"\$container\" >>\"\$LOGFILE\" 2>&1 || true
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<?php
|
||||
|
||||
it('copies the realtime terminal utilities into the container image', function () {
|
||||
$dockerfile = file_get_contents(base_path('docker/coolify-realtime/Dockerfile'));
|
||||
it('copies the terminal utilities into the Coolify container images', function (string $dockerfile) {
|
||||
$dockerfile = file_get_contents(base_path($dockerfile));
|
||||
|
||||
expect($dockerfile)->toContain('COPY docker/coolify-realtime/terminal-utils.js /terminal/terminal-utils.js');
|
||||
});
|
||||
expect($dockerfile)->toContain('COPY docker/coolify-terminal/terminal-utils.js /terminal/terminal-utils.js');
|
||||
})->with([
|
||||
'production image' => 'docker/production/Dockerfile',
|
||||
'development image' => 'docker/development/Dockerfile',
|
||||
]);
|
||||
|
||||
it('mounts the realtime terminal utilities in local development compose files', function (string $composeFile) {
|
||||
$composeContents = file_get_contents(base_path($composeFile));
|
||||
|
||||
expect($composeContents)->toContain('./docker/coolify-realtime/terminal-utils.js:/terminal/terminal-utils.js');
|
||||
expect($composeContents)->toContain('./docker/coolify-terminal/terminal-utils.js:/terminal/terminal-utils.js');
|
||||
})->with([
|
||||
'default dev compose' => 'docker-compose.dev.yml',
|
||||
'maxio dev compose' => 'docker-compose-maxio.dev.yml',
|
||||
@@ -25,7 +28,7 @@ it('keeps terminal browser logging restricted to Vite development mode', functio
|
||||
});
|
||||
|
||||
it('keeps realtime terminal server logging behind the explicit debug flag', function () {
|
||||
$terminalServer = file_get_contents(base_path('docker/coolify-realtime/terminal-server.js'));
|
||||
$terminalServer = file_get_contents(base_path('docker/coolify-terminal/terminal-server.js'));
|
||||
|
||||
expect($terminalServer)
|
||||
->toContain('const debugOverride = String(process.env.TERMINAL_DEBUG')
|
||||
@@ -35,7 +38,7 @@ it('keeps realtime terminal server logging behind the explicit debug flag', func
|
||||
});
|
||||
|
||||
it('configures a server-initiated WebSocket heartbeat to survive proxy idle timeouts', function () {
|
||||
$terminalServer = file_get_contents(base_path('docker/coolify-realtime/terminal-server.js'));
|
||||
$terminalServer = file_get_contents(base_path('docker/coolify-terminal/terminal-server.js'));
|
||||
|
||||
expect($terminalServer)
|
||||
->toContain('ws.isAlive = true;')
|
||||
@@ -60,7 +63,7 @@ it('uses a fast probe timeout when the tab regains visibility', function () {
|
||||
});
|
||||
|
||||
it('does not hard close terminal sessions after 30 minutes on the server', function () {
|
||||
$terminalServer = file_get_contents(base_path('docker/coolify-realtime/terminal-server.js'));
|
||||
$terminalServer = file_get_contents(base_path('docker/coolify-terminal/terminal-server.js'));
|
||||
|
||||
expect($terminalServer)
|
||||
->not->toContain('IDLE_TIMEOUT_MS = 30 * 60 * 1000')
|
||||
@@ -110,7 +113,7 @@ it('replays the last command on reconnect so the PTY respawns automatically', fu
|
||||
});
|
||||
|
||||
it('buffers messages received before the realtime server finishes auth so the replay is not lost', function () {
|
||||
$terminalServer = file_get_contents(base_path('docker/coolify-realtime/terminal-server.js'));
|
||||
$terminalServer = file_get_contents(base_path('docker/coolify-terminal/terminal-server.js'));
|
||||
|
||||
expect($terminalServer)
|
||||
->toContain('authReady: false')
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
it('uses Reverb as the first-party broadcast server', function () {
|
||||
expect(file_get_contents(base_path('composer.json')))
|
||||
->toContain('"laravel/reverb"')
|
||||
->and(file_get_contents(config_path('broadcasting.php')))
|
||||
->toContain("'default' => env('BROADCAST_CONNECTION', env('BROADCAST_DRIVER', 'reverb'))")
|
||||
->toContain("'reverb' => [")
|
||||
->toContain("'key' => env('PUSHER_APP_KEY', 'coolify')")
|
||||
->toContain("'secret' => env('PUSHER_APP_SECRET', 'coolify')")
|
||||
->toContain("'app_id' => env('PUSHER_APP_ID', 'coolify')")
|
||||
->toContain("'host' => env('PUSHER_HOST', 'coolify')")
|
||||
->toContain("'port' => env('PUSHER_BACKEND_PORT', 6001)")
|
||||
->and(file_exists(config_path('reverb.php')))->toBeTrue();
|
||||
});
|
||||
|
||||
it('runs Reverb and terminal websocket services inside the Coolify containers', function (string $dockerfile, string $dependencyService) {
|
||||
$dockerfileContents = file_get_contents(base_path($dockerfile));
|
||||
|
||||
expect($dockerfileContents)
|
||||
->toContain('nodejs')
|
||||
->toContain('npm')
|
||||
->toContain('COPY docker/coolify-terminal/package*.json /terminal/')
|
||||
->toContain('COPY docker/coolify-terminal/terminal-server.js /terminal/terminal-server.js')
|
||||
->toContain('COPY docker/coolify-terminal/terminal-utils.js /terminal/terminal-utils.js')
|
||||
->toContain('npm ci --prefix /terminal')
|
||||
->and(file_get_contents(base_path(dirname($dockerfile).'/etc/s6-overlay/s6-rc.d/reverb/run')))
|
||||
->toContain('exec php artisan reverb:start --host=0.0.0.0 --port=${PUSHER_BACKEND_PORT:-6001}')
|
||||
->and(file_get_contents(base_path(dirname($dockerfile).'/etc/s6-overlay/s6-rc.d/terminal-server/run')))
|
||||
->toContain('exec node /terminal/terminal-server.js')
|
||||
->and(file_exists(base_path(dirname($dockerfile)."/etc/s6-overlay/s6-rc.d/reverb/dependencies.d/{$dependencyService}")))->toBeTrue()
|
||||
->and(file_exists(base_path(dirname($dockerfile)."/etc/s6-overlay/s6-rc.d/terminal-server/dependencies.d/{$dependencyService}")))->toBeTrue()
|
||||
->and(file_exists(base_path(dirname($dockerfile).'/etc/s6-overlay/s6-rc.d/user/contents.d/reverb')))->toBeTrue()
|
||||
->and(file_exists(base_path(dirname($dockerfile).'/etc/s6-overlay/s6-rc.d/user/contents.d/terminal-server')))->toBeTrue();
|
||||
})->with([
|
||||
'production image' => ['docker/production/Dockerfile', 'init-script'],
|
||||
'development image' => ['docker/development/Dockerfile', 'init-setup'],
|
||||
]);
|
||||
|
||||
it('removes the dedicated realtime service from bundled compose files', function (string $composeFile, bool $hasRuntimeEnvironment) {
|
||||
$composeContents = file_get_contents(base_path($composeFile));
|
||||
|
||||
expect($composeContents)
|
||||
->not->toContain('coolify-realtime')
|
||||
->not->toContain('soketi:')
|
||||
->not->toContain('SOKETI_DEFAULT_APP_ID')
|
||||
->toContain('6001')
|
||||
->toContain('6002')
|
||||
->not->toContain('REVERB_');
|
||||
|
||||
if ($hasRuntimeEnvironment) {
|
||||
expect($composeContents)->toContain('PUSHER_BACKEND_PORT');
|
||||
}
|
||||
})->with([
|
||||
'base compose' => ['docker-compose.yml', false],
|
||||
'production compose' => ['docker-compose.prod.yml', true],
|
||||
'development compose' => ['docker-compose.dev.yml', true],
|
||||
'maxio development compose' => ['docker-compose-maxio.dev.yml', true],
|
||||
'windows compose' => ['docker-compose.windows.yml', true],
|
||||
]);
|
||||
|
||||
it('keeps the internal Reverb listen port separate from the public Pusher port', function () {
|
||||
expect(file_get_contents(config_path('reverb.php')))
|
||||
->toContain("'port' => env('PUSHER_BACKEND_PORT', 6001)")
|
||||
->toContain("'port' => env('PUSHER_PORT', 6001)")
|
||||
->and(file_get_contents(base_path('docker/production/etc/s6-overlay/s6-rc.d/reverb/run')))
|
||||
->toContain('exec php artisan reverb:start --host=0.0.0.0 --port=${PUSHER_BACKEND_PORT:-6001}')
|
||||
->and(file_get_contents(base_path('docker/development/etc/s6-overlay/s6-rc.d/reverb/run')))
|
||||
->toContain('exec php artisan reverb:start --host=0.0.0.0 --port=${PUSHER_BACKEND_PORT:-6001}');
|
||||
});
|
||||
|
||||
it('proxies Reverb and terminal websocket traffic to the Coolify app container', function () {
|
||||
$serverModel = file_get_contents(app_path('Models/Server.php'));
|
||||
|
||||
expect($serverModel)
|
||||
->toContain("'rule' => \"Host(`{\$host}`) && PathPrefix(`/app`)\"")
|
||||
->toContain("'rule' => \"Host(`{\$host}`) && PathPrefix(`/apps`)\"")
|
||||
->toContain("'rule' => \"Host(`{\$host}`) && PathPrefix(`/terminal/ws`)\"")
|
||||
->toContain("'url' => 'http://coolify:6001'")
|
||||
->toContain("'url' => 'http://coolify:6002'")
|
||||
->toContain('reverse_proxy coolify:6001')
|
||||
->toContain('reverse_proxy coolify:6002')
|
||||
->not->toContain('http://coolify-realtime:6001')
|
||||
->not->toContain('http://coolify-realtime:6002')
|
||||
->not->toContain('reverse_proxy coolify-realtime');
|
||||
});
|
||||
|
||||
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',
|
||||
'other/nightly/.env.production',
|
||||
'other/nightly/docker-compose.prod.yml',
|
||||
'other/nightly/docker-compose.windows.yml',
|
||||
'other/nightly/install.sh',
|
||||
'other/nightly/upgrade.sh',
|
||||
];
|
||||
|
||||
foreach ($files as $file) {
|
||||
expect(file_get_contents(base_path($file)))
|
||||
->toContain('PUSHER_')
|
||||
->not->toContain('REVERB_');
|
||||
}
|
||||
});
|
||||
|
||||
it('defaults the public Pusher websocket port to Reverb instead of the HTTP app port', function () {
|
||||
expect(file_get_contents(base_path('.env.production')))
|
||||
->toContain('PUSHER_PORT=6001')
|
||||
->toContain('PUSHER_BACKEND_PORT=6001')
|
||||
->and(file_get_contents(base_path('.env.windows-docker-desktop.example')))
|
||||
->toContain('PUSHER_PORT=6001')
|
||||
->toContain('PUSHER_BACKEND_PORT=6001')
|
||||
->and(file_get_contents(base_path('scripts/install.sh')))
|
||||
->toContain('update_env_var "PUSHER_PORT" "6001"')
|
||||
->toContain('update_env_var "PUSHER_BACKEND_PORT" "6001"')
|
||||
->toContain('normalize_pusher_port')
|
||||
->and(file_get_contents(base_path('scripts/upgrade.sh')))
|
||||
->toContain('update_env_var "PUSHER_PORT" "6001"')
|
||||
->toContain('update_env_var "PUSHER_BACKEND_PORT" "6001"')
|
||||
->toContain('normalize_pusher_port');
|
||||
});
|
||||
|
||||
it('stops publishing or preserving the obsolete realtime image', function () {
|
||||
expect(file_get_contents(config_path('constants.php')))
|
||||
->not->toContain('realtime_version')
|
||||
->not->toContain('realtime_image')
|
||||
->and(file_get_contents(app_path('Actions/Server/CleanupDocker.php')))
|
||||
->not->toContain('coolify-realtime')
|
||||
->not->toContain('realtimeImage')
|
||||
->and(file_get_contents(base_path('versions.json')))
|
||||
->not->toContain('"realtime"')
|
||||
->and(is_dir(base_path('docker/coolify-realtime')))->toBeFalse()
|
||||
->and(file_exists(base_path('.github/workflows/coolify-realtime.yml')))->toBeFalse()
|
||||
->and(file_exists(base_path('.github/workflows/coolify-realtime-next.yml')))->toBeFalse();
|
||||
});
|
||||
@@ -255,54 +255,34 @@ it('correctly excludes Docker Compose images from general prune', function () {
|
||||
}
|
||||
});
|
||||
|
||||
it('excludes current version of Coolify infrastructure images from any registry', function () {
|
||||
// Test the regex pattern used to protect the current version of infrastructure images
|
||||
// regardless of which registry they come from (ghcr.io, docker.io, or no prefix)
|
||||
it('excludes current version of the Coolify helper image from any registry', function () {
|
||||
$helperVersion = '1.0.12';
|
||||
$realtimeVersion = '1.0.10';
|
||||
|
||||
// Build the exclusion pattern the same way CleanupDocker does
|
||||
// Pattern: (^|/)coollabsio/coolify-helper:VERSION$|(^|/)coollabsio/coolify-realtime:VERSION$
|
||||
$escapedHelperVersion = preg_replace('/([.\\\\+*?\[\]^$(){}|])/', '\\\\$1', $helperVersion);
|
||||
$escapedRealtimeVersion = preg_replace('/([.\\\\+*?\[\]^$(){}|])/', '\\\\$1', $realtimeVersion);
|
||||
$escapedHelperVersion = preg_quote($helperVersion, '/');
|
||||
$infraPattern = "(^|/)coollabsio/coolify-helper:{$escapedHelperVersion}$";
|
||||
$pattern = "#{$infraPattern}#";
|
||||
|
||||
// For PHP preg_match, escape forward slashes
|
||||
$infraPattern = "(^|\\/)coollabsio\\/coolify-helper:{$escapedHelperVersion}$|(^|\\/)coollabsio\\/coolify-realtime:{$escapedRealtimeVersion}$";
|
||||
$pattern = "/{$infraPattern}/";
|
||||
|
||||
// Current versioned infrastructure images from ANY registry should be PROTECTED
|
||||
$protectedImages = [
|
||||
// ghcr.io registry
|
||||
"ghcr.io/coollabsio/coolify-helper:{$helperVersion}",
|
||||
"ghcr.io/coollabsio/coolify-realtime:{$realtimeVersion}",
|
||||
// docker.io registry (explicit)
|
||||
"docker.io/coollabsio/coolify-helper:{$helperVersion}",
|
||||
"docker.io/coollabsio/coolify-realtime:{$realtimeVersion}",
|
||||
// No registry prefix (Docker Hub implicit)
|
||||
"coollabsio/coolify-helper:{$helperVersion}",
|
||||
"coollabsio/coolify-realtime:{$realtimeVersion}",
|
||||
];
|
||||
|
||||
// Verify current infrastructure images ARE protected from any registry
|
||||
foreach ($protectedImages as $image) {
|
||||
expect(preg_match($pattern, $image))->toBe(1, "Current infrastructure image {$image} should be protected");
|
||||
}
|
||||
|
||||
// Verify OLD versions of infrastructure images are NOT protected (can be deleted)
|
||||
$oldVersionImages = [
|
||||
'ghcr.io/coollabsio/coolify-helper:1.0.11',
|
||||
'docker.io/coollabsio/coolify-helper:1.0.10',
|
||||
'coollabsio/coolify-helper:1.0.9',
|
||||
'ghcr.io/coollabsio/coolify-realtime:1.0.9',
|
||||
'ghcr.io/coollabsio/coolify-helper:latest',
|
||||
'coollabsio/coolify-realtime:latest',
|
||||
];
|
||||
|
||||
foreach ($oldVersionImages as $image) {
|
||||
expect(preg_match($pattern, $image))->toBe(0, "Old infrastructure image {$image} should NOT be protected");
|
||||
}
|
||||
|
||||
// Verify other images are NOT protected (can be deleted)
|
||||
$deletableImages = [
|
||||
'nginx:alpine',
|
||||
'postgres:15',
|
||||
@@ -316,31 +296,19 @@ it('excludes current version of Coolify infrastructure images from any registry'
|
||||
}
|
||||
});
|
||||
|
||||
it('protects current infrastructure images from any registry even when no applications exist', function () {
|
||||
// When there are no applications, current versioned infrastructure images should still be protected
|
||||
// regardless of which registry they come from
|
||||
it('protects current helper image from any registry even when no applications exist', function () {
|
||||
$helperVersion = '1.0.12';
|
||||
$realtimeVersion = '1.0.10';
|
||||
|
||||
// Build the pattern the same way CleanupDocker does
|
||||
$escapedHelperVersion = preg_replace('/([.\\\\+*?\[\]^$(){}|])/', '\\\\$1', $helperVersion);
|
||||
$escapedRealtimeVersion = preg_replace('/([.\\\\+*?\[\]^$(){}|])/', '\\\\$1', $realtimeVersion);
|
||||
$escapedHelperVersion = preg_quote($helperVersion, '/');
|
||||
$infraPattern = "(^|/)coollabsio/coolify-helper:{$escapedHelperVersion}$";
|
||||
$pattern = "#{$infraPattern}#";
|
||||
|
||||
// For PHP preg_match, escape forward slashes
|
||||
$infraPattern = "(^|\\/)coollabsio\\/coolify-helper:{$escapedHelperVersion}$|(^|\\/)coollabsio\\/coolify-realtime:{$escapedRealtimeVersion}$";
|
||||
$pattern = "/{$infraPattern}/";
|
||||
|
||||
// Verify current infrastructure images from any registry are protected
|
||||
expect(preg_match($pattern, "ghcr.io/coollabsio/coolify-helper:{$helperVersion}"))->toBe(1);
|
||||
expect(preg_match($pattern, "docker.io/coollabsio/coolify-helper:{$helperVersion}"))->toBe(1);
|
||||
expect(preg_match($pattern, "coollabsio/coolify-helper:{$helperVersion}"))->toBe(1);
|
||||
expect(preg_match($pattern, "ghcr.io/coollabsio/coolify-realtime:{$realtimeVersion}"))->toBe(1);
|
||||
|
||||
// Old versions should NOT be protected
|
||||
expect(preg_match($pattern, 'ghcr.io/coollabsio/coolify-helper:1.0.11'))->toBe(0);
|
||||
expect(preg_match($pattern, 'docker.io/coollabsio/coolify-helper:1.0.11'))->toBe(0);
|
||||
|
||||
// Other images should not be protected
|
||||
expect(preg_match($pattern, 'nginx:alpine'))->toBe(0);
|
||||
});
|
||||
|
||||
|
||||
@@ -9,9 +9,6 @@
|
||||
"helper": {
|
||||
"version": "1.0.14"
|
||||
},
|
||||
"realtime": {
|
||||
"version": "1.0.16"
|
||||
},
|
||||
"sentinel": {
|
||||
"version": "0.0.21"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user