Merge branch 'next' into dep-and-remove-unused-stuff
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Actions\Server;
|
|||||||
|
|
||||||
use App\Jobs\PullHelperImageJob;
|
use App\Jobs\PullHelperImageJob;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use Illuminate\Support\Sleep;
|
||||||
use Lorisleiva\Actions\Concerns\AsAction;
|
use Lorisleiva\Actions\Concerns\AsAction;
|
||||||
|
|
||||||
class UpdateCoolify
|
class UpdateCoolify
|
||||||
@@ -18,6 +19,11 @@ class UpdateCoolify
|
|||||||
|
|
||||||
public function handle($manual_update = false)
|
public function handle($manual_update = false)
|
||||||
{
|
{
|
||||||
|
if (isDev()) {
|
||||||
|
Sleep::for(10)->seconds();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
$settings = instanceSettings();
|
$settings = instanceSettings();
|
||||||
$this->server = Server::find(0);
|
$this->server = Server::find(0);
|
||||||
if (! $this->server) {
|
if (! $this->server) {
|
||||||
@@ -44,19 +50,7 @@ class UpdateCoolify
|
|||||||
|
|
||||||
private function update()
|
private function update()
|
||||||
{
|
{
|
||||||
if (isDev()) {
|
PullHelperImageJob::dispatch($this->server);
|
||||||
remote_process([
|
|
||||||
'sleep 10',
|
|
||||||
], $this->server);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$all_servers = Server::all();
|
|
||||||
$servers = $all_servers->where('settings.is_usable', true)->where('settings.is_reachable', true)->where('ip', '!=', '1.2.3.4');
|
|
||||||
foreach ($servers as $server) {
|
|
||||||
PullHelperImageJob::dispatch($server);
|
|
||||||
}
|
|
||||||
|
|
||||||
instant_remote_process(["docker pull -q ghcr.io/coollabsio/coolify:{$this->latestVersion}"], $this->server, false);
|
instant_remote_process(["docker pull -q ghcr.io/coollabsio/coolify:{$this->latestVersion}"], $this->server, false);
|
||||||
|
|
||||||
|
@@ -636,7 +636,7 @@ class ApplicationsController extends Controller
|
|||||||
|
|
||||||
private function create_application(Request $request, $type)
|
private function create_application(Request $request, $type)
|
||||||
{
|
{
|
||||||
$allowedFields = ['project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image'];
|
$allowedFields = ['project_uuid', 'environment_name', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image', 'custom_nginx_configuration'];
|
||||||
$teamId = getTeamIdFromToken();
|
$teamId = getTeamIdFromToken();
|
||||||
if (is_null($teamId)) {
|
if (is_null($teamId)) {
|
||||||
return invalidTokenResponse();
|
return invalidTokenResponse();
|
||||||
@@ -676,6 +676,27 @@ class ApplicationsController extends Controller
|
|||||||
$githubAppUuid = $request->github_app_uuid;
|
$githubAppUuid = $request->github_app_uuid;
|
||||||
$useBuildServer = $request->use_build_server;
|
$useBuildServer = $request->use_build_server;
|
||||||
$isStatic = $request->is_static;
|
$isStatic = $request->is_static;
|
||||||
|
$customNginxConfiguration = $request->custom_nginx_configuration;
|
||||||
|
|
||||||
|
if (! is_null($customNginxConfiguration)) {
|
||||||
|
if (! isBase64Encoded($customNginxConfiguration)) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => [
|
||||||
|
'custom_nginx_configuration' => 'The custom_nginx_configuration should be base64 encoded.',
|
||||||
|
],
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
$customNginxConfiguration = base64_decode($customNginxConfiguration);
|
||||||
|
if (mb_detect_encoding($customNginxConfiguration, 'ASCII', true) === false) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => [
|
||||||
|
'custom_nginx_configuration' => 'The custom_nginx_configuration should be base64 encoded.',
|
||||||
|
],
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$project = Project::whereTeamId($teamId)->whereUuid($request->project_uuid)->first();
|
$project = Project::whereTeamId($teamId)->whereUuid($request->project_uuid)->first();
|
||||||
if (! $project) {
|
if (! $project) {
|
||||||
@@ -1500,7 +1521,7 @@ class ApplicationsController extends Controller
|
|||||||
], 404);
|
], 404);
|
||||||
}
|
}
|
||||||
$server = $application->destination->server;
|
$server = $application->destination->server;
|
||||||
$allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server'];
|
$allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'custom_nginx_configuration'];
|
||||||
|
|
||||||
$validationRules = [
|
$validationRules = [
|
||||||
'name' => 'string|max:255',
|
'name' => 'string|max:255',
|
||||||
@@ -1512,6 +1533,7 @@ class ApplicationsController extends Controller
|
|||||||
'docker_compose_domains' => 'array|nullable',
|
'docker_compose_domains' => 'array|nullable',
|
||||||
'docker_compose_custom_start_command' => 'string|nullable',
|
'docker_compose_custom_start_command' => 'string|nullable',
|
||||||
'docker_compose_custom_build_command' => 'string|nullable',
|
'docker_compose_custom_build_command' => 'string|nullable',
|
||||||
|
'custom_nginx_configuration' => 'string|nullable',
|
||||||
];
|
];
|
||||||
$validationRules = array_merge($validationRules, sharedDataApplications());
|
$validationRules = array_merge($validationRules, sharedDataApplications());
|
||||||
$validator = customApiValidator($request->all(), $validationRules);
|
$validator = customApiValidator($request->all(), $validationRules);
|
||||||
@@ -1530,6 +1552,25 @@ class ApplicationsController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($request->has('custom_nginx_configuration')) {
|
||||||
|
if (! isBase64Encoded($request->custom_nginx_configuration)) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => [
|
||||||
|
'custom_nginx_configuration' => 'The custom_nginx_configuration should be base64 encoded.',
|
||||||
|
],
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
$customNginxConfiguration = base64_decode($request->custom_nginx_configuration);
|
||||||
|
if (mb_detect_encoding($customNginxConfiguration, 'ASCII', true) === false) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Validation failed.',
|
||||||
|
'errors' => [
|
||||||
|
'custom_nginx_configuration' => 'The custom_nginx_configuration should be base64 encoded.',
|
||||||
|
],
|
||||||
|
], 422);
|
||||||
|
}
|
||||||
|
}
|
||||||
$return = $this->validateDataApplications($request, $server);
|
$return = $this->validateDataApplications($request, $server);
|
||||||
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
if ($return instanceof \Illuminate\Http\JsonResponse) {
|
||||||
return $return;
|
return $return;
|
||||||
|
@@ -1990,22 +1990,11 @@ COPY . .
|
|||||||
RUN rm -f /usr/share/nginx/html/nginx.conf
|
RUN rm -f /usr/share/nginx/html/nginx.conf
|
||||||
RUN rm -f /usr/share/nginx/html/Dockerfile
|
RUN rm -f /usr/share/nginx/html/Dockerfile
|
||||||
COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
||||||
$nginx_config = base64_encode('server {
|
if (str($this->application->custom_nginx_configuration)->isNotEmpty()) {
|
||||||
listen 80;
|
$nginx_config = base64_encode($this->application->custom_nginx_configuration);
|
||||||
listen [::]:80;
|
} else {
|
||||||
server_name localhost;
|
$nginx_config = base64_encode(defaultNginxConfiguration());
|
||||||
|
|
||||||
location / {
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
index index.html;
|
|
||||||
try_files $uri $uri.html $uri/index.html $uri/ /index.html =404;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
|
||||||
location = /50x.html {
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
}
|
|
||||||
}');
|
|
||||||
} else {
|
} else {
|
||||||
if ($this->application->build_pack === 'nixpacks') {
|
if ($this->application->build_pack === 'nixpacks') {
|
||||||
$this->nixpacks_plan = base64_encode($this->nixpacks_plan);
|
$this->nixpacks_plan = base64_encode($this->nixpacks_plan);
|
||||||
@@ -2068,23 +2057,11 @@ WORKDIR /usr/share/nginx/html/
|
|||||||
LABEL coolify.deploymentId={$this->deployment_uuid}
|
LABEL coolify.deploymentId={$this->deployment_uuid}
|
||||||
COPY --from=$this->build_image_name /app/{$this->application->publish_directory} .
|
COPY --from=$this->build_image_name /app/{$this->application->publish_directory} .
|
||||||
COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
||||||
|
if (str($this->application->custom_nginx_configuration)->isNotEmpty()) {
|
||||||
$nginx_config = base64_encode('server {
|
$nginx_config = base64_encode($this->application->custom_nginx_configuration);
|
||||||
listen 80;
|
} else {
|
||||||
listen [::]:80;
|
$nginx_config = base64_encode(defaultNginxConfiguration());
|
||||||
server_name localhost;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
index index.html;
|
|
||||||
try_files $uri $uri.html $uri/index.html $uri/ /index.html =404;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
|
||||||
location = /50x.html {
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
}
|
|
||||||
}');
|
|
||||||
}
|
}
|
||||||
$build_command = "docker build {$this->addHosts} --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t {$this->production_image_name} {$this->workdir}";
|
$build_command = "docker build {$this->addHosts} --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t {$this->production_image_name} {$this->workdir}";
|
||||||
$base64_build_command = base64_encode($build_command);
|
$base64_build_command = base64_encode($build_command);
|
||||||
|
@@ -84,6 +84,7 @@ class General extends Component
|
|||||||
'application.pre_deployment_command_container' => 'nullable',
|
'application.pre_deployment_command_container' => 'nullable',
|
||||||
'application.post_deployment_command' => 'nullable',
|
'application.post_deployment_command' => 'nullable',
|
||||||
'application.post_deployment_command_container' => 'nullable',
|
'application.post_deployment_command_container' => 'nullable',
|
||||||
|
'application.custom_nginx_configuration' => 'nullable',
|
||||||
'application.settings.is_static' => 'boolean|required',
|
'application.settings.is_static' => 'boolean|required',
|
||||||
'application.settings.is_build_server_enabled' => 'boolean|required',
|
'application.settings.is_build_server_enabled' => 'boolean|required',
|
||||||
'application.settings.is_container_label_escape_enabled' => 'boolean|required',
|
'application.settings.is_container_label_escape_enabled' => 'boolean|required',
|
||||||
@@ -121,6 +122,7 @@ class General extends Component
|
|||||||
'application.custom_docker_run_options' => 'Custom docker run commands',
|
'application.custom_docker_run_options' => 'Custom docker run commands',
|
||||||
'application.docker_compose_custom_start_command' => 'Docker compose custom start command',
|
'application.docker_compose_custom_start_command' => 'Docker compose custom start command',
|
||||||
'application.docker_compose_custom_build_command' => 'Docker compose custom build command',
|
'application.docker_compose_custom_build_command' => 'Docker compose custom build command',
|
||||||
|
'application.custom_nginx_configuration' => 'Custom Nginx configuration',
|
||||||
'application.settings.is_static' => 'Is static',
|
'application.settings.is_static' => 'Is static',
|
||||||
'application.settings.is_build_server_enabled' => 'Is build server enabled',
|
'application.settings.is_build_server_enabled' => 'Is build server enabled',
|
||||||
'application.settings.is_container_label_escape_enabled' => 'Is container label escape enabled',
|
'application.settings.is_container_label_escape_enabled' => 'Is container label escape enabled',
|
||||||
@@ -241,6 +243,13 @@ class General extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updatedApplicationSettingsIsStatic($value)
|
||||||
|
{
|
||||||
|
if ($value) {
|
||||||
|
$this->generateNginxConfiguration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function updatedApplicationBuildPack()
|
public function updatedApplicationBuildPack()
|
||||||
{
|
{
|
||||||
if ($this->application->build_pack !== 'nixpacks') {
|
if ($this->application->build_pack !== 'nixpacks') {
|
||||||
@@ -257,6 +266,7 @@ class General extends Component
|
|||||||
if ($this->application->build_pack === 'static') {
|
if ($this->application->build_pack === 'static') {
|
||||||
$this->application->ports_exposes = $this->ports_exposes = 80;
|
$this->application->ports_exposes = $this->ports_exposes = 80;
|
||||||
$this->resetDefaultLabels(false);
|
$this->resetDefaultLabels(false);
|
||||||
|
$this->generateNginxConfiguration();
|
||||||
}
|
}
|
||||||
$this->submit();
|
$this->submit();
|
||||||
$this->dispatch('buildPackUpdated');
|
$this->dispatch('buildPackUpdated');
|
||||||
@@ -274,6 +284,13 @@ class General extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function generateNginxConfiguration()
|
||||||
|
{
|
||||||
|
$this->application->custom_nginx_configuration = defaultNginxConfiguration();
|
||||||
|
$this->application->save();
|
||||||
|
$this->dispatch('success', 'Nginx configuration generated.');
|
||||||
|
}
|
||||||
|
|
||||||
public function resetDefaultLabels($manualReset = false)
|
public function resetDefaultLabels($manualReset = false)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@@ -23,6 +23,9 @@ class Upgrade extends Component
|
|||||||
try {
|
try {
|
||||||
$this->latestVersion = get_latest_version_of_coolify();
|
$this->latestVersion = get_latest_version_of_coolify();
|
||||||
$this->isUpgradeAvailable = data_get(InstanceSettings::get(), 'new_version_available', false);
|
$this->isUpgradeAvailable = data_get(InstanceSettings::get(), 'new_version_available', false);
|
||||||
|
if (isDev()) {
|
||||||
|
$this->isUpgradeAvailable = true;
|
||||||
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
|
@@ -98,6 +98,7 @@ use Visus\Cuid2\Cuid2;
|
|||||||
'updated_at' => ['type' => 'string', 'format' => 'date-time', 'description' => 'The date and time when the application was last updated.'],
|
'updated_at' => ['type' => 'string', 'format' => 'date-time', 'description' => 'The date and time when the application was last updated.'],
|
||||||
'deleted_at' => ['type' => 'string', 'format' => 'date-time', 'nullable' => true, 'description' => 'The date and time when the application was deleted.'],
|
'deleted_at' => ['type' => 'string', 'format' => 'date-time', 'nullable' => true, 'description' => 'The date and time when the application was deleted.'],
|
||||||
'compose_parsing_version' => ['type' => 'string', 'description' => 'How Coolify parse the compose file.'],
|
'compose_parsing_version' => ['type' => 'string', 'description' => 'How Coolify parse the compose file.'],
|
||||||
|
'custom_nginx_configuration' => ['type' => 'string', 'nullable' => true, 'description' => 'Custom Nginx configuration base64 encoded.'],
|
||||||
]
|
]
|
||||||
)]
|
)]
|
||||||
|
|
||||||
@@ -114,11 +115,11 @@ class Application extends BaseModel
|
|||||||
protected static function booted()
|
protected static function booted()
|
||||||
{
|
{
|
||||||
static::saving(function ($application) {
|
static::saving(function ($application) {
|
||||||
|
$payload = [];
|
||||||
|
if ($application->isDirty('fqdn')) {
|
||||||
if ($application->fqdn === '') {
|
if ($application->fqdn === '') {
|
||||||
$application->fqdn = null;
|
$application->fqdn = null;
|
||||||
}
|
}
|
||||||
$payload = [];
|
|
||||||
if ($application->isDirty('fqdn')) {
|
|
||||||
$payload['fqdn'] = $application->fqdn;
|
$payload['fqdn'] = $application->fqdn;
|
||||||
}
|
}
|
||||||
if ($application->isDirty('install_command')) {
|
if ($application->isDirty('install_command')) {
|
||||||
@@ -139,6 +140,11 @@ class Application extends BaseModel
|
|||||||
if ($application->isDirty('status')) {
|
if ($application->isDirty('status')) {
|
||||||
$payload['last_online_at'] = now();
|
$payload['last_online_at'] = now();
|
||||||
}
|
}
|
||||||
|
if ($application->isDirty('custom_nginx_configuration')) {
|
||||||
|
if ($application->custom_nginx_configuration === '') {
|
||||||
|
$payload['custom_nginx_configuration'] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (count($payload) > 0) {
|
if (count($payload) > 0) {
|
||||||
$application->forceFill($payload);
|
$application->forceFill($payload);
|
||||||
}
|
}
|
||||||
@@ -632,6 +638,14 @@ class Application extends BaseModel
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function customNginxConfiguration(): Attribute
|
||||||
|
{
|
||||||
|
return Attribute::make(
|
||||||
|
set: fn ($value) => base64_encode($value),
|
||||||
|
get: fn ($value) => base64_decode($value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function portsExposesArray(): Attribute
|
public function portsExposesArray(): Attribute
|
||||||
{
|
{
|
||||||
return Attribute::make(
|
return Attribute::make(
|
||||||
@@ -862,7 +876,7 @@ class Application extends BaseModel
|
|||||||
|
|
||||||
public function isConfigurationChanged(bool $save = false)
|
public function isConfigurationChanged(bool $save = false)
|
||||||
{
|
{
|
||||||
$newConfigHash = $this->fqdn.$this->git_repository.$this->git_branch.$this->git_commit_sha.$this->build_pack.$this->static_image.$this->install_command.$this->build_command.$this->start_command.$this->ports_exposes.$this->ports_mappings.$this->base_directory.$this->publish_directory.$this->dockerfile.$this->dockerfile_location.$this->custom_labels.$this->custom_docker_run_options.$this->dockerfile_target_build.$this->redirect;
|
$newConfigHash = base64_encode($this->fqdn.$this->git_repository.$this->git_branch.$this->git_commit_sha.$this->build_pack.$this->static_image.$this->install_command.$this->build_command.$this->start_command.$this->ports_exposes.$this->ports_mappings.$this->base_directory.$this->publish_directory.$this->dockerfile.$this->dockerfile_location.$this->custom_labels.$this->custom_docker_run_options.$this->dockerfile_target_build.$this->redirect.$this->custom_nginx_configuration);
|
||||||
if ($this->pull_request_id === 0 || $this->pull_request_id === null) {
|
if ($this->pull_request_id === 0 || $this->pull_request_id === null) {
|
||||||
$newConfigHash .= json_encode($this->environment_variables()->get('value')->sort());
|
$newConfigHash .= json_encode($this->environment_variables()->get('value')->sort());
|
||||||
} else {
|
} else {
|
||||||
|
@@ -64,7 +64,7 @@ class Server extends BaseModel
|
|||||||
$server->forceFill($payload);
|
$server->forceFill($payload);
|
||||||
});
|
});
|
||||||
static::saved(function ($server) {
|
static::saved(function ($server) {
|
||||||
if ($server->privateKey->isDirty()) {
|
if ($server->privateKey?->isDirty()) {
|
||||||
refresh_server_connection($server->privateKey);
|
refresh_server_connection($server->privateKey);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -4062,3 +4062,33 @@ function isEmailRateLimited(string $limiterKey, int $decaySeconds = 3600, ?calla
|
|||||||
|
|
||||||
return $rateLimited;
|
return $rateLimited;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function defaultNginxConfiguration(): string
|
||||||
|
{
|
||||||
|
return 'server {
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
try_files $uri $uri/index.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
try_files $uri @redirect_to_index;
|
||||||
|
internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_page 404 = @handle_404;
|
||||||
|
|
||||||
|
location @handle_404 {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
try_files /404.html @redirect_to_index;
|
||||||
|
internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
location @redirect_to_index {
|
||||||
|
return 302 /;
|
||||||
|
}
|
||||||
|
}';
|
||||||
|
}
|
||||||
|
@@ -7,7 +7,7 @@ return [
|
|||||||
|
|
||||||
// The release version of your application
|
// The release version of your application
|
||||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||||
'release' => '4.0.0-beta.364',
|
'release' => '4.0.0-beta.367',
|
||||||
|
|
||||||
// When left empty or `null` the Laravel environment will be used
|
// When left empty or `null` the Laravel environment will be used
|
||||||
'environment' => config('app.env'),
|
'environment' => config('app.env'),
|
||||||
|
@@ -6,21 +6,7 @@ return [
|
|||||||
// Stripe
|
// Stripe
|
||||||
'stripe_api_key' => env('STRIPE_API_KEY', null),
|
'stripe_api_key' => env('STRIPE_API_KEY', null),
|
||||||
'stripe_webhook_secret' => env('STRIPE_WEBHOOK_SECRET', null),
|
'stripe_webhook_secret' => env('STRIPE_WEBHOOK_SECRET', null),
|
||||||
'stripe_price_id_basic_monthly' => env('STRIPE_PRICE_ID_BASIC_MONTHLY', null),
|
|
||||||
'stripe_price_id_basic_yearly' => env('STRIPE_PRICE_ID_BASIC_YEARLY', null),
|
|
||||||
'stripe_price_id_pro_monthly' => env('STRIPE_PRICE_ID_PRO_MONTHLY', null),
|
|
||||||
'stripe_price_id_pro_yearly' => env('STRIPE_PRICE_ID_PRO_YEARLY', null),
|
|
||||||
'stripe_price_id_ultimate_monthly' => env('STRIPE_PRICE_ID_ULTIMATE_MONTHLY', null),
|
|
||||||
'stripe_price_id_ultimate_yearly' => env('STRIPE_PRICE_ID_ULTIMATE_YEARLY', null),
|
|
||||||
'stripe_excluded_plans' => env('STRIPE_EXCLUDED_PLANS', null),
|
'stripe_excluded_plans' => env('STRIPE_EXCLUDED_PLANS', null),
|
||||||
|
|
||||||
'stripe_price_id_basic_monthly_old' => env('STRIPE_PRICE_ID_BASIC_MONTHLY_OLD', null),
|
|
||||||
'stripe_price_id_basic_yearly_old' => env('STRIPE_PRICE_ID_BASIC_YEARLY_OLD', null),
|
|
||||||
'stripe_price_id_pro_monthly_old' => env('STRIPE_PRICE_ID_PRO_MONTHLY_OLD', null),
|
|
||||||
'stripe_price_id_pro_yearly_old' => env('STRIPE_PRICE_ID_PRO_YEARLY_OLD', null),
|
|
||||||
'stripe_price_id_ultimate_monthly_old' => env('STRIPE_PRICE_ID_ULTIMATE_MONTHLY_OLD', null),
|
|
||||||
'stripe_price_id_ultimate_yearly_old' => env('STRIPE_PRICE_ID_ULTIMATE_YEARLY_OLD', null),
|
|
||||||
|
|
||||||
'stripe_price_id_dynamic_monthly' => env('STRIPE_PRICE_ID_DYNAMIC_MONTHLY', null),
|
'stripe_price_id_dynamic_monthly' => env('STRIPE_PRICE_ID_DYNAMIC_MONTHLY', null),
|
||||||
'stripe_price_id_dynamic_yearly' => env('STRIPE_PRICE_ID_DYNAMIC_YEARLY', null),
|
'stripe_price_id_dynamic_yearly' => env('STRIPE_PRICE_ID_DYNAMIC_YEARLY', null),
|
||||||
];
|
];
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return '4.0.0-beta.364';
|
return '4.0.0-beta.367';
|
||||||
|
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->longText('custom_nginx_configuration')->nullable()->after('static_image');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('custom_nginx_configuration');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@@ -29,6 +29,7 @@ services:
|
|||||||
- REDIS_HOST
|
- REDIS_HOST
|
||||||
- REDIS_PASSWORD
|
- REDIS_PASSWORD
|
||||||
- HORIZON_BALANCE
|
- HORIZON_BALANCE
|
||||||
|
- HORIZON_MIN_PROCESSES
|
||||||
- HORIZON_MAX_PROCESSES
|
- HORIZON_MAX_PROCESSES
|
||||||
- HORIZON_BALANCE_MAX_SHIFT
|
- HORIZON_BALANCE_MAX_SHIFT
|
||||||
- HORIZON_BALANCE_COOLDOWN
|
- HORIZON_BALANCE_COOLDOWN
|
||||||
@@ -50,29 +51,8 @@ services:
|
|||||||
- TERMINAL_HOST
|
- TERMINAL_HOST
|
||||||
- TERMINAL_PORT
|
- TERMINAL_PORT
|
||||||
- AUTOUPDATE
|
- AUTOUPDATE
|
||||||
- SELF_HOSTED
|
|
||||||
- SSH_MUX_ENABLED
|
- SSH_MUX_ENABLED
|
||||||
- SSH_MUX_PERSIST_TIME
|
- SSH_MUX_PERSIST_TIME
|
||||||
- FEEDBACK_DISCORD_WEBHOOK
|
|
||||||
- WAITLIST
|
|
||||||
- SUBSCRIPTION_PROVIDER
|
|
||||||
- STRIPE_API_KEY
|
|
||||||
- STRIPE_WEBHOOK_SECRET
|
|
||||||
- STRIPE_PRICE_ID_BASIC_MONTHLY
|
|
||||||
- STRIPE_PRICE_ID_BASIC_YEARLY
|
|
||||||
- STRIPE_PRICE_ID_PRO_MONTHLY
|
|
||||||
- STRIPE_PRICE_ID_PRO_YEARLY
|
|
||||||
- STRIPE_PRICE_ID_ULTIMATE_MONTHLY
|
|
||||||
- STRIPE_PRICE_ID_ULTIMATE_YEARLY
|
|
||||||
- STRIPE_PRICE_ID_DYNAMIC_MONTHLY
|
|
||||||
- STRIPE_PRICE_ID_DYNAMIC_YEARLY
|
|
||||||
- STRIPE_PRICE_ID_BASIC_MONTHLY_OLD
|
|
||||||
- STRIPE_PRICE_ID_BASIC_YEARLY_OLD
|
|
||||||
- STRIPE_PRICE_ID_PRO_MONTHLY_OLD
|
|
||||||
- STRIPE_PRICE_ID_PRO_YEARLY_OLD
|
|
||||||
- STRIPE_PRICE_ID_ULTIMATE_MONTHLY_OLD
|
|
||||||
- STRIPE_PRICE_ID_ULTIMATE_YEARLY_OLD
|
|
||||||
- STRIPE_EXCLUDED_PLANS
|
|
||||||
ports:
|
ports:
|
||||||
- "${APP_PORT:-8000}:80"
|
- "${APP_PORT:-8000}:80"
|
||||||
expose:
|
expose:
|
||||||
|
@@ -29,6 +29,7 @@ services:
|
|||||||
- REDIS_HOST
|
- REDIS_HOST
|
||||||
- REDIS_PASSWORD
|
- REDIS_PASSWORD
|
||||||
- HORIZON_BALANCE
|
- HORIZON_BALANCE
|
||||||
|
- HORIZON_MIN_PROCESSES
|
||||||
- HORIZON_MAX_PROCESSES
|
- HORIZON_MAX_PROCESSES
|
||||||
- HORIZON_BALANCE_MAX_SHIFT
|
- HORIZON_BALANCE_MAX_SHIFT
|
||||||
- HORIZON_BALANCE_COOLDOWN
|
- HORIZON_BALANCE_COOLDOWN
|
||||||
@@ -50,29 +51,8 @@ services:
|
|||||||
- TERMINAL_HOST
|
- TERMINAL_HOST
|
||||||
- TERMINAL_PORT
|
- TERMINAL_PORT
|
||||||
- AUTOUPDATE
|
- AUTOUPDATE
|
||||||
- SELF_HOSTED
|
|
||||||
- SSH_MUX_ENABLED
|
- SSH_MUX_ENABLED
|
||||||
- SSH_MUX_PERSIST_TIME
|
- SSH_MUX_PERSIST_TIME
|
||||||
- FEEDBACK_DISCORD_WEBHOOK
|
|
||||||
- WAITLIST
|
|
||||||
- SUBSCRIPTION_PROVIDER
|
|
||||||
- STRIPE_API_KEY
|
|
||||||
- STRIPE_WEBHOOK_SECRET
|
|
||||||
- STRIPE_PRICE_ID_BASIC_MONTHLY
|
|
||||||
- STRIPE_PRICE_ID_BASIC_YEARLY
|
|
||||||
- STRIPE_PRICE_ID_PRO_MONTHLY
|
|
||||||
- STRIPE_PRICE_ID_PRO_YEARLY
|
|
||||||
- STRIPE_PRICE_ID_ULTIMATE_MONTHLY
|
|
||||||
- STRIPE_PRICE_ID_ULTIMATE_YEARLY
|
|
||||||
- STRIPE_PRICE_ID_DYNAMIC_MONTHLY
|
|
||||||
- STRIPE_PRICE_ID_DYNAMIC_YEARLY
|
|
||||||
- STRIPE_PRICE_ID_BASIC_MONTHLY_OLD
|
|
||||||
- STRIPE_PRICE_ID_BASIC_YEARLY_OLD
|
|
||||||
- STRIPE_PRICE_ID_PRO_MONTHLY_OLD
|
|
||||||
- STRIPE_PRICE_ID_PRO_YEARLY_OLD
|
|
||||||
- STRIPE_PRICE_ID_ULTIMATE_MONTHLY_OLD
|
|
||||||
- STRIPE_PRICE_ID_ULTIMATE_YEARLY_OLD
|
|
||||||
- STRIPE_EXCLUDED_PLANS
|
|
||||||
ports:
|
ports:
|
||||||
- "${APP_PORT:-8000}:80"
|
- "${APP_PORT:-8000}:80"
|
||||||
expose:
|
expose:
|
||||||
@@ -113,7 +93,7 @@ services:
|
|||||||
retries: 10
|
retries: 10
|
||||||
timeout: 2s
|
timeout: 2s
|
||||||
soketi:
|
soketi:
|
||||||
image: 'ghcr.io/coollabsio/coolify-realtime:1.0.3'
|
image: 'ghcr.io/coollabsio/coolify-realtime:1.0.4'
|
||||||
ports:
|
ports:
|
||||||
- "${SOKETI_PORT:-6001}:6001"
|
- "${SOKETI_PORT:-6001}:6001"
|
||||||
- "6002:6002"
|
- "6002:6002"
|
||||||
|
@@ -1,11 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
## Do not modify this file. You will lose the ability to autoupdate!
|
## Do not modify this file. You will lose the ability to autoupdate!
|
||||||
|
|
||||||
VERSION="1.2"
|
VERSION="13"
|
||||||
CDN="https://cdn.coollabs.io/coolify-nightly"
|
CDN="https://cdn.coollabs.io/coolify-nightly"
|
||||||
LATEST_IMAGE=${1:-latest}
|
LATEST_IMAGE=${1:-latest}
|
||||||
LATEST_HELPER_VERSION=${2:-latest}
|
LATEST_HELPER_VERSION=${2:-latest}
|
||||||
|
|
||||||
DATE=$(date +%Y-%m-%d-%H-%M-%S)
|
DATE=$(date +%Y-%m-%d-%H-%M-%S)
|
||||||
|
LOGFILE="/data/coolify/source/upgrade-${DATE}.log"
|
||||||
|
|
||||||
curl -fsSL $CDN/docker-compose.yml -o /data/coolify/source/docker-compose.yml
|
curl -fsSL $CDN/docker-compose.yml -o /data/coolify/source/docker-compose.yml
|
||||||
curl -fsSL $CDN/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml
|
curl -fsSL $CDN/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml
|
||||||
@@ -32,8 +34,8 @@ docker network create --attachable coolify 2>/dev/null
|
|||||||
# docker network create --attachable --driver=overlay coolify-overlay 2>/dev/null
|
# docker network create --attachable --driver=overlay coolify-overlay 2>/dev/null
|
||||||
|
|
||||||
if [ -f /data/coolify/source/docker-compose.custom.yml ]; then
|
if [ -f /data/coolify/source/docker-compose.custom.yml ]; then
|
||||||
echo "docker-compose.custom.yml detected."
|
echo "docker-compose.custom.yml detected." >> $LOGFILE
|
||||||
docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/coollabsio/coolify-helper:${LATEST_HELPER_VERSION:-latest} bash -c "LATEST_IMAGE=${1:-} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml -f /data/coolify/source/docker-compose.custom.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" > /data/coolify/source/upgrade-${DATE}.log 2>&1
|
docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/coollabsio/coolify-helper:${LATEST_HELPER_VERSION} bash -c "LATEST_IMAGE=${LATEST_IMAGE} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml -f /data/coolify/source/docker-compose.custom.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" >> $LOGFILE 2>&1
|
||||||
else
|
else
|
||||||
docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/coollabsio/coolify-helper:${LATEST_HELPER_VERSION:-latest} bash -c "LATEST_IMAGE=${1:-} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" > /data/coolify/source/upgrade-${DATE}.log 2>&1
|
docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/coollabsio/coolify-helper:${LATEST_HELPER_VERSION} bash -c "LATEST_IMAGE=${LATEST_IMAGE} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" >> $LOGFILE 2>&1
|
||||||
fi
|
fi
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"coolify": {
|
"coolify": {
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.363"
|
"version": "4.0.0-beta.367"
|
||||||
},
|
},
|
||||||
"nightly": {
|
"nightly": {
|
||||||
"version": "4.0.0-beta.364"
|
"version": "4.0.0-beta.368"
|
||||||
},
|
},
|
||||||
"helper": {
|
"helper": {
|
||||||
"version": "1.0.3"
|
"version": "1.0.3"
|
||||||
|
@@ -61,8 +61,16 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
@if ($application->settings->is_static || $application->build_pack === 'static')
|
||||||
|
<x-forms.textarea id="application.custom_nginx_configuration"
|
||||||
|
placeholder="Empty means default configuration will be used." label="Custom Nginx Configuration"
|
||||||
|
helper="You can add custom Nginx configuration here." />
|
||||||
|
<x-forms.button wire:click="generateNginxConfiguration">Generate Default Nginx
|
||||||
|
Configuration</x-forms.button>
|
||||||
|
@endif
|
||||||
@if ($application->build_pack !== 'dockercompose')
|
@if ($application->build_pack !== 'dockercompose')
|
||||||
<div class="flex items-end gap-2">
|
<div class="flex items-end gap-2">
|
||||||
|
|
||||||
<x-forms.input placeholder="https://coolify.io" wire:model.blur="application.fqdn" label="Domains"
|
<x-forms.input placeholder="https://coolify.io" wire:model.blur="application.fqdn" label="Domains"
|
||||||
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io,https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. " />
|
helper="You can specify one domain with path or more with comma. You can specify a port to bind the domain to.<br><br><span class='text-helper'>Example</span><br>- http://app.coolify.io,https://cloud.coolify.io/dashboard<br>- http://app.coolify.io/api/v3<br>- http://app.coolify.io:3000 -> app.coolify.io will point to port 3000 inside the container. " />
|
||||||
<x-forms.button wire:click="getWildcardDomain">Generate Domain
|
<x-forms.button wire:click="getWildcardDomain">Generate Domain
|
||||||
|
@@ -2,8 +2,7 @@
|
|||||||
x-init="$wire.checkUpdate" x-data="upgradeModal">
|
x-init="$wire.checkUpdate" x-data="upgradeModal">
|
||||||
@if ($isUpgradeAvailable)
|
@if ($isUpgradeAvailable)
|
||||||
<div :class="{ 'z-40': modalOpen }" class="relative w-auto h-auto">
|
<div :class="{ 'z-40': modalOpen }" class="relative w-auto h-auto">
|
||||||
<button class="menu-item" @click="modalOpen=true">
|
<button class="menu-item" @click="modalOpen=true" x-show="showProgress">
|
||||||
@if ($showProgress)
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg"
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300 lds-heart" viewBox="0 0 24 24"
|
class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300 lds-heart" viewBox="0 0 24 24"
|
||||||
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||||
@@ -12,7 +11,8 @@
|
|||||||
<path d="M19.5 13.572l-7.5 7.428l-7.5 -7.428m0 0a5 5 0 1 1 7.5 -6.566a5 5 0 1 1 7.5 6.572" />
|
<path d="M19.5 13.572l-7.5 7.428l-7.5 -7.428m0 0a5 5 0 1 1 7.5 -6.566a5 5 0 1 1 7.5 6.572" />
|
||||||
</svg>
|
</svg>
|
||||||
In progress
|
In progress
|
||||||
@else
|
</button>
|
||||||
|
<button class="menu-item" @click="modalOpen=true" x-show="!showProgress">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg"
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300" viewBox="0 0 24 24"
|
class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300" viewBox="0 0 24 24"
|
||||||
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||||
@@ -24,9 +24,7 @@
|
|||||||
<path d="M9 18h6" />
|
<path d="M9 18h6" />
|
||||||
</svg>
|
</svg>
|
||||||
Upgrade
|
Upgrade
|
||||||
@endif
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<template x-teleport="body">
|
<template x-teleport="body">
|
||||||
<div x-show="modalOpen"
|
<div x-show="modalOpen"
|
||||||
class="fixed top-0 lg:pt-10 left-0 z-[99] flex items-start justify-center w-screen h-screen"
|
class="fixed top-0 lg:pt-10 left-0 z-[99] flex items-start justify-center w-screen h-screen"
|
||||||
@@ -45,15 +43,13 @@
|
|||||||
class="relative w-full py-6 border rounded min-w-full lg:min-w-[36rem] max-w-fit bg-neutral-100 border-neutral-400 dark:bg-base px-7 dark:border-coolgray-300">
|
class="relative w-full py-6 border rounded min-w-full lg:min-w-[36rem] max-w-fit bg-neutral-100 border-neutral-400 dark:bg-base px-7 dark:border-coolgray-300">
|
||||||
<div class="flex items-center justify-between pb-3">
|
<div class="flex items-center justify-between pb-3">
|
||||||
<h3 class="text-lg font-semibold">Upgrade confirmation</h3>
|
<h3 class="text-lg font-semibold">Upgrade confirmation</h3>
|
||||||
@if (!$showProgress)
|
<button x-show="!showProgress" @click="modalOpen=false"
|
||||||
<button @click="modalOpen=false"
|
|
||||||
class="absolute top-0 right-0 flex items-center justify-center w-8 h-8 mt-5 mr-5 text-gray-600 rounded-full hover:text-gray-800 hover:bg-gray-50">
|
class="absolute top-0 right-0 flex items-center justify-center w-8 h-8 mt-5 mr-5 text-gray-600 rounded-full hover:text-gray-800 hover:bg-gray-50">
|
||||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none"
|
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||||
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
<div class="relative w-auto pb-8">
|
<div class="relative w-auto pb-8">
|
||||||
<p>Are you sure you would like to upgrade your instance to {{ $latestVersion }}?</p>
|
<p>Are you sure you would like to upgrade your instance to {{ $latestVersion }}?</p>
|
||||||
@@ -65,22 +61,18 @@
|
|||||||
<a class="font-bold underline dark:text-white" href="https://coolify.io/docs/upgrade"
|
<a class="font-bold underline dark:text-white" href="https://coolify.io/docs/upgrade"
|
||||||
target="_blank">guide</a> on what to do.
|
target="_blank">guide</a> on what to do.
|
||||||
</p>
|
</p>
|
||||||
@if ($showProgress)
|
<div class="flex flex-col pt-4" x-show="showProgress">
|
||||||
<div class="flex flex-col pt-4">
|
|
||||||
<h2>Progress <x-loading /></h2>
|
<h2>Progress <x-loading /></h2>
|
||||||
<div x-html="currentStatus"></div>
|
<div x-html="currentStatus"></div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-4">
|
<div class="flex gap-4" x-show="!showProgress">
|
||||||
@if (!$showProgress)
|
|
||||||
<x-forms.button @click="modalOpen=false"
|
<x-forms.button @click="modalOpen=false"
|
||||||
class="w-24 dark:bg-coolgray-200 dark:hover:bg-coolgray-300">Cancel
|
class="w-24 dark:bg-coolgray-200 dark:hover:bg-coolgray-300">Cancel
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
<x-forms.button @click="confirmed" class="w-24" isHighlighted type="button">Continue
|
<x-forms.button @click="confirmed" class="w-24" isHighlighted type="button">Continue
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -93,12 +85,12 @@
|
|||||||
document.addEventListener('alpine:init', () => {
|
document.addEventListener('alpine:init', () => {
|
||||||
Alpine.data('upgradeModal', () => ({
|
Alpine.data('upgradeModal', () => ({
|
||||||
modalOpen: false,
|
modalOpen: false,
|
||||||
showProgress: @js($showProgress),
|
showProgress: false,
|
||||||
currentStatus: '',
|
currentStatus: '',
|
||||||
confirmed() {
|
confirmed() {
|
||||||
|
this.showProgress = true;
|
||||||
this.$wire.$call('upgrade')
|
this.$wire.$call('upgrade')
|
||||||
this.upgrade();
|
this.upgrade();
|
||||||
this.$wire.showProgress = true;
|
|
||||||
window.addEventListener('beforeunload', (event) => {
|
window.addEventListener('beforeunload', (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.returnValue = '';
|
event.returnValue = '';
|
||||||
|
@@ -1,11 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
## Do not modify this file. You will lose the ability to autoupdate!
|
## Do not modify this file. You will lose the ability to autoupdate!
|
||||||
|
|
||||||
VERSION="1.2"
|
VERSION="13"
|
||||||
CDN="https://cdn.coollabs.io/coolify"
|
CDN="https://cdn.coollabs.io/coolify"
|
||||||
LATEST_IMAGE=${1:-latest}
|
LATEST_IMAGE=${1:-latest}
|
||||||
LATEST_HELPER_VERSION=${2:-latest}
|
LATEST_HELPER_VERSION=${2:-latest}
|
||||||
|
|
||||||
DATE=$(date +%Y-%m-%d-%H-%M-%S)
|
DATE=$(date +%Y-%m-%d-%H-%M-%S)
|
||||||
|
LOGFILE="/data/coolify/source/upgrade-${DATE}.log"
|
||||||
|
|
||||||
curl -fsSL $CDN/docker-compose.yml -o /data/coolify/source/docker-compose.yml
|
curl -fsSL $CDN/docker-compose.yml -o /data/coolify/source/docker-compose.yml
|
||||||
curl -fsSL $CDN/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml
|
curl -fsSL $CDN/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml
|
||||||
@@ -32,8 +34,8 @@ docker network create --attachable coolify 2>/dev/null
|
|||||||
# docker network create --attachable --driver=overlay coolify-overlay 2>/dev/null
|
# docker network create --attachable --driver=overlay coolify-overlay 2>/dev/null
|
||||||
|
|
||||||
if [ -f /data/coolify/source/docker-compose.custom.yml ]; then
|
if [ -f /data/coolify/source/docker-compose.custom.yml ]; then
|
||||||
echo "docker-compose.custom.yml detected."
|
echo "docker-compose.custom.yml detected." >> $LOGFILE
|
||||||
docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/coollabsio/coolify-helper:${LATEST_HELPER_VERSION:-latest} bash -c "LATEST_IMAGE=${1:-} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml -f /data/coolify/source/docker-compose.custom.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" > /data/coolify/source/upgrade-${DATE}.log 2>&1
|
docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/coollabsio/coolify-helper:${LATEST_HELPER_VERSION} bash -c "LATEST_IMAGE=${LATEST_IMAGE} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml -f /data/coolify/source/docker-compose.custom.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" >> $LOGFILE 2>&1
|
||||||
else
|
else
|
||||||
docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/coollabsio/coolify-helper:${LATEST_HELPER_VERSION:-latest} bash -c "LATEST_IMAGE=${1:-} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" > /data/coolify/source/upgrade-${DATE}.log 2>&1
|
docker run -v /data/coolify/source:/data/coolify/source -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/coollabsio/coolify-helper:${LATEST_HELPER_VERSION} bash -c "LATEST_IMAGE=${LATEST_IMAGE} docker compose --env-file /data/coolify/source/.env -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml up -d --remove-orphans --force-recreate --wait --wait-timeout 60" >> $LOGFILE 2>&1
|
||||||
fi
|
fi
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"coolify": {
|
"coolify": {
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.364"
|
"version": "4.0.0-beta.367"
|
||||||
},
|
},
|
||||||
"nightly": {
|
"nightly": {
|
||||||
"version": "4.0.0-beta.365"
|
"version": "4.0.0-beta.368"
|
||||||
},
|
},
|
||||||
"helper": {
|
"helper": {
|
||||||
"version": "1.0.3"
|
"version": "1.0.3"
|
||||||
|
Reference in New Issue
Block a user