Merge remote-tracking branch 'upstream/next' into docker-image-login

This commit is contained in:
David Buday 2024-11-18 09:02:12 +00:00
commit b7e00ce054
32 changed files with 1001 additions and 953 deletions

View file

@ -13,7 +13,6 @@ class CleanupRedis extends Command
public function handle()
{
echo "Cleanup Redis keys.\n";
$prefix = config('database.redis.options.prefix');
$keys = Redis::connection()->keys('*:laravel*');

View file

@ -30,7 +30,6 @@ class CleanupStuckedResources extends Command
public function handle()
{
echo "Running cleanup stucked resources.\n";
$this->cleanup_stucked_resources();
}

View file

@ -13,7 +13,7 @@ class Horizon extends Command
public function handle()
{
if (config('constants.horizon.is_horizon_enabled')) {
$this->info('Horizon is enabled. Starting.');
$this->info('[x]: Horizon is enabled. Starting.');
$this->call('horizon');
exit(0);
} else {

View file

@ -2,9 +2,9 @@
namespace App\Console\Commands;
use App\Actions\Server\StopSentinel;
use App\Enums\ActivityTypes;
use App\Enums\ApplicationDeploymentStatus;
use App\Jobs\CheckHelperImageJob;
use App\Models\ApplicationDeploymentQueue;
use App\Models\Environment;
use App\Models\ScheduledDatabaseBackup;
@ -12,6 +12,7 @@ use App\Models\Server;
use App\Models\StandalonePostgresql;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Http;
@ -25,6 +26,8 @@ class Init extends Command
public function handle()
{
$this->optimize();
if (isCloud() && ! $this->option('force-cloud')) {
echo "Skipping init as we are on cloud and --force-cloud option is not set\n";
@ -39,7 +42,6 @@ class Init extends Command
}
// Backward compatibility
// $this->disable_metrics();
$this->replace_slash_in_environment_name();
$this->restore_coolify_db_backup();
$this->update_user_emails();
@ -53,9 +55,18 @@ class Init extends Command
} else {
$this->cleanup_in_progress_application_deployments();
}
echo "[3]: Cleanup Redis keys.\n";
$this->call('cleanup:redis');
echo "[4]: Cleanup stucked resources.\n";
$this->call('cleanup:stucked-resources');
try {
$this->pullHelperImage();
} catch (\Throwable $e) {
//
}
if (isCloud()) {
try {
$this->pullTemplatesFromCDN();
@ -87,6 +98,11 @@ class Init extends Command
}
}
private function pullHelperImage()
{
CheckHelperImageJob::dispatch();
}
private function pullTemplatesFromCDN()
{
$response = Http::retry(3, 1000)->get(config('constants.services.official'));
@ -95,19 +111,13 @@ class Init extends Command
File::put(base_path('templates/service-templates.json'), json_encode($services));
}
}
// private function disable_metrics()
// {
// if (version_compare('4.0.0-beta.312', config('version'), '<=')) {
// foreach ($this->servers as $server) {
// if ($server->settings->is_metrics_enabled === true) {
// $server->settings->update(['is_metrics_enabled' => false]);
// }
// if ($server->isFunctional()) {
// StopSentinel::dispatch($server)->onQueue('high');
// }
// }
// }
// }
private function optimize()
{
echo "[1]: Optimizing Laravel (caching config, routes, views).\n";
Artisan::call('optimize:clear');
Artisan::call('optimize');
}
private function update_user_emails()
{
@ -222,15 +232,15 @@ class Init extends Command
$settings = instanceSettings();
$do_not_track = data_get($settings, 'do_not_track');
if ($do_not_track == true) {
echo "Skipping alive as do_not_track is enabled\n";
echo "[2]: Skipping sending live signal as do_not_track is enabled\n";
return;
}
try {
Http::get("https://undead.coolify.io/v4/alive?appId=$id&version=$version");
echo "I am alive!\n";
echo "[2]: Sending live signal!\n";
} catch (\Throwable $e) {
echo "Error in alive: {$e->getMessage()}\n";
echo "[2]: Error in sending live signal: {$e->getMessage()}\n";
}
}

View file

@ -13,7 +13,7 @@ class Scheduler extends Command
public function handle()
{
if (config('constants.horizon.is_scheduler_enabled')) {
$this->info('Scheduler is enabled. Starting.');
$this->info('[x]: Scheduler is enabled. Starting.');
$this->call('schedule:work');
exit(0);
} else {

View file

@ -25,7 +25,7 @@ class ServerStorageCheckJob implements ShouldBeEncrypted, ShouldQueue
return isDev() ? 1 : 3;
}
public function __construct(public Server $server, public ?int $percentage = null) {}
public function __construct(public Server $server, public int|string|null $percentage = null) {}
public function handle()
{

View file

@ -21,8 +21,8 @@ class CreateScheduledBackup extends Component
public bool $enabled = true;
#[Validate(['required', 'integer'])]
public int $s3StorageId;
#[Validate(['nullable', 'integer'])]
public ?int $s3StorageId = null;
public Collection $definedS3s;
@ -49,6 +49,7 @@ class CreateScheduledBackup extends Component
return;
}
$payload = [
'enabled' => true,
'frequency' => $this->frequency,
@ -58,6 +59,7 @@ class CreateScheduledBackup extends Component
'database_type' => $this->database->getMorphClass(),
'team_id' => currentTeam()->id,
];
if ($this->database->type() === 'standalone-postgresql') {
$payload['databases_to_backup'] = $this->database->postgres_db;
} elseif ($this->database->type() === 'standalone-mysql') {
@ -72,11 +74,11 @@ class CreateScheduledBackup extends Component
} else {
$this->dispatch('refreshScheduledBackups');
}
} catch (\Throwable $e) {
return handleError($e, $this);
} finally {
$this->frequency = '';
$this->saveToS3 = true;
}
}
}

View file

@ -37,6 +37,7 @@ class Tags extends Component
$this->validate();
$tags = str($this->newTags)->trim()->explode(' ');
foreach ($tags as $tag) {
$tag = strip_tags($tag);
if (strlen($tag) < 2) {
$this->dispatch('error', 'Invalid tag.', "Tag <span class='dark:text-warning'>$tag</span> is invalid. Min length is 2.");
@ -65,6 +66,7 @@ class Tags extends Component
public function addTag(string $id, string $name)
{
try {
$name = strip_tags($name);
if ($this->resource->tags()->where('id', $id)->exists()) {
$this->dispatch('error', 'Duplicate tags.', "Tag <span class='dark:text-warning'>$name</span> already added.");

View file

@ -6,64 +6,60 @@ use App\Enums\ProxyTypes;
use App\Models\Server;
use App\Models\Team;
use Illuminate\Support\Collection;
use Livewire\Attributes\Locked;
use Livewire\Attributes\Validate;
use Livewire\Component;
class ByIp extends Component
{
#[Locked]
public $private_keys;
#[Locked]
public $limit_reached;
#[Validate('nullable|integer', as: 'Private Key')]
public ?int $private_key_id = null;
#[Validate('nullable|string', as: 'Private Key Name')]
public $new_private_key_name;
#[Validate('nullable|string', as: 'Private Key Description')]
public $new_private_key_description;
#[Validate('nullable|string', as: 'Private Key Value')]
public $new_private_key_value;
#[Validate('required|string', as: 'Name')]
public string $name;
#[Validate('nullable|string', as: 'Description')]
public ?string $description = null;
#[Validate('required|string', as: 'IP Address/Domain')]
public string $ip;
#[Validate('required|string', as: 'User')]
public string $user = 'root';
#[Validate('required|integer|between:1,65535', as: 'Port')]
public int $port = 22;
#[Validate('required|boolean', as: 'Swarm Manager')]
public bool $is_swarm_manager = false;
#[Validate('required|boolean', as: 'Swarm Worker')]
public bool $is_swarm_worker = false;
#[Validate('nullable|integer', as: 'Swarm Cluster')]
public $selected_swarm_cluster = null;
#[Validate('required|boolean', as: 'Build Server')]
public bool $is_build_server = false;
#[Locked]
public Collection $swarm_managers;
protected $rules = [
'name' => 'required|string',
'description' => 'nullable|string',
'ip' => 'required',
'user' => 'required|string',
'port' => 'required|integer',
'is_swarm_manager' => 'required|boolean',
'is_swarm_worker' => 'required|boolean',
'is_build_server' => 'required|boolean',
];
protected $validationAttributes = [
'name' => 'Name',
'description' => 'Description',
'ip' => 'IP Address/Domain',
'user' => 'User',
'port' => 'Port',
'is_swarm_manager' => 'Swarm Manager',
'is_swarm_worker' => 'Swarm Worker',
'is_build_server' => 'Build Server',
];
public function mount()
{
$this->name = generate_random_name();
@ -88,6 +84,12 @@ class ByIp extends Component
{
$this->validate();
try {
if (Server::where('team_id', currentTeam()->id)
->where('ip', $this->ip)
->exists()) {
return $this->dispatch('error', 'This IP/Domain is already in use by another server in your team.');
}
if (is_null($this->private_key_id)) {
return $this->dispatch('error', 'You must select a private key');
}

View file

@ -107,6 +107,15 @@ class Show extends Component
{
if ($toModel) {
$this->validate();
if (Server::where('team_id', currentTeam()->id)
->where('ip', $this->ip)
->where('id', '!=', $this->server->id)
->exists()) {
$this->ip = $this->server->ip;
throw new \Exception('This IP/Domain is already in use by another server in your team.');
}
$this->server->name = $this->name;
$this->server->description = $this->description;
$this->server->ip = $this->ip;

View file

@ -218,10 +218,12 @@ class PrivateKey extends BaseModel
private static function fingerprintExists($fingerprint, $excludeId = null)
{
$query = self::where('fingerprint', $fingerprint);
$query = self::query()
->where('fingerprint', $fingerprint)
->where('id', '!=', $excludeId);
if (! is_null($excludeId)) {
$query->where('id', '!=', $excludeId);
if (currentTeam()) {
$query->where('team_id', currentTeam()->id);
}
return $query->exists();

View file

@ -17,11 +17,14 @@ class Checkbox extends Component
public ?string $value = null,
public ?string $label = null,
public ?string $helper = null,
public string|bool|null $checked = false,
public string|bool $instantSave = false,
public bool $disabled = false,
public string $defaultClass = 'dark:border-neutral-700 text-coolgray-400 focus:ring-warning dark:bg-coolgray-100 rounded cursor-pointer dark:disabled:bg-base dark:disabled:cursor-not-allowed',
) {
//
if ($this->disabled) {
$this->defaultClass .= ' opacity-40';
}
}
/**

View file

@ -227,13 +227,17 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
$MINIO_BROWSER_REDIRECT_URL = $variables->where('key', 'MINIO_BROWSER_REDIRECT_URL')->first();
$MINIO_SERVER_URL = $variables->where('key', 'MINIO_SERVER_URL')->first();
if (str($MINIO_BROWSER_REDIRECT_URL->value)->isEmpty()) {
$MINIO_BROWSER_REDIRECT_URL?->update([
if (is_null($MINIO_BROWSER_REDIRECT_URL) || is_null($MINIO_SERVER_URL)) {
return collect([]);
}
if (str($MINIO_BROWSER_REDIRECT_URL->value ?? '')->isEmpty()) {
$MINIO_BROWSER_REDIRECT_URL->update([
'value' => generateFqdn($server, 'console-'.$uuid, true),
]);
}
if (str($MINIO_SERVER_URL->value)->isEmpty()) {
$MINIO_SERVER_URL?->update([
if (str($MINIO_SERVER_URL->value ?? '')->isEmpty()) {
$MINIO_SERVER_URL->update([
'value' => generateFqdn($server, 'minio-'.$uuid, true),
]);
}
@ -246,13 +250,17 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
$LOGTO_ENDPOINT = $variables->where('key', 'LOGTO_ENDPOINT')->first();
$LOGTO_ADMIN_ENDPOINT = $variables->where('key', 'LOGTO_ADMIN_ENDPOINT')->first();
if (str($LOGTO_ENDPOINT?->value)->isEmpty()) {
$LOGTO_ENDPOINT?->update([
if (is_null($LOGTO_ENDPOINT) || is_null($LOGTO_ADMIN_ENDPOINT)) {
return collect([]);
}
if (str($LOGTO_ENDPOINT->value ?? '')->isEmpty()) {
$LOGTO_ENDPOINT->update([
'value' => generateFqdn($server, 'logto-'.$uuid),
]);
}
if (str($LOGTO_ADMIN_ENDPOINT?->value)->isEmpty()) {
$LOGTO_ADMIN_ENDPOINT?->update([
if (str($LOGTO_ADMIN_ENDPOINT->value ?? '')->isEmpty()) {
$LOGTO_ADMIN_ENDPOINT->update([
'value' => generateFqdn($server, 'logto-admin-'.$uuid),
]);
}

View file

@ -4075,7 +4075,7 @@ function defaultNginxConfiguration(): string
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/index.html =404;
try_files $uri $uri.html $uri/index.html $uri/index.htm $uri/ /index.html /index.htm =404;
}
error_page 500 502 503 504 /50x.html;

View file

@ -42,6 +42,7 @@
"socialiteproviders/microsoft-azure": "^5.1",
"spatie/laravel-activitylog": "^4.7.3",
"spatie/laravel-data": "^4.11",
"spatie/laravel-ray": "^1.37",
"spatie/laravel-schemaless-attributes": "^2.4",
"spatie/url": "^2.2",
"stripe/stripe-php": "^16.2.0",
@ -63,7 +64,6 @@
"phpunit/phpunit": "^11.4",
"serversideup/spin": "^2.3",
"spatie/laravel-ignition": "^2.1.0",
"spatie/laravel-ray": "^1.37",
"symfony/http-client": "^7.1"
},
"minimum-stability": "stable",

1686
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -2,9 +2,9 @@
return [
'coolify' => [
'version' => '4.0.0-beta.368',
'version' => '4.0.0-beta.370',
'self_hosted' => env('SELF_HOSTED', true),
'autoupdate' => env('AUTOUPDATE', false),
'autoupdate' => env('AUTOUPDATE'),
'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'),
'helper_image' => env('HELPER_IMAGE', 'ghcr.io/coollabsio/coolify-helper'),
'is_windows_docker_desktop' => env('IS_WINDOWS_DOCKER_DESKTOP', false),

View file

@ -1,3 +1,3 @@
<?php
return '4.0.0-beta.368';
return '4.0.0-beta.370';

View file

@ -22,9 +22,9 @@ class ProductionSeeder extends Seeder
public function run(): void
{
if (isCloud()) {
echo "Running in cloud mode.\n";
echo "[x]: Running in cloud mode.\n";
} else {
echo "Running in self-hosted mode.\n";
echo "[x]: Running in self-hosted mode.\n";
}
// Fix for 4.0.0-beta.37

View file

@ -1,4 +1,5 @@
# Versions
# https://hub.docker.com/_/alpine
ARG BASE_IMAGE=alpine:3.20
# https://download.docker.com/linux/static/stable/

View file

@ -1,5 +1,6 @@
FROM quay.io/soketi/soketi:1.6-16-alpine
ARG TARGETPLATFORM
# https://github.com/cloudflare/cloudflared/releases
ARG CLOUDFLARED_VERSION=2024.4.1

View file

@ -57,13 +57,6 @@ RUN composer dump-autoload
COPY --from=static-assets --chown=9999:9999 /app/public/build ./public/build
COPY --chmod=755 docker/prod/etc/s6-overlay/ /etc/s6-overlay/
RUN php artisan route:clear
RUN php artisan view:clear
RUN php artisan config:clear
RUN php artisan route:cache
RUN php artisan view:cache
RUN php artisan config:cache
RUN echo "alias ll='ls -al'" >>/etc/bash.bashrc
RUN echo "alias a='php artisan'" >>/etc/bash.bashrc
RUN echo "alias logs='tail -f storage/logs/laravel.log'" >>/etc/bash.bashrc
@ -86,4 +79,4 @@ RUN { \
} > /etc/php/current_version/cli/conf.d/upload-limits.ini
COPY --from=minio-client /usr/bin/mc /usr/bin/mc
RUN chmod +x /usr/bin/mc
RUN chmod +x /usr/bin/mc

View file

@ -9,7 +9,7 @@ CDN="https://cdn.coollabs.io/coolify-nightly"
DATE=$(date +"%Y%m%d-%H%M%S")
VERSION="1.6"
DOCKER_VERSION="27.3"
DOCKER_VERSION="27.0"
# TODO: Ask for a user
CURRENT_USER=$USER

View file

@ -5,6 +5,7 @@
'disabled' => false,
'instantSave' => false,
'value' => null,
'checked' => false,
'hideLabel' => false,
'fullWidth' => false,
])
@ -14,7 +15,9 @@
'w-full' => $fullWidth,
])>
@if (!$hideLabel)
<label @class(['flex gap-4 items-center px-0 min-w-fit label w-full cursor-pointer', 'opacity-40' => $disabled])>
<label @class([
'flex gap-4 items-center px-0 min-w-fit label w-full cursor-pointer',
])>
<span class="flex flex-grow gap-2">
@if ($label)
{!! $label !!}
@ -26,9 +29,10 @@
@endif
</span>
@endif
<input @disabled($disabled) type="checkbox" {{ $attributes->merge(['class' => $defaultClass]) }}
@if ($instantSave) wire:loading.attr="disabled" wire:click='{{ $instantSave === 'instantSave' || $instantSave == '1' ? 'instantSave' : $instantSave }}'
wire:model={{ $id }} @else wire:model={{ $value ?? $id }} @endif />
<input @disabled($disabled) type="checkbox" {{ $attributes->merge(['class' => $defaultClass]) }}
@if ($instantSave) wire:loading.attr="disabled" wire:click='{{ $instantSave === 'instantSave' || $instantSave == '1' ? 'instantSave' : $instantSave }}'
@if ($checked) checked @endif
wire:model={{ $id }} @else wire:model={{ $value ?? $id }} @endif />
@if (!$hideLabel)
</label>
@endif

View file

@ -9,7 +9,7 @@
'closeOutside' => true,
])
<div x-data="{ modalOpen: false }" :class="{ 'z-40': modalOpen }" @keydown.window.escape="modalOpen=false"
class="relative w-auto h-auto">
class="relative w-auto h-auto" wire:ignore>
@if ($content)
<div @click="modalOpen=true">
{{ $content }}
@ -27,7 +27,7 @@
@endif
<template x-teleport="body">
<div x-show="modalOpen"
class="fixed top-0 left-0 lg:px-0 px-4 z-[99] flex items-center justify-center w-screen h-screen" x-cloak>
class="fixed top-0 left-0 lg:px-0 px-4 z-[99] flex items-center justify-center w-screen h-screen">
<div x-show="modalOpen" x-transition:enter="ease-out duration-100" x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-100"
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"

View file

@ -8,7 +8,7 @@
@forelse ($private_keys as $key)
@if ($private_key_id == $key->id)
<div class="gap-2 py-4 cursor-pointer group hover:bg-coollabs bg-coolgray-200 box"
wire:click.defer="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}">
wire:click="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}">
<div class="flex flex-col mx-6">
<div class="box-title">
{{ $key->name }}
@ -21,7 +21,7 @@
</div>
@else
<div class="gap-2 py-4 cursor-pointer group hover:bg-coollabs bg-coolgray-200 box"
wire:click.defer="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}">
wire:click="setPrivateKey('{{ $key->id }}')" wire:key="{{ $key->id }}">
<div class="flex flex-col mx-6">
<div class="box-title">
{{ $key->name }}

View file

@ -103,7 +103,7 @@
@if (!is_null(config('constants.coolify.autoupdate', null)))
<div class="text-right md:w-96">
<x-forms.checkbox instantSave helper="AUTOUPDATE is set in .env file, you need to modify it there."
disabled id="is_auto_update_enabled" label="Enabled" />
disabled checked="{{ config('constants.coolify.autoupdate') }}" label="Auto Update Enabled" />
</div>
@else
<x-forms.checkbox instantSave id="is_auto_update_enabled" label="Auto Update Enabled" />

View file

@ -9,7 +9,7 @@ CDN="https://cdn.coollabs.io/coolify"
DATE=$(date +"%Y%m%d-%H%M%S")
VERSION="1.6"
DOCKER_VERSION="27.3"
DOCKER_VERSION="27.0"
# TODO: Ask for a user
CURRENT_USER=$USER
@ -151,24 +151,24 @@ echo "| Coolify | $LATEST_VERSION"
echo "| Helper | $LATEST_HELPER_VERSION"
echo "| Realtime | $LATEST_REALTIME_VERSION"
echo -e "---------------------------------------------\n"
echo -e "1. Installing required packages (curl, wget, git, jq). "
echo -e "1. Installing required packages (curl, wget, git, jq, openssl). "
case "$OS_TYPE" in
arch)
pacman -Sy --noconfirm --needed curl wget git jq >/dev/null || true
pacman -Sy --noconfirm --needed curl wget git jq openssl >/dev/null || true
;;
alpine)
sed -i '/^#.*\/community/s/^#//' /etc/apk/repositories
apk update >/dev/null
apk add curl wget git jq >/dev/null
apk add curl wget git jq openssl >/dev/null
;;
ubuntu | debian | raspbian)
apt-get update -y >/dev/null
apt-get install -y curl wget git jq >/dev/null
apt-get install -y curl wget git jq openssl >/dev/null
;;
centos | fedora | rhel | ol | rocky | almalinux | amzn)
if [ "$OS_TYPE" = "amzn" ]; then
dnf install -y wget git jq >/dev/null
dnf install -y wget git jq openssl >/dev/null
else
if ! command -v dnf >/dev/null; then
yum install -y dnf >/dev/null
@ -176,12 +176,12 @@ centos | fedora | rhel | ol | rocky | almalinux | amzn)
if ! command -v curl >/dev/null; then
dnf install -y curl >/dev/null
fi
dnf install -y wget git jq >/dev/null
dnf install -y wget git jq openssl >/dev/null
fi
;;
sles | opensuse-leap | opensuse-tumbleweed)
zypper refresh >/dev/null
zypper install -y curl wget git jq >/dev/null
zypper install -y curl wget git jq openssl >/dev/null
;;
*)
echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now."
@ -326,6 +326,22 @@ if ! [ -x "$(command -v docker)" ]; then
exit 1
fi
;;
"fedora")
if [ -x "$(command -v dnf5)" ]; then
# dnf5 is available
dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/fedora/docker-ce.repo --overwrite >/dev/null 2>&1
else
# dnf5 is not available, use dnf
dnf config-manager --add-repo=https://download.docker.com/linux/fedora/docker-ce.repo >/dev/null 2>&1
fi
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin >/dev/null 2>&1
if ! [ -x "$(command -v docker)" ]; then
echo " - Docker could not be installed automatically. Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
systemctl start docker >/dev/null 2>&1
systemctl enable docker >/dev/null 2>&1
;;
*)
if [ "$OS_TYPE" = "ubuntu" ] && [ "$OS_VERSION" = "24.10" ]; then
echo "Docker automated installation is not supported on Ubuntu 24.10 (non-LTS release)."
@ -516,9 +532,8 @@ echo -e "\033[0;35m
\____\___/|_| |_|\__, |_| \__,_|\__|\__,_|_|\__,_|\__|_|\___/|_| |_|___(_)
|___/
\033[0m"
echo -e "\nYour instance is ready to use."
echo -e "You can access Coolify through:"
echo -e "- Public IP: http://$(curl -4s https://ifconfig.io):8000"
echo -e "\nYour instance is ready to use!\n"
echo -e "You can access Coolify through your Public IP: http://$(curl -4s https://ifconfig.io):8000"
set +e
DEFAULT_PRIVATE_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
@ -526,15 +541,12 @@ PRIVATE_IPS=$(hostname -I)
set -e
if [ -n "$PRIVATE_IPS" ]; then
echo -e "If your Public IP is not accessible, you can use the following Private IPs:\n"
echo -e "\nIf your Public IP is not accessible, you can use the following Private IPs:\n"
for IP in $PRIVATE_IPS; do
if [ "$IP" == "$DEFAULT_PRIVATE_IP" ]; then
echo -e "http://$DEFAULT_PRIVATE_IP:8000 (default)"
else
if [ "$IP" != "$DEFAULT_PRIVATE_IP" ]; then
echo -e "http://$IP:8000"
fi
done
fi
echo -e "\n"
echo -e "WARNING: It is highly recommended to backup your Environment variables file (/data/coolify/source/.env) to a safe location, outside of this server (e.g. into a Password Manager).\n"
echo -e "\nWARNING: It is highly recommended to backup your Environment variables file (/data/coolify/source/.env) to a safe location, outside of this server (e.g. into a Password Manager).\n"
cp /data/coolify/source/.env /data/coolify/source/.env.backup

View file

@ -9,7 +9,7 @@ services:
image: ghcr.io/browserless/chromium
environment:
- SERVICE_FQDN_BROWSERLESS_3000
- TOKEN=$SERVICE_BASE64_BROWSERLESS_TOKEN
- TOKEN=$SERVICE_PASSWORD_BROWSERLESS
expose:
- 3000
healthcheck:

View file

@ -22,6 +22,7 @@ services:
- MONGO_URI=mongodb://mongo:27017/heyform
- REDIS_HOST=keydb
- REDIS_PORT=6379
- REDIS_PASSWORD=${SERVICE_PASSWORD_KEYDB}
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8000 || exit 1"]
interval: 5s

View file

@ -192,7 +192,7 @@
"browserless": {
"documentation": "https://docs.browserless.io/?utm_source=coolify.io",
"slogan": "A headless Chrome browser as a service .",
"compose": "c2VydmljZXM6CiAgYnJvd3Nlcmxlc3M6CiAgICBpbWFnZTogZ2hjci5pby9icm93c2VybGVzcy9jaHJvbWl1bQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0JST1dTRVJMRVNTXzMwMDAKICAgICAgLSBUT0tFTj0kU0VSVklDRV9CQVNFNjRfQlJPV1NFUkxFU1NfVE9LRU4KICAgIGV4cG9zZToKICAgICAgLSAzMDAwCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMC9kb2NzJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1Cg==",
"compose": "c2VydmljZXM6CiAgYnJvd3Nlcmxlc3M6CiAgICBpbWFnZTogZ2hjci5pby9icm93c2VybGVzcy9jaHJvbWl1bQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0JST1dTRVJMRVNTXzMwMDAKICAgICAgLSBUT0tFTj0kU0VSVklDRV9QQVNTV09SRF9CUk9XU0VSTEVTUwogICAgZXhwb3NlOgogICAgICAtIDMwMDAKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTozMDAwL2RvY3MnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUK",
"tags": [
"chrome",
"headless",
@ -1131,7 +1131,7 @@
"heyform": {
"documentation": "https://docs.heyform.net/open-source/self-hosting?utm_source=coolify.io",
"slogan": "Allows anyone to create engaging conversational forms for surveys, questionnaires, quizzes, and polls. No coding skills required.",
"compose": "c2VydmljZXM6CiAgaGV5Zm9ybToKICAgIGltYWdlOiAnaGV5Zm9ybS9jb21tdW5pdHktZWRpdGlvbjpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdoZXlmb3JtLWFzc2V0czovYXBwL3N0YXRpYy91cGxvYWQnCiAgICBkZXBlbmRzX29uOgogICAgICBtb25nbzoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBrZXlkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0hFWUZPUk1fODAwMAogICAgICAtICdBUFBfSE9NRVBBR0VfVVJMPSR7U0VSVklDRV9GUUROX0hFWUZPUk19JwogICAgICAtICdTRVNTSU9OX0tFWT0ke1NFUlZJQ0VfQkFTRTY0XzY0X1NFU1NJT059JwogICAgICAtICdGT1JNX0VOQ1JZUFRJT05fS0VZPSR7U0VSVklDRV9CQVNFNjRfNjRfRk9STX0nCiAgICAgIC0gJ01PTkdPX1VSST1tb25nb2RiOi8vbW9uZ286MjcwMTcvaGV5Zm9ybScKICAgICAgLSBSRURJU19IT1NUPWtleWRiCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3dnZXQgLXFPLSBodHRwOi8vMTI3LjAuMC4xOjgwMDAgfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMwogIG1vbmdvOgogICAgaW1hZ2U6ICdwZXJjb25hL3BlcmNvbmEtc2VydmVyLW1vbmdvZGI6bGF0ZXN0JwogICAgdm9sdW1lczoKICAgICAgLSAnaGV5Zm9ybS1tb25nby1kYXRhOi9kYXRhL2RiJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICJlY2hvICdvaycgPiAvZGV2L251bGwgMj4mMSIKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMKICBrZXlkYjoKICAgIGltYWdlOiAnZXFhbHBoYS9rZXlkYjpsYXRlc3QnCiAgICBjb21tYW5kOiAna2V5ZGItc2VydmVyIC0tYXBwZW5kb25seSB5ZXMnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnS0VZREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX0tFWURCfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2hleWZvcm0ta2V5ZGItZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBrZXlkYi1jbGkKICAgICAgICAtICctLXBhc3MnCiAgICAgICAgLSAnJHtTRVJWSUNFX1BBU1NXT1JEX0tFWURCfScKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMK",
"compose": "c2VydmljZXM6CiAgaGV5Zm9ybToKICAgIGltYWdlOiAnaGV5Zm9ybS9jb21tdW5pdHktZWRpdGlvbjpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdoZXlmb3JtLWFzc2V0czovYXBwL3N0YXRpYy91cGxvYWQnCiAgICBkZXBlbmRzX29uOgogICAgICBtb25nbzoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBrZXlkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0hFWUZPUk1fODAwMAogICAgICAtICdBUFBfSE9NRVBBR0VfVVJMPSR7U0VSVklDRV9GUUROX0hFWUZPUk19JwogICAgICAtICdTRVNTSU9OX0tFWT0ke1NFUlZJQ0VfQkFTRTY0XzY0X1NFU1NJT059JwogICAgICAtICdGT1JNX0VOQ1JZUFRJT05fS0VZPSR7U0VSVklDRV9CQVNFNjRfNjRfRk9STX0nCiAgICAgIC0gJ01PTkdPX1VSST1tb25nb2RiOi8vbW9uZ286MjcwMTcvaGV5Zm9ybScKICAgICAgLSBSRURJU19IT1NUPWtleWRiCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICAgIC0gJ1JFRElTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9LRVlEQn0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3dnZXQgLXFPLSBodHRwOi8vMTI3LjAuMC4xOjgwMDAgfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMwogIG1vbmdvOgogICAgaW1hZ2U6ICdwZXJjb25hL3BlcmNvbmEtc2VydmVyLW1vbmdvZGI6bGF0ZXN0JwogICAgdm9sdW1lczoKICAgICAgLSAnaGV5Zm9ybS1tb25nby1kYXRhOi9kYXRhL2RiJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICJlY2hvICdvaycgPiAvZGV2L251bGwgMj4mMSIKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMKICBrZXlkYjoKICAgIGltYWdlOiAnZXFhbHBoYS9rZXlkYjpsYXRlc3QnCiAgICBjb21tYW5kOiAna2V5ZGItc2VydmVyIC0tYXBwZW5kb25seSB5ZXMnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnS0VZREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX0tFWURCfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2hleWZvcm0ta2V5ZGItZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBrZXlkYi1jbGkKICAgICAgICAtICctLXBhc3MnCiAgICAgICAgLSAnJHtTRVJWSUNFX1BBU1NXT1JEX0tFWURCfScKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMK",
"tags": [
"form",
"builder",

View file

@ -1,19 +1,19 @@
{
"coolify": {
"v4": {
"version": "4.0.0-beta.368"
"version": "4.0.0-beta.370"
},
"nightly": {
"version": "4.0.0-beta.369"
"version": "4.0.0-beta.371"
},
"helper": {
"version": "1.0.3"
"version": "1.0.4"
},
"realtime": {
"version": "1.0.4"
"version": "1.0.5"
},
"sentinel": {
"version": "0.0.15"
}
}
}
}