mirror of
https://github.com/ershisan99/coolify.git
synced 2026-01-07 12:34:18 +00:00
Compare commits
11 Commits
v4.0.0-bet
...
v4.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df021760a7 | ||
|
|
fb2598f2e4 | ||
|
|
7af07b2718 | ||
|
|
23a94c9378 | ||
|
|
ed34fc9645 | ||
|
|
cafd9e0ab2 | ||
|
|
e882477e21 | ||
|
|
db0e3cfcc4 | ||
|
|
b3c4429028 | ||
|
|
87ab4bd71e | ||
|
|
61e1fdede9 |
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Actions\Database;
|
namespace App\Actions\Database;
|
||||||
|
|
||||||
|
use App\Models\ServiceDatabase;
|
||||||
use App\Models\StandaloneMariadb;
|
use App\Models\StandaloneMariadb;
|
||||||
use App\Models\StandaloneMongodb;
|
use App\Models\StandaloneMongodb;
|
||||||
use App\Models\StandaloneMysql;
|
use App\Models\StandaloneMysql;
|
||||||
@@ -14,21 +15,53 @@ class StartDatabaseProxy
|
|||||||
{
|
{
|
||||||
use AsAction;
|
use AsAction;
|
||||||
|
|
||||||
public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb $database)
|
public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|ServiceDatabase $database)
|
||||||
{
|
{
|
||||||
$internalPort = null;
|
$internalPort = null;
|
||||||
if ($database->getMorphClass() === 'App\Models\StandaloneRedis') {
|
$type = $database->getMorphClass();
|
||||||
|
$network = data_get($database, 'destination.network');
|
||||||
|
$server = data_get($database, 'destination.server');
|
||||||
|
$containerName = data_get($database, 'uuid');
|
||||||
|
$proxyContainerName = "{$database->uuid}-proxy";
|
||||||
|
if ($database->getMorphClass() === 'App\Models\ServiceDatabase') {
|
||||||
|
$databaseType = $database->databaseType();
|
||||||
|
$network = data_get($database, 'service.destination.network');
|
||||||
|
$server = data_get($database, 'service.destination.server');
|
||||||
|
$proxyContainerName = "{$database->service->uuid}-proxy";
|
||||||
|
switch ($databaseType) {
|
||||||
|
case 'standalone-mariadb':
|
||||||
|
$type = 'App\Models\StandaloneMariadb';
|
||||||
|
$containerName = "mariadb-{$database->service->uuid}";
|
||||||
|
break;
|
||||||
|
case 'standalone-mongodb':
|
||||||
|
$type = 'App\Models\StandaloneMongodb';
|
||||||
|
$containerName = "mongodb-{$database->service->uuid}";
|
||||||
|
break;
|
||||||
|
case 'standalone-mysql':
|
||||||
|
$type = 'App\Models\StandaloneMysql';
|
||||||
|
$containerName = "mysql-{$database->service->uuid}";
|
||||||
|
break;
|
||||||
|
case 'standalone-postgresql':
|
||||||
|
$type = 'App\Models\StandalonePostgresql';
|
||||||
|
$containerName = "postgresql-{$database->service->uuid}";
|
||||||
|
break;
|
||||||
|
case 'standalone-redis':
|
||||||
|
$type = 'App\Models\StandaloneRedis';
|
||||||
|
$containerName = "redis-{$database->service->uuid}";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($type === 'App\Models\StandaloneRedis') {
|
||||||
$internalPort = 6379;
|
$internalPort = 6379;
|
||||||
} else if ($database->getMorphClass() === 'App\Models\StandalonePostgresql') {
|
} else if ($type === 'App\Models\StandalonePostgresql') {
|
||||||
$internalPort = 5432;
|
$internalPort = 5432;
|
||||||
} else if ($database->getMorphClass() === 'App\Models\StandaloneMongodb') {
|
} else if ($type === 'App\Models\StandaloneMongodb') {
|
||||||
$internalPort = 27017;
|
$internalPort = 27017;
|
||||||
} else if ($database->getMorphClass() === 'App\Models\StandaloneMysql') {
|
} else if ($type === 'App\Models\StandaloneMysql') {
|
||||||
$internalPort = 3306;
|
$internalPort = 3306;
|
||||||
} else if ($database->getMorphClass() === 'App\Models\StandaloneMariadb') {
|
} else if ($type === 'App\Models\StandaloneMariadb') {
|
||||||
$internalPort = 3306;
|
$internalPort = 3306;
|
||||||
}
|
}
|
||||||
$containerName = "{$database->uuid}-proxy";
|
|
||||||
$configuration_dir = database_proxy_dir($database->uuid);
|
$configuration_dir = database_proxy_dir($database->uuid);
|
||||||
$nginxconf = <<<EOF
|
$nginxconf = <<<EOF
|
||||||
user nginx;
|
user nginx;
|
||||||
@@ -42,7 +75,7 @@ class StartDatabaseProxy
|
|||||||
stream {
|
stream {
|
||||||
server {
|
server {
|
||||||
listen $database->public_port;
|
listen $database->public_port;
|
||||||
proxy_pass $database->uuid:$internalPort;
|
proxy_pass $containerName:$internalPort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF;
|
EOF;
|
||||||
@@ -54,19 +87,19 @@ class StartDatabaseProxy
|
|||||||
$docker_compose = [
|
$docker_compose = [
|
||||||
'version' => '3.8',
|
'version' => '3.8',
|
||||||
'services' => [
|
'services' => [
|
||||||
$containerName => [
|
$proxyContainerName => [
|
||||||
'build' => [
|
'build' => [
|
||||||
'context' => $configuration_dir,
|
'context' => $configuration_dir,
|
||||||
'dockerfile' => 'Dockerfile',
|
'dockerfile' => 'Dockerfile',
|
||||||
],
|
],
|
||||||
'image' => "nginx:stable-alpine",
|
'image' => "nginx:stable-alpine",
|
||||||
'container_name' => $containerName,
|
'container_name' => $proxyContainerName,
|
||||||
'restart' => RESTART_MODE,
|
'restart' => RESTART_MODE,
|
||||||
'ports' => [
|
'ports' => [
|
||||||
"$database->public_port:$database->public_port",
|
"$database->public_port:$database->public_port",
|
||||||
],
|
],
|
||||||
'networks' => [
|
'networks' => [
|
||||||
$database->destination->network,
|
$network,
|
||||||
],
|
],
|
||||||
'healthcheck' => [
|
'healthcheck' => [
|
||||||
'test' => [
|
'test' => [
|
||||||
@@ -81,9 +114,9 @@ class StartDatabaseProxy
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
'networks' => [
|
'networks' => [
|
||||||
$database->destination->network => [
|
$network => [
|
||||||
'external' => true,
|
'external' => true,
|
||||||
'name' => $database->destination->network,
|
'name' => $network,
|
||||||
'attachable' => true,
|
'attachable' => true,
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@@ -97,6 +130,6 @@ class StartDatabaseProxy
|
|||||||
"echo '{$nginxconf_base64}' | base64 -d > $configuration_dir/nginx.conf",
|
"echo '{$nginxconf_base64}' | base64 -d > $configuration_dir/nginx.conf",
|
||||||
"echo '{$dockercompose_base64}' | base64 -d > $configuration_dir/docker-compose.yaml",
|
"echo '{$dockercompose_base64}' | base64 -d > $configuration_dir/docker-compose.yaml",
|
||||||
"docker compose --project-directory {$configuration_dir} up --build -d",
|
"docker compose --project-directory {$configuration_dir} up --build -d",
|
||||||
], $database->destination->server);
|
], $server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class StartMariadb
|
|||||||
'memswap_limit' => $this->database->limits_memory_swap,
|
'memswap_limit' => $this->database->limits_memory_swap,
|
||||||
'mem_swappiness' => $this->database->limits_memory_swappiness,
|
'mem_swappiness' => $this->database->limits_memory_swappiness,
|
||||||
'mem_reservation' => $this->database->limits_memory_reservation,
|
'mem_reservation' => $this->database->limits_memory_reservation,
|
||||||
'cpus' => $this->database->limits_cpus,
|
'cpus' => (int) $this->database->limits_cpus,
|
||||||
'cpuset' => $this->database->limits_cpuset,
|
'cpuset' => $this->database->limits_cpuset,
|
||||||
'cpu_shares' => $this->database->limits_cpu_shares,
|
'cpu_shares' => $this->database->limits_cpu_shares,
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class StartMongodb
|
|||||||
'memswap_limit' => $this->database->limits_memory_swap,
|
'memswap_limit' => $this->database->limits_memory_swap,
|
||||||
'mem_swappiness' => $this->database->limits_memory_swappiness,
|
'mem_swappiness' => $this->database->limits_memory_swappiness,
|
||||||
'mem_reservation' => $this->database->limits_memory_reservation,
|
'mem_reservation' => $this->database->limits_memory_reservation,
|
||||||
'cpus' => $this->database->limits_cpus,
|
'cpus' => (int) $this->database->limits_cpus,
|
||||||
'cpuset' => $this->database->limits_cpuset,
|
'cpuset' => $this->database->limits_cpuset,
|
||||||
'cpu_shares' => $this->database->limits_cpu_shares,
|
'cpu_shares' => $this->database->limits_cpu_shares,
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class StartMysql
|
|||||||
'memswap_limit' => $this->database->limits_memory_swap,
|
'memswap_limit' => $this->database->limits_memory_swap,
|
||||||
'mem_swappiness' => $this->database->limits_memory_swappiness,
|
'mem_swappiness' => $this->database->limits_memory_swappiness,
|
||||||
'mem_reservation' => $this->database->limits_memory_reservation,
|
'mem_reservation' => $this->database->limits_memory_reservation,
|
||||||
'cpus' => $this->database->limits_cpus,
|
'cpus' => (int) $this->database->limits_cpus,
|
||||||
'cpuset' => $this->database->limits_cpuset,
|
'cpuset' => $this->database->limits_cpuset,
|
||||||
'cpu_shares' => $this->database->limits_cpu_shares,
|
'cpu_shares' => $this->database->limits_cpu_shares,
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class StartPostgresql
|
|||||||
'memswap_limit' => $this->database->limits_memory_swap,
|
'memswap_limit' => $this->database->limits_memory_swap,
|
||||||
'mem_swappiness' => $this->database->limits_memory_swappiness,
|
'mem_swappiness' => $this->database->limits_memory_swappiness,
|
||||||
'mem_reservation' => $this->database->limits_memory_reservation,
|
'mem_reservation' => $this->database->limits_memory_reservation,
|
||||||
'cpus' => $this->database->limits_cpus,
|
'cpus' => (int) $this->database->limits_cpus,
|
||||||
'cpuset' => $this->database->limits_cpuset,
|
'cpuset' => $this->database->limits_cpuset,
|
||||||
'cpu_shares' => $this->database->limits_cpu_shares,
|
'cpu_shares' => $this->database->limits_cpu_shares,
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class StartRedis
|
|||||||
'memswap_limit' => $this->database->limits_memory_swap,
|
'memswap_limit' => $this->database->limits_memory_swap,
|
||||||
'mem_swappiness' => $this->database->limits_memory_swappiness,
|
'mem_swappiness' => $this->database->limits_memory_swappiness,
|
||||||
'mem_reservation' => $this->database->limits_memory_reservation,
|
'mem_reservation' => $this->database->limits_memory_reservation,
|
||||||
'cpus' => $this->database->limits_cpus,
|
'cpus' => (int) $this->database->limits_cpus,
|
||||||
'cpuset' => $this->database->limits_cpuset,
|
'cpuset' => $this->database->limits_cpuset,
|
||||||
'cpu_shares' => $this->database->limits_cpu_shares,
|
'cpu_shares' => $this->database->limits_cpu_shares,
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Actions\Database;
|
namespace App\Actions\Database;
|
||||||
|
|
||||||
|
use App\Models\ServiceDatabase;
|
||||||
use App\Models\StandaloneMariadb;
|
use App\Models\StandaloneMariadb;
|
||||||
use App\Models\StandaloneMongodb;
|
use App\Models\StandaloneMongodb;
|
||||||
use App\Models\StandaloneMysql;
|
use App\Models\StandaloneMysql;
|
||||||
@@ -13,9 +14,13 @@ class StopDatabaseProxy
|
|||||||
{
|
{
|
||||||
use AsAction;
|
use AsAction;
|
||||||
|
|
||||||
public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb $database)
|
public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|ServiceDatabase $database)
|
||||||
{
|
{
|
||||||
instant_remote_process(["docker rm -f {$database->uuid}-proxy"], $database->destination->server);
|
$server = data_get($database, 'destination.server');
|
||||||
|
if ($database->getMorphClass() === 'App\Models\ServiceDatabase') {
|
||||||
|
$server = data_get($database, 'service.server');
|
||||||
|
}
|
||||||
|
instant_remote_process(["docker rm -f {$database->uuid}-proxy"], $server);
|
||||||
$database->is_public = false;
|
$database->is_public = false;
|
||||||
$database->save();
|
$database->save();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,28 +2,56 @@
|
|||||||
|
|
||||||
namespace App\Http\Livewire\Project\Service;
|
namespace App\Http\Livewire\Project\Service;
|
||||||
|
|
||||||
|
use App\Actions\Database\StartDatabaseProxy;
|
||||||
|
use App\Actions\Database\StopDatabaseProxy;
|
||||||
use App\Models\ServiceDatabase;
|
use App\Models\ServiceDatabase;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Database extends Component
|
class Database extends Component
|
||||||
{
|
{
|
||||||
public ServiceDatabase $database;
|
public ServiceDatabase $database;
|
||||||
|
public ?string $db_url_public = null;
|
||||||
public $fileStorages;
|
public $fileStorages;
|
||||||
|
|
||||||
protected $listeners = ["refreshFileStorages"];
|
protected $listeners = ["refreshFileStorages"];
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'database.human_name' => 'nullable',
|
'database.human_name' => 'nullable',
|
||||||
'database.description' => 'nullable',
|
'database.description' => 'nullable',
|
||||||
'database.image' => 'required',
|
'database.image' => 'required',
|
||||||
'database.exclude_from_status' => 'required|boolean',
|
'database.exclude_from_status' => 'required|boolean',
|
||||||
|
'database.public_port' => 'nullable|integer',
|
||||||
|
'database.is_public' => 'required|boolean',
|
||||||
];
|
];
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.project.service.database');
|
return view('livewire.project.service.database');
|
||||||
}
|
}
|
||||||
public function mount() {
|
public function mount() {
|
||||||
|
if ($this->database->is_public) {
|
||||||
|
$this->db_url_public = $this->database->getServiceDatabaseUrl();
|
||||||
|
}
|
||||||
$this->refreshFileStorages();
|
$this->refreshFileStorages();
|
||||||
}
|
}
|
||||||
public function instantSave() {
|
public function instantSave() {
|
||||||
|
if ($this->database->is_public && !$this->database->public_port) {
|
||||||
|
$this->emit('error', 'Public port is required.');
|
||||||
|
$this->database->is_public = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($this->database->is_public) {
|
||||||
|
if (!str($this->database->status)->startsWith('running')) {
|
||||||
|
$this->emit('error', 'Database must be started to be publicly accessible.');
|
||||||
|
$this->database->is_public = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StartDatabaseProxy::run($this->database);
|
||||||
|
$this->db_url_public = $this->database->getServiceDatabaseUrl();
|
||||||
|
$this->emit('success', 'Database is now publicly accessible.');
|
||||||
|
} else {
|
||||||
|
StopDatabaseProxy::run($this->database);
|
||||||
|
$this->db_url_public = null;
|
||||||
|
$this->emit('success', 'Database is no longer publicly accessible.');
|
||||||
|
}
|
||||||
$this->submit();
|
$this->submit();
|
||||||
}
|
}
|
||||||
public function refreshFileStorages()
|
public function refreshFileStorages()
|
||||||
|
|||||||
@@ -192,6 +192,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
$this->deploy_dockerimage_buildpack();
|
$this->deploy_dockerimage_buildpack();
|
||||||
} else if ($this->application->build_pack === 'dockerfile') {
|
} else if ($this->application->build_pack === 'dockerfile') {
|
||||||
$this->deploy_dockerfile_buildpack();
|
$this->deploy_dockerfile_buildpack();
|
||||||
|
} else if ($this->application->build_pack === 'static') {
|
||||||
|
$this->deploy_static_buildpack();
|
||||||
} else {
|
} else {
|
||||||
if ($this->pull_request_id !== 0) {
|
if ($this->pull_request_id !== 0) {
|
||||||
$this->deploy_pull_request();
|
$this->deploy_pull_request();
|
||||||
@@ -227,6 +229,14 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
[
|
[
|
||||||
"docker rm -f {$this->deployment_uuid} >/dev/null 2>&1",
|
"docker rm -f {$this->deployment_uuid} >/dev/null 2>&1",
|
||||||
"hidden" => true,
|
"hidden" => true,
|
||||||
|
"ignore_errors" => true,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$this->execute_remote_command(
|
||||||
|
[
|
||||||
|
"docker image prune -f >/dev/null 2>&1",
|
||||||
|
"hidden" => true,
|
||||||
|
"ignore_errors" => true,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -421,6 +431,23 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
$this->build_image();
|
$this->build_image();
|
||||||
$this->rolling_update();
|
$this->rolling_update();
|
||||||
}
|
}
|
||||||
|
private function deploy_static_buildpack()
|
||||||
|
{
|
||||||
|
$this->execute_remote_command(
|
||||||
|
[
|
||||||
|
"echo 'Starting deployment of {$this->customRepository}:{$this->application->git_branch}.'"
|
||||||
|
],
|
||||||
|
);
|
||||||
|
$this->prepare_builder_image();
|
||||||
|
$this->check_git_if_build_needed();
|
||||||
|
$this->set_base_dir();
|
||||||
|
$this->generate_image_names();
|
||||||
|
$this->clone_repository();
|
||||||
|
$this->cleanup_git();
|
||||||
|
$this->build_image();
|
||||||
|
$this->generate_compose_file();
|
||||||
|
$this->rolling_update();
|
||||||
|
}
|
||||||
|
|
||||||
private function rolling_update()
|
private function rolling_update()
|
||||||
{
|
{
|
||||||
@@ -787,7 +814,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
'memswap_limit' => $this->application->limits_memory_swap,
|
'memswap_limit' => $this->application->limits_memory_swap,
|
||||||
'mem_swappiness' => $this->application->limits_memory_swappiness,
|
'mem_swappiness' => $this->application->limits_memory_swappiness,
|
||||||
'mem_reservation' => $this->application->limits_memory_reservation,
|
'mem_reservation' => $this->application->limits_memory_reservation,
|
||||||
'cpus' => $this->application->limits_cpus,
|
'cpus' => (int) $this->application->limits_cpus,
|
||||||
'cpuset' => $this->application->limits_cpuset,
|
'cpuset' => $this->application->limits_cpuset,
|
||||||
'cpu_shares' => $this->application->limits_cpu_shares,
|
'cpu_shares' => $this->application->limits_cpu_shares,
|
||||||
]
|
]
|
||||||
@@ -910,22 +937,26 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
|
|
||||||
private function build_image()
|
private function build_image()
|
||||||
{
|
{
|
||||||
$this->execute_remote_command([
|
if ($this->application->build_pack === 'static') {
|
||||||
"echo -n 'Building docker image for your application. To check the current progress, click on Show Debug Logs.'",
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($this->application->settings->is_static) {
|
|
||||||
$this->execute_remote_command([
|
$this->execute_remote_command([
|
||||||
executeInDocker($this->deployment_uuid, "docker build $this->buildTarget $this->addHosts --network host -f {$this->workdir}/{$this->dockerfile_location} {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true
|
"echo -n 'Static deployment. Copying static assets to the image.'",
|
||||||
]);
|
]);
|
||||||
|
} else {
|
||||||
|
$this->execute_remote_command([
|
||||||
|
"echo -n 'Building docker image for your application. To check the current progress, click on Show Debug Logs.'",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
$dockerfile = base64_encode("FROM {$this->application->static_image}
|
if ($this->application->settings->is_static || $this->application->build_pack === 'static') {
|
||||||
|
if ($this->application->build_pack === 'static') {
|
||||||
|
$dockerfile = base64_encode("FROM {$this->application->static_image}
|
||||||
WORKDIR /usr/share/nginx/html/
|
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 . .
|
||||||
|
RUN rm -f /usr/share/nginx/html/nginx.conf
|
||||||
|
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 {
|
||||||
$nginx_config = base64_encode("server {
|
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
@@ -941,15 +972,43 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
|||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
}
|
}
|
||||||
}");
|
}");
|
||||||
|
} else {
|
||||||
|
$this->execute_remote_command([
|
||||||
|
executeInDocker($this->deployment_uuid, "docker build $this->buildTarget $this->addHosts --network host -f {$this->workdir}/{$this->dockerfile_location} {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
$dockerfile = base64_encode("FROM {$this->application->static_image}
|
||||||
|
WORKDIR /usr/share/nginx/html/
|
||||||
|
LABEL coolify.deploymentId={$this->deployment_uuid}
|
||||||
|
COPY --from=$this->build_image_name /app/{$this->application->publish_directory} .
|
||||||
|
COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
||||||
|
|
||||||
|
$nginx_config = base64_encode("server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}");
|
||||||
|
}
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[
|
[
|
||||||
executeInDocker($this->deployment_uuid, "echo '{$dockerfile}' | base64 -d > {$this->workdir}/Dockerfile-prod")
|
executeInDocker($this->deployment_uuid, "echo '{$dockerfile}' | base64 -d > {$this->workdir}/Dockerfile")
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
executeInDocker($this->deployment_uuid, "echo '{$nginx_config}' | base64 -d > {$this->workdir}/nginx.conf")
|
executeInDocker($this->deployment_uuid, "echo '{$nginx_config}' | base64 -d > {$this->workdir}/nginx.conf")
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
executeInDocker($this->deployment_uuid, "docker build $this->addHosts --network host -f {$this->workdir}/Dockerfile-prod {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true
|
executeInDocker($this->deployment_uuid, "docker build $this->addHosts --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Jobs;
|
namespace App\Jobs;
|
||||||
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use Exception;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
|
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
@@ -10,12 +11,13 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
|||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class DockerCleanupJob implements ShouldQueue, ShouldBeEncrypted
|
class DockerCleanupJob implements ShouldQueue, ShouldBeEncrypted
|
||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
public $timeout = 1000;
|
public $timeout = 300;
|
||||||
public ?string $dockerRootFilesystem = null;
|
public ?string $dockerRootFilesystem = null;
|
||||||
public ?int $usageBefore = null;
|
public ?int $usageBefore = null;
|
||||||
|
|
||||||
@@ -33,14 +35,15 @@ class DockerCleanupJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
}
|
}
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
$queuedCount = 0;
|
$isInprogress = false;
|
||||||
$this->server->applications()->each(function ($application) use ($queuedCount) {
|
$this->server->applications()->each(function ($application) use (&$isInprogress) {
|
||||||
$count = data_get($application->deployments(), 'count', 0);
|
if ($application->isDeploymentInprogress()) {
|
||||||
$queuedCount += $count;
|
$isInprogress = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if ($queuedCount > 0) {
|
if ($isInprogress) {
|
||||||
ray('DockerCleanupJob: ApplicationDeploymentQueue is not empty, skipping')->color('orange');
|
throw new Exception('DockerCleanupJob: ApplicationDeploymentQueue is not empty, skipping...');
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (!$this->server->isFunctional()) {
|
if (!$this->server->isFunctional()) {
|
||||||
@@ -49,23 +52,25 @@ class DockerCleanupJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
$this->dockerRootFilesystem = "/";
|
$this->dockerRootFilesystem = "/";
|
||||||
$this->usageBefore = $this->getFilesystemUsage();
|
$this->usageBefore = $this->getFilesystemUsage();
|
||||||
if ($this->usageBefore >= $this->server->settings->cleanup_after_percentage) {
|
if ($this->usageBefore >= $this->server->settings->cleanup_after_percentage) {
|
||||||
ray('Cleaning up ' . $this->server->name)->color('orange');
|
ray('Cleaning up ' . $this->server->name);
|
||||||
instant_remote_process(['docker image prune -af'], $this->server);
|
instant_remote_process(['docker image prune -af'], $this->server);
|
||||||
instant_remote_process(['docker container prune -f --filter "label=coolify.managed=true"'], $this->server);
|
instant_remote_process(['docker container prune -f --filter "label=coolify.managed=true"'], $this->server);
|
||||||
instant_remote_process(['docker builder prune -af'], $this->server);
|
instant_remote_process(['docker builder prune -af'], $this->server);
|
||||||
$usageAfter = $this->getFilesystemUsage();
|
$usageAfter = $this->getFilesystemUsage();
|
||||||
if ($usageAfter < $this->usageBefore) {
|
if ($usageAfter < $this->usageBefore) {
|
||||||
ray('Saved ' . ($this->usageBefore - $usageAfter) . '% disk space on ' . $this->server->name)->color('orange');
|
ray('Saved ' . ($this->usageBefore - $usageAfter) . '% disk space on ' . $this->server->name);
|
||||||
send_internal_notification('DockerCleanupJob done: Saved ' . ($this->usageBefore - $usageAfter) . '% disk space on ' . $this->server->name);
|
send_internal_notification('DockerCleanupJob done: Saved ' . ($this->usageBefore - $usageAfter) . '% disk space on ' . $this->server->name);
|
||||||
|
Log::info('DockerCleanupJob done: Saved ' . ($this->usageBefore - $usageAfter) . '% disk space on ' . $this->server->name);
|
||||||
} else {
|
} else {
|
||||||
ray('DockerCleanupJob failed to save disk space on ' . $this->server->name)->color('orange');
|
Log::info('DockerCleanupJob failed to save disk space on ' . $this->server->name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ray('No need to clean up ' . $this->server->name)->color('orange');
|
ray('No need to clean up ' . $this->server->name);
|
||||||
|
Log::info('No need to clean up ' . $this->server->name);
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
send_internal_notification('DockerCleanupJob failed with: ' . $e->getMessage());
|
send_internal_notification('DockerCleanupJob failed with: ' . $e->getMessage());
|
||||||
ray($e->getMessage())->color('orange');
|
ray($e->getMessage());
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,6 +213,14 @@ class Application extends BaseModel
|
|||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isDeploymentInprogress() {
|
||||||
|
$deployments = ApplicationDeploymentQueue::where('application_id', $this->id)->where('status', 'in_progress')->count();
|
||||||
|
if ($deployments > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function deployments(int $skip = 0, int $take = 10)
|
public function deployments(int $skip = 0, int $take = 10)
|
||||||
{
|
{
|
||||||
$deployments = ApplicationDeploymentQueue::where('application_id', $this->id)->orderBy('created_at', 'desc');
|
$deployments = ApplicationDeploymentQueue::where('application_id', $this->id)->orderBy('created_at', 'desc');
|
||||||
|
|||||||
@@ -28,6 +28,16 @@ class ServiceDatabase extends BaseModel
|
|||||||
}
|
}
|
||||||
return "standalone-$image";
|
return "standalone-$image";
|
||||||
}
|
}
|
||||||
|
public function getServiceDatabaseUrl() {
|
||||||
|
// $type = $this->databaseType();
|
||||||
|
$port = $this->public_port;
|
||||||
|
$realIp = $this->service->server->ip;
|
||||||
|
if ($realIp === 'host.docker.internal' || isDev()) {
|
||||||
|
$realIp = base_ip();
|
||||||
|
}
|
||||||
|
$url = "{$realIp}:{$port}";
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
public function service()
|
public function service()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Service::class);
|
return $this->belongsTo(Service::class);
|
||||||
|
|||||||
@@ -58,8 +58,9 @@ class StandaloneRedis extends BaseModel
|
|||||||
{
|
{
|
||||||
return 'standalone-redis';
|
return 'standalone-redis';
|
||||||
}
|
}
|
||||||
public function getDbUrl(): string {
|
public function getDbUrl(bool $useInternal = false): string
|
||||||
if ($this->is_public) {
|
{
|
||||||
|
if ($this->is_public && !$useInternal) {
|
||||||
return "redis://:{$this->redis_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
|
return "redis://:{$this->redis_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
|
||||||
} else {
|
} else {
|
||||||
return "redis://:{$this->redis_password}@{$this->uuid}:6379/0";
|
return "redis://:{$this->redis_password}@{$this->uuid}:6379/0";
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Input extends Component
|
|||||||
public bool $readonly = false,
|
public bool $readonly = false,
|
||||||
public string|null $helper = null,
|
public string|null $helper = null,
|
||||||
public bool $allowToPeak = true,
|
public bool $allowToPeak = true,
|
||||||
public string $defaultClass = "input input-sm bg-coolgray-200 rounded text-white w-full disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500 read-only:text-neutral-500 read-only:bg-coolgray-200/50"
|
public string $defaultClass = "input input-sm bg-coolgray-100 rounded text-white w-full disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500 read-only:text-neutral-500 read-only:bg-coolgray-200/50"
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Select extends Component
|
|||||||
public string|null $label = null,
|
public string|null $label = null,
|
||||||
public string|null $helper = null,
|
public string|null $helper = null,
|
||||||
public bool $required = false,
|
public bool $required = false,
|
||||||
public string $defaultClass = "select select-sm w-full rounded text-white text-sm bg-coolgray-200 font-normal disabled:bg-coolgray-200/50 disabled:border-none"
|
public string $defaultClass = "select select-sm w-full rounded text-white text-sm bg-coolgray-100 font-normal disabled:bg-coolgray-200/50 disabled:border-none"
|
||||||
) {
|
) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class Textarea extends Component
|
|||||||
public bool $readonly = false,
|
public bool $readonly = false,
|
||||||
public string|null $helper = null,
|
public string|null $helper = null,
|
||||||
public bool $realtimeValidation = false,
|
public bool $realtimeValidation = false,
|
||||||
public string $defaultClass = "textarea leading-normal bg-coolgray-200 rounded text-white scrollbar disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500 read-only:text-neutral-500 read-only:bg-coolgray-200/50"
|
public string $defaultClass = "textarea leading-normal bg-coolgray-100 rounded text-white scrollbar disabled:bg-coolgray-200/50 disabled:border-none placeholder:text-coolgray-500 read-only:text-neutral-500 read-only:bg-coolgray-200/50"
|
||||||
) {
|
) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.118',
|
'release' => '4.0.0-beta.120',
|
||||||
// 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'),
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return '4.0.0-beta.118';
|
return '4.0.0-beta.120';
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?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('service_databases', function (Blueprint $table) {
|
||||||
|
$table->integer('public_port')->nullable();
|
||||||
|
$table->boolean('is_public')->default(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('service_databases', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('public_port');
|
||||||
|
$table->dropColumn('is_public');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -53,7 +53,7 @@ a {
|
|||||||
@apply text-white;
|
@apply text-white;
|
||||||
}
|
}
|
||||||
.box {
|
.box {
|
||||||
@apply flex p-2 transition-colors cursor-pointer min-h-16 bg-coolgray-200 hover:bg-coollabs-100 hover:text-white hover:no-underline min-w-[24rem];
|
@apply flex p-2 transition-colors cursor-pointer min-h-16 bg-coolgray-100 hover:bg-coollabs-100 hover:text-white hover:no-underline min-w-[24rem];
|
||||||
}
|
}
|
||||||
.box-without-bg {
|
.box-without-bg {
|
||||||
@apply flex p-2 transition-colors min-h-16 hover:text-white hover:no-underline min-w-[24rem];
|
@apply flex p-2 transition-colors min-h-16 hover:text-white hover:no-underline min-w-[24rem];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<Transition name="fade">
|
<Transition name="fade">
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center p-1 px-2 overflow-hidden transition-all transform rounded cursor-pointer bg-coolgray-200"
|
<div class="flex items-center p-1 px-2 overflow-hidden transition-all transform rounded cursor-pointer bg-coolgray-100"
|
||||||
@click="showCommandPalette = true">
|
@click="showCommandPalette = true">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 icon" viewBox="0 0 24 24" stroke-width="2"
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 icon" viewBox="0 0 24 24" stroke-width="2"
|
||||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
@auth
|
@auth
|
||||||
<nav class="fixed h-full overflow-hidden overflow-y-auto pt-14 scrollbar">
|
<nav class="fixed h-full overflow-hidden overflow-y-auto pt-14 scrollbar">
|
||||||
<a href="/" class="fixed top-0 z-50 mx-3 mt-3 cursor-pointer bg-coolgray-100"><img class="transition rounded w-11 h-11" src="{{ asset('coolify-transparent.png') }}"></a>
|
<a href="/" class="fixed top-0 z-50 mx-3 mt-3 bg-transparent cursor-pointer"><img
|
||||||
|
class="transition rounded w-11 h-11" src="{{ asset('coolify-transparent.png') }}"></a>
|
||||||
<ul class="flex flex-col h-full gap-4 menu flex-nowrap">
|
<ul class="flex flex-col h-full gap-4 menu flex-nowrap">
|
||||||
<li title="Dashboard">
|
<li title="Dashboard">
|
||||||
<a class="hover:bg-transparent" @if (!request()->is('/')) href="/" @endif>
|
<a class="hover:bg-transparent" @if (!request()->is('/')) href="/" @endif>
|
||||||
@@ -11,6 +12,18 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li title="Help us!">
|
||||||
|
<a class="hover:bg-transparent"href="https://coolify.io/sponsorships" target="_blank">
|
||||||
|
<svg class="icon hover:text-pink-500" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
stroke-width="2">
|
||||||
|
<path d="M19.5 12.572L12 20l-7.5-7.428A5 5 0 1 1 12 6.006a5 5 0 1 1 7.5 6.572" />
|
||||||
|
<path
|
||||||
|
d="M12 6L8.707 9.293a1 1 0 0 0 0 1.414l.543.543c.69.69 1.81.69 2.5 0l1-1a3.182 3.182 0 0 1 4.5 0l2.25 2.25m-7 3l2 2M15 13l2 2" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li title="Send us feedback or get help!" class="fixed top-0 right-0 p-2 px-4 pt-4 mt-auto text-xs">
|
<li title="Send us feedback or get help!" class="fixed top-0 right-0 p-2 px-4 pt-4 mt-auto text-xs">
|
||||||
<div class="justify-center" wire:click="help" onclick="help.showModal()">
|
<div class="justify-center" wire:click="help" onclick="help.showModal()">
|
||||||
<svg class="w-5 h-5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-5 h-5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
@auth
|
@auth
|
||||||
<nav class="fixed h-full overflow-hidden overflow-y-auto pt-28 scrollbar">
|
<nav class="fixed h-full overflow-hidden overflow-y-auto pt-28 scrollbar">
|
||||||
<a href="/" class="fixed top-0 z-50 mx-3 mt-3 cursor-pointer bg-coolgray-100"><img class="transition rounded w-11 h-11" src="{{ asset('coolify-transparent.png') }}"></a>
|
<a href="/" class="fixed top-0 z-50 mx-3 mt-3 bg-transparent cursor-pointer"><img
|
||||||
|
class="transition rounded w-11 h-11" src="{{ asset('coolify-transparent.png') }}"></a>
|
||||||
<ul class="flex flex-col h-full gap-4 menu flex-nowrap">
|
<ul class="flex flex-col h-full gap-4 menu flex-nowrap">
|
||||||
<li title="Dashboard">
|
<li title="Dashboard">
|
||||||
<a class="hover:bg-transparent" @if (!request()->is('/')) href="/" @endif>
|
<a class="hover:bg-transparent" @if (!request()->is('/')) href="/" @endif>
|
||||||
@@ -87,6 +88,18 @@
|
|||||||
@if (isInstanceAdmin() && !isCloud())
|
@if (isInstanceAdmin() && !isCloud())
|
||||||
<livewire:upgrade />
|
<livewire:upgrade />
|
||||||
@endif
|
@endif
|
||||||
|
<li title="Help us!">
|
||||||
|
<a class="hover:bg-transparent"href="https://coolify.io/sponsorships" target="_blank">
|
||||||
|
<svg class="icon hover:text-pink-500" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
stroke-width="2">
|
||||||
|
<path d="M19.5 12.572L12 20l-7.5-7.428A5 5 0 1 1 12 6.006a5 5 0 1 1 7.5 6.572" />
|
||||||
|
<path
|
||||||
|
d="M12 6L8.707 9.293a1 1 0 0 0 0 1.414l.543.543c.69.69 1.81.69 2.5 0l1-1a3.182 3.182 0 0 1 4.5 0l2.25 2.25m-7 3l2 2M15 13l2 2" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li title="Profile">
|
<li title="Profile">
|
||||||
<a class="hover:bg-transparent" @if (!request()->is('profile')) href="/profile" @endif>
|
<a class="hover:bg-transparent" @if (!request()->is('profile')) href="/profile" @endif>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" stroke-width="1.5"
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24" stroke-width="1.5"
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
@endif
|
@endif
|
||||||
</head>
|
</head>
|
||||||
@section('body')
|
@section('body')
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@livewireScripts
|
@livewireScripts
|
||||||
<dialog id="help" class="modal">
|
<dialog id="help" class="modal">
|
||||||
|
|||||||
@@ -27,10 +27,11 @@
|
|||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<x-forms.select wire:model="application.build_pack" label="Build Pack" required>
|
<x-forms.select wire:model="application.build_pack" label="Build Pack" required>
|
||||||
<option value="nixpacks">Nixpacks</option>
|
<option value="nixpacks">Nixpacks</option>
|
||||||
|
<option value="static">Static</option>
|
||||||
<option value="dockerfile">Dockerfile</option>
|
<option value="dockerfile">Dockerfile</option>
|
||||||
<option value="dockerimage">Docker Image</option>
|
<option value="dockerimage">Docker Image</option>
|
||||||
</x-forms.select>
|
</x-forms.select>
|
||||||
@if ($application->settings->is_static)
|
@if ($application->settings->is_static || $application->build_pack === 'static')
|
||||||
<x-forms.select id="application.static_image" label="Static Image" required>
|
<x-forms.select id="application.static_image" label="Static Image" required>
|
||||||
<option value="nginx:alpine">nginx:alpine</option>
|
<option value="nginx:alpine">nginx:alpine</option>
|
||||||
<option disabled value="apache:alpine">apache:alpine</option>
|
<option disabled value="apache:alpine">apache:alpine</option>
|
||||||
@@ -97,7 +98,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<h3>Network</h3>
|
<h3>Network</h3>
|
||||||
<div class="flex flex-col gap-2 xl:flex-row">
|
<div class="flex flex-col gap-2 xl:flex-row">
|
||||||
@if ($application->settings->is_static)
|
@if ($application->settings->is_static || $application->build_pack === 'static')
|
||||||
<x-forms.input id="application.ports_exposes" label="Ports Exposes" readonly />
|
<x-forms.input id="application.ports_exposes" label="Ports Exposes" readonly />
|
||||||
@else
|
@else
|
||||||
<x-forms.input placeholder="3000,3001" id="application.ports_exposes" label="Ports Exposes" required
|
<x-forms.input placeholder="3000,3001" id="application.ports_exposes" label="Ports Exposes" required
|
||||||
|
|||||||
@@ -12,10 +12,19 @@
|
|||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<x-forms.input label="Name" id="database.human_name" placeholder="Name"></x-forms.input>
|
<x-forms.input label="Name" id="database.human_name" placeholder="Name"></x-forms.input>
|
||||||
<x-forms.input label="Description" id="database.description"></x-forms.input>
|
<x-forms.input label="Description" id="database.description"></x-forms.input>
|
||||||
|
<x-forms.input required
|
||||||
|
helper="You can change the image you would like to deploy.<br><br><span class='text-warning'>WARNING. You could corrupt your data. Only do it if you know what you are doing.</span>"
|
||||||
|
label="Image Tag" id="database.image"></x-forms.input>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex items-end gap-2">
|
||||||
<x-forms.input required helper="You can change the image you would like to deploy.<br><br><span class='text-warning'>WARNING. You could corrupt your data. Only do it if you know what you are doing.</span>" label="Image Tag"
|
@if ($db_url_public)
|
||||||
id="database.image"></x-forms.input>
|
<x-forms.input label="Database URL (public)"
|
||||||
|
helper="Your credentials are available in your environment variables." type="password" readonly
|
||||||
|
wire:model="db_url_public" />
|
||||||
|
@endif
|
||||||
|
<x-forms.input placeholder="5432" disabled="{{ $database->is_public }}" id="database.public_port"
|
||||||
|
label="Public Port" />
|
||||||
|
<x-forms.checkbox instantSave id="database.is_public" label="Accessible over the internet" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="pt-2">Advanced</h3>
|
<h3 class="pt-2">Advanced</h3>
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
@if (
|
@if (
|
||||||
$resource->getMorphClass() == 'App\Models\Application' ||
|
$resource->getMorphClass() == 'App\Models\Application' ||
|
||||||
$resource->getMorphClass() == 'App\Models\StandalonePostgresql' ||
|
$resource->getMorphClass() == 'App\Models\StandalonePostgresql' ||
|
||||||
$resource->getMorphClass() == 'App\Models\StandaloneRedis')
|
$resource->getMorphClass() == 'App\Models\StandaloneRedis' ||
|
||||||
|
$resource->getMorphClass() == 'App\Models\StandaloneMariadb' ||
|
||||||
|
$resource->getMorphClass() == 'App\Models\StandaloneMongodb')
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<h2>Storages</h2>
|
<h2>Storages</h2>
|
||||||
<x-helper
|
<x-helper
|
||||||
|
|||||||
@@ -39,12 +39,12 @@ module.exports = {
|
|||||||
themes: [
|
themes: [
|
||||||
{
|
{
|
||||||
coollabs: {
|
coollabs: {
|
||||||
primary: "#323232",
|
primary: "#202020",
|
||||||
"primary-focus": "#242424",
|
"primary-focus": "#242424",
|
||||||
secondary: "#6B16ED",
|
secondary: "#6B16ED",
|
||||||
accent: "#4338ca",
|
accent: "#4338ca",
|
||||||
neutral: "#1B1D1D",
|
neutral: "#1B1D1D",
|
||||||
"base-100": "#181818",
|
"base-100": "#101010",
|
||||||
info: "#2563EB",
|
info: "#2563EB",
|
||||||
success: "#16A34A",
|
success: "#16A34A",
|
||||||
warning: "#FCD34D",
|
warning: "#FCD34D",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"version": "3.12.36"
|
"version": "3.12.36"
|
||||||
},
|
},
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.118"
|
"version": "4.0.0-beta.120"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user