Merge branch 'next' into feat-db-ssl
@@ -30,7 +30,6 @@ class StopDatabaseProxy
|
|||||||
}
|
}
|
||||||
instant_remote_process(["docker rm -f {$uuid}-proxy"], $server);
|
instant_remote_process(["docker rm -f {$uuid}-proxy"], $server);
|
||||||
|
|
||||||
$database->is_public = false;
|
|
||||||
$database->save();
|
$database->save();
|
||||||
|
|
||||||
DatabaseProxyStopped::dispatch();
|
DatabaseProxyStopped::dispatch();
|
||||||
|
@@ -57,7 +57,7 @@ class StartProxy
|
|||||||
" echo 'Successfully stopped and removed existing coolify-proxy.'",
|
" echo 'Successfully stopped and removed existing coolify-proxy.'",
|
||||||
'fi',
|
'fi',
|
||||||
"echo 'Starting coolify-proxy.'",
|
"echo 'Starting coolify-proxy.'",
|
||||||
'docker compose up -d --remove-orphans',
|
'docker compose up -d',
|
||||||
"echo 'Successfully started coolify-proxy.'",
|
"echo 'Successfully started coolify-proxy.'",
|
||||||
]);
|
]);
|
||||||
$commands = $commands->merge(connectProxyToNetworks($server));
|
$commands = $commands->merge(connectProxyToNetworks($server));
|
||||||
|
@@ -1681,7 +1681,8 @@ class ApplicationsController extends Controller
|
|||||||
], 422);
|
], 422);
|
||||||
}
|
}
|
||||||
$domains = $request->domains;
|
$domains = $request->domains;
|
||||||
if ($request->has('domains') && $server->isProxyShouldRun()) {
|
$requestHasDomains = $request->has('domains');
|
||||||
|
if ($requestHasDomains && $server->isProxyShouldRun()) {
|
||||||
$uuid = $request->uuid;
|
$uuid = $request->uuid;
|
||||||
$fqdn = $request->domains;
|
$fqdn = $request->domains;
|
||||||
$fqdn = str($fqdn)->replaceEnd(',', '')->trim();
|
$fqdn = str($fqdn)->replaceEnd(',', '')->trim();
|
||||||
@@ -1743,7 +1744,7 @@ class ApplicationsController extends Controller
|
|||||||
removeUnnecessaryFieldsFromRequest($request);
|
removeUnnecessaryFieldsFromRequest($request);
|
||||||
|
|
||||||
$data = $request->all();
|
$data = $request->all();
|
||||||
if ($request->has('domains') && $server->isProxyShouldRun()) {
|
if ($requestHasDomains && $server->isProxyShouldRun()) {
|
||||||
data_set($data, 'fqdn', $domains);
|
data_set($data, 'fqdn', $domains);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -346,9 +346,9 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
if ($databaseWithCollections === 'all') {
|
if ($databaseWithCollections === 'all') {
|
||||||
$commands[] = 'mkdir -p '.$this->backup_dir;
|
$commands[] = 'mkdir -p '.$this->backup_dir;
|
||||||
if (str($this->database->image)->startsWith('mongo:4')) {
|
if (str($this->database->image)->startsWith('mongo:4')) {
|
||||||
$commands[] = "docker exec $this->container_name mongodump --uri=$url --gzip --archive > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mongodump --uri=\"$url\" --gzip --archive > $this->backup_location";
|
||||||
} else {
|
} else {
|
||||||
$commands[] = "docker exec $this->container_name mongodump --authenticationDatabase=admin --uri=$url --gzip --archive > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mongodump --authenticationDatabase=admin --uri=\"$url\" --gzip --archive > $this->backup_location";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (str($databaseWithCollections)->contains(':')) {
|
if (str($databaseWithCollections)->contains(':')) {
|
||||||
@@ -361,15 +361,15 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
$commands[] = 'mkdir -p '.$this->backup_dir;
|
$commands[] = 'mkdir -p '.$this->backup_dir;
|
||||||
if ($collectionsToExclude->count() === 0) {
|
if ($collectionsToExclude->count() === 0) {
|
||||||
if (str($this->database->image)->startsWith('mongo:4')) {
|
if (str($this->database->image)->startsWith('mongo:4')) {
|
||||||
$commands[] = "docker exec $this->container_name mongodump --uri=$url --gzip --archive > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mongodump --uri=\"$url\" --gzip --archive > $this->backup_location";
|
||||||
} else {
|
} else {
|
||||||
$commands[] = "docker exec $this->container_name mongodump --authenticationDatabase=admin --uri=$url --db $databaseName --gzip --archive > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mongodump --authenticationDatabase=admin --uri=\"$url\" --db $databaseName --gzip --archive > $this->backup_location";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (str($this->database->image)->startsWith('mongo:4')) {
|
if (str($this->database->image)->startsWith('mongo:4')) {
|
||||||
$commands[] = "docker exec $this->container_name mongodump --uri=$url --gzip --excludeCollection ".$collectionsToExclude->implode(' --excludeCollection ')." --archive > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mongodump --uri=$url --gzip --excludeCollection ".$collectionsToExclude->implode(' --excludeCollection ')." --archive > $this->backup_location";
|
||||||
} else {
|
} else {
|
||||||
$commands[] = "docker exec $this->container_name mongodump --authenticationDatabase=admin --uri=$url --db $databaseName --gzip --excludeCollection ".$collectionsToExclude->implode(' --excludeCollection ')." --archive > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mongodump --authenticationDatabase=admin --uri=\"$url\" --db $databaseName --gzip --excludeCollection ".$collectionsToExclude->implode(' --excludeCollection ')." --archive > $this->backup_location";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,9 +415,9 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
try {
|
try {
|
||||||
$commands[] = 'mkdir -p '.$this->backup_dir;
|
$commands[] = 'mkdir -p '.$this->backup_dir;
|
||||||
if ($this->backup->dump_all) {
|
if ($this->backup->dump_all) {
|
||||||
$commands[] = "docker exec $this->container_name mysqldump -u root -p{$this->database->mysql_root_password} --all-databases --single-transaction --quick --lock-tables=false --compress | gzip > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mysqldump -u root -p\"{$this->database->mysql_root_password}\" --all-databases --single-transaction --quick --lock-tables=false --compress | gzip > $this->backup_location";
|
||||||
} else {
|
} else {
|
||||||
$commands[] = "docker exec $this->container_name mysqldump -u root -p{$this->database->mysql_root_password} $database > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mysqldump -u root -p\"{$this->database->mysql_root_password}\" $database > $this->backup_location";
|
||||||
}
|
}
|
||||||
$this->backup_output = instant_remote_process($commands, $this->server);
|
$this->backup_output = instant_remote_process($commands, $this->server);
|
||||||
$this->backup_output = trim($this->backup_output);
|
$this->backup_output = trim($this->backup_output);
|
||||||
@@ -435,9 +435,9 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
try {
|
try {
|
||||||
$commands[] = 'mkdir -p '.$this->backup_dir;
|
$commands[] = 'mkdir -p '.$this->backup_dir;
|
||||||
if ($this->backup->dump_all) {
|
if ($this->backup->dump_all) {
|
||||||
$commands[] = "docker exec $this->container_name mariadb-dump -u root -p{$this->database->mariadb_root_password} --all-databases --single-transaction --quick --lock-tables=false --compress > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mariadb-dump -u root -p\"{$this->database->mariadb_root_password}\" --all-databases --single-transaction --quick --lock-tables=false --compress > $this->backup_location";
|
||||||
} else {
|
} else {
|
||||||
$commands[] = "docker exec $this->container_name mariadb-dump -u root -p{$this->database->mariadb_root_password} $database > $this->backup_location";
|
$commands[] = "docker exec $this->container_name mariadb-dump -u root -p\"{$this->database->mariadb_root_password}\" $database > $this->backup_location";
|
||||||
}
|
}
|
||||||
$this->backup_output = instant_remote_process($commands, $this->server);
|
$this->backup_output = instant_remote_process($commands, $this->server);
|
||||||
$this->backup_output = trim($this->backup_output);
|
$this->backup_output = trim($this->backup_output);
|
||||||
@@ -495,7 +495,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
} else {
|
} else {
|
||||||
$commands[] = "docker run -d --network {$network} --name backup-of-{$this->backup->uuid} --rm -v $this->backup_location:$this->backup_location:ro {$fullImageName}";
|
$commands[] = "docker run -d --network {$network} --name backup-of-{$this->backup->uuid} --rm -v $this->backup_location:$this->backup_location:ro {$fullImageName}";
|
||||||
}
|
}
|
||||||
$commands[] = "docker exec backup-of-{$this->backup->uuid} mc config host add temporary {$endpoint} $key $secret";
|
$commands[] = "docker exec backup-of-{$this->backup->uuid} mc config host add temporary {$endpoint} $key \"$secret\"";
|
||||||
$commands[] = "docker exec backup-of-{$this->backup->uuid} mc cp $this->backup_location temporary/$bucket{$this->backup_dir}/";
|
$commands[] = "docker exec backup-of-{$this->backup->uuid} mc cp $this->backup_location temporary/$bucket{$this->backup_dir}/";
|
||||||
instant_remote_process($commands, $this->server);
|
instant_remote_process($commands, $this->server);
|
||||||
|
|
||||||
|
@@ -188,11 +188,22 @@ class PublicGitRepository extends Component
|
|||||||
|
|
||||||
private function getGitSource()
|
private function getGitSource()
|
||||||
{
|
{
|
||||||
|
$this->git_branch = 'main';
|
||||||
|
$this->base_directory = '/';
|
||||||
|
|
||||||
$this->repository_url_parsed = Url::fromString($this->repository_url);
|
$this->repository_url_parsed = Url::fromString($this->repository_url);
|
||||||
$this->git_host = $this->repository_url_parsed->getHost();
|
$this->git_host = $this->repository_url_parsed->getHost();
|
||||||
$this->git_repository = $this->repository_url_parsed->getSegment(1).'/'.$this->repository_url_parsed->getSegment(2);
|
$this->git_repository = $this->repository_url_parsed->getSegment(1).'/'.$this->repository_url_parsed->getSegment(2);
|
||||||
|
|
||||||
if ($this->repository_url_parsed->getSegment(3) === 'tree') {
|
if ($this->repository_url_parsed->getSegment(3) === 'tree') {
|
||||||
$this->git_branch = str($this->repository_url_parsed->getPath())->after('tree/')->value();
|
$path = str($this->repository_url_parsed->getPath())->trim('/');
|
||||||
|
$this->git_branch = str($path)->after('tree/')->before('/')->value();
|
||||||
|
$this->base_directory = str($path)->after($this->git_branch)->after('/')->value();
|
||||||
|
if (filled($this->base_directory)) {
|
||||||
|
$this->base_directory = '/'.$this->base_directory;
|
||||||
|
} else {
|
||||||
|
$this->base_directory = '/';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->git_branch = 'main';
|
$this->git_branch = 'main';
|
||||||
}
|
}
|
||||||
|
@@ -138,6 +138,7 @@ class All extends Component
|
|||||||
private function handleBulkSubmit()
|
private function handleBulkSubmit()
|
||||||
{
|
{
|
||||||
$variables = parseEnvFormatToArray($this->variables);
|
$variables = parseEnvFormatToArray($this->variables);
|
||||||
|
|
||||||
$this->deleteRemovedVariables(false, $variables);
|
$this->deleteRemovedVariables(false, $variables);
|
||||||
$this->updateOrCreateVariables(false, $variables);
|
$this->updateOrCreateVariables(false, $variables);
|
||||||
|
|
||||||
@@ -189,6 +190,9 @@ class All extends Component
|
|||||||
private function updateOrCreateVariables($isPreview, $variables)
|
private function updateOrCreateVariables($isPreview, $variables)
|
||||||
{
|
{
|
||||||
foreach ($variables as $key => $value) {
|
foreach ($variables as $key => $value) {
|
||||||
|
if (str($key)->startsWith('SERVICE_FQDN') || str($key)->startsWith('SERVICE_URL')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$method = $isPreview ? 'environment_variables_preview' : 'environment_variables';
|
$method = $isPreview ? 'environment_variables_preview' : 'environment_variables';
|
||||||
$found = $this->resource->$method()->where('key', $key)->first();
|
$found = $this->resource->$method()->where('key', $key)->first();
|
||||||
|
|
||||||
|
@@ -30,6 +30,6 @@ class SwitchTeam extends Component
|
|||||||
}
|
}
|
||||||
refreshSession($team_to_switch_to);
|
refreshSession($team_to_switch_to);
|
||||||
|
|
||||||
return redirect(request()->header('Referer'));
|
return redirect('dashboard');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -149,6 +149,7 @@ function generate_default_proxy_configuration(Server $server)
|
|||||||
'coolify.proxy=true',
|
'coolify.proxy=true',
|
||||||
];
|
];
|
||||||
$config = [
|
$config = [
|
||||||
|
'name' => 'coolify-proxy',
|
||||||
'networks' => $array_of_networks->toArray(),
|
'networks' => $array_of_networks->toArray(),
|
||||||
'services' => [
|
'services' => [
|
||||||
'traefik' => [
|
'traefik' => [
|
||||||
@@ -182,9 +183,9 @@ function generate_default_proxy_configuration(Server $server)
|
|||||||
'--entrypoints.http.address=:80',
|
'--entrypoints.http.address=:80',
|
||||||
'--entrypoints.https.address=:443',
|
'--entrypoints.https.address=:443',
|
||||||
'--entrypoints.http.http.encodequerysemicolons=true',
|
'--entrypoints.http.http.encodequerysemicolons=true',
|
||||||
'--entryPoints.http.http2.maxConcurrentStreams=50',
|
'--entryPoints.http.http2.maxConcurrentStreams=250',
|
||||||
'--entrypoints.https.http.encodequerysemicolons=true',
|
'--entrypoints.https.http.encodequerysemicolons=true',
|
||||||
'--entryPoints.https.http2.maxConcurrentStreams=50',
|
'--entryPoints.https.http2.maxConcurrentStreams=250',
|
||||||
'--entrypoints.https.http3',
|
'--entrypoints.https.http3',
|
||||||
'--providers.file.directory=/traefik/dynamic/',
|
'--providers.file.directory=/traefik/dynamic/',
|
||||||
'--providers.file.watch=true',
|
'--providers.file.watch=true',
|
||||||
|
BIN
public/coolify-logo-dev-transparent.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 641 KiB |
Before Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 7.7 KiB |
@@ -5,6 +5,20 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="robots" content="noindex">
|
<meta name="robots" content="noindex">
|
||||||
|
<meta name="theme-color" content="#ffffff" />
|
||||||
|
<meta name="Description" content="Coolify: An open-source & self-hostable Heroku / Netlify / Vercel alternative" />
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta name="twitter:site" content="@coolifyio" />
|
||||||
|
<meta name="twitter:title" content="Coolify" />
|
||||||
|
<meta name="twitter:description" content="An open-source & self-hostable Heroku / Netlify / Vercel alternative." />
|
||||||
|
<meta name="twitter:image" content="https://cdn.coollabs.io/assets/coolify/og-image.png" />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:url" content="https://coolify.io" />
|
||||||
|
<meta property="og:title" content="Coolify" />
|
||||||
|
<meta property="og:description" content="An open-source & self-hostable Heroku / Netlify / Vercel alternative." />
|
||||||
|
<meta property="og:site_name" content="Coolify" />
|
||||||
|
<meta property="og:image" content="https://cdn.coollabs.io/assets/coolify/og-image.png" />
|
||||||
@use('App\Models\InstanceSettings')
|
@use('App\Models\InstanceSettings')
|
||||||
@php
|
@php
|
||||||
|
|
||||||
@@ -21,7 +35,7 @@
|
|||||||
@endphp
|
@endphp
|
||||||
<title>{{ $name }}{{ $title ?? 'Coolify' }}</title>
|
<title>{{ $name }}{{ $title ?? 'Coolify' }}</title>
|
||||||
@env('local')
|
@env('local')
|
||||||
<link rel="icon" href="{{ asset('favicon-dev.png') }}" type="image/x-icon" />
|
<link rel="icon" href="{{ asset('coolify-logo-dev-transparent.png') }}" type="image/x-icon" />
|
||||||
@else
|
@else
|
||||||
<link rel="icon" href="{{ asset('coolify-transparent.png') }}" type="image/x-icon" />
|
<link rel="icon" href="{{ asset('coolify-transparent.png') }}" type="image/x-icon" />
|
||||||
@endenv
|
@endenv
|
||||||
|
@@ -291,16 +291,18 @@
|
|||||||
@if ($application->settings->is_raw_compose_deployment_enabled)
|
@if ($application->settings->is_raw_compose_deployment_enabled)
|
||||||
<x-forms.textarea rows="10" readonly id="application.docker_compose_raw"
|
<x-forms.textarea rows="10" readonly id="application.docker_compose_raw"
|
||||||
label="Docker Compose Content (applicationId: {{ $application->id }})"
|
label="Docker Compose Content (applicationId: {{ $application->id }})"
|
||||||
helper="You need to modify the docker compose file." monacoEditorLanguage="yaml"
|
helper="You need to modify the docker compose file in the git repository."
|
||||||
useMonacoEditor />
|
monacoEditorLanguage="yaml" useMonacoEditor />
|
||||||
@else
|
@else
|
||||||
@if ((int) $application->compose_parsing_version >= 3)
|
@if ((int) $application->compose_parsing_version >= 3)
|
||||||
<x-forms.textarea rows="10" readonly id="application.docker_compose_raw"
|
<x-forms.textarea rows="10" readonly id="application.docker_compose_raw"
|
||||||
label="Docker Compose Content (raw)" helper="You need to modify the docker compose file."
|
label="Docker Compose Content (raw)"
|
||||||
|
helper="You need to modify the docker compose file in the git repository."
|
||||||
monacoEditorLanguage="yaml" useMonacoEditor />
|
monacoEditorLanguage="yaml" useMonacoEditor />
|
||||||
@endif
|
@endif
|
||||||
<x-forms.textarea rows="10" readonly id="application.docker_compose"
|
<x-forms.textarea rows="10" readonly id="application.docker_compose"
|
||||||
label="Docker Compose Content" helper="You need to modify the docker compose file."
|
label="Docker Compose Content"
|
||||||
|
helper="You need to modify the docker compose file in the git repository."
|
||||||
monacoEditorLanguage="yaml" useMonacoEditor />
|
monacoEditorLanguage="yaml" useMonacoEditor />
|
||||||
@endif
|
@endif
|
||||||
<div class="w-96">
|
<div class="w-96">
|
||||||
|
@@ -103,7 +103,7 @@
|
|||||||
:src='service.logo'
|
:src='service.logo'
|
||||||
x-on:error.window="$event.target.src = service.logo_github_url"
|
x-on:error.window="$event.target.src = service.logo_github_url"
|
||||||
onerror="this.onerror=null; this.src=this.getAttribute('data-fallback');"
|
onerror="this.onerror=null; this.src=this.getAttribute('data-fallback');"
|
||||||
x-on:error="$event.target.src = '/svgs/coolify.png'"
|
x-on:error="$event.target.src = '/svgs/coolify-transparent.png'"
|
||||||
:data-fallback='service.logo_github_url' />
|
:data-fallback='service.logo_github_url' />
|
||||||
</template>
|
</template>
|
||||||
</x-slot:logo>
|
</x-slot:logo>
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
</x-modal-input>
|
</x-modal-input>
|
||||||
</div>
|
</div>
|
||||||
<x-forms.button
|
<x-forms.button
|
||||||
wire:click='switch'>{{ $view === 'normal' ? 'Developer view' : 'Normal view (required to set variables at build time)' }}</x-forms.button>
|
wire:click='switch'>{{ $view === 'normal' ? 'Developer view' : 'Normal view' }}</x-forms.button>
|
||||||
</div>
|
</div>
|
||||||
<div>Environment variables (secrets) for this resource. </div>
|
<div>Environment variables (secrets) for this resource. </div>
|
||||||
@if ($this->resourceClass === 'App\Models\Application' && data_get($this->resource, 'build_pack') !== 'dockercompose')
|
@if ($this->resourceClass === 'App\Models\Application' && data_get($this->resource, 'build_pack') !== 'dockercompose')
|
||||||
@@ -41,9 +41,9 @@
|
|||||||
$requiredEmptyVars = $resource->environment_variables->filter(function ($env) {
|
$requiredEmptyVars = $resource->environment_variables->filter(function ($env) {
|
||||||
return $env->is_required && empty($env->value);
|
return $env->is_required && empty($env->value);
|
||||||
});
|
});
|
||||||
|
|
||||||
$otherVars = $resource->environment_variables->diff($requiredEmptyVars);
|
$otherVars = $resource->environment_variables->diff($requiredEmptyVars);
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@forelse ($requiredEmptyVars->merge($otherVars) as $env)
|
@forelse ($requiredEmptyVars->merge($otherVars) as $env)
|
||||||
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
|
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
|
||||||
:env="$env" :type="$resource->type()" />
|
:env="$env" :type="$resource->type()" />
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# documentation: https://github.com/coollabsio/next-image-transformation
|
# documentation: https://github.com/coollabsio/next-image-transformation
|
||||||
# slogan: Drop-in replacement for Vercel's Nextjs image optimization service.
|
# slogan: Drop-in replacement for Vercel's Nextjs image optimization service.
|
||||||
# tags: nextjs,image,transformation,service
|
# tags: nextjs,image,transformation,service
|
||||||
# logo: svgs/coolify.png
|
# logo: svgs/coolify-transparent.png
|
||||||
# port: 3000
|
# port: 3000
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|