commit
8b0a0d67da
@ -36,7 +36,7 @@ # Installation
|
|||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
Contact us [here](https://coolify.io/contact).
|
Contact us [here](https://coolify.io/docs/contact).
|
||||||
|
|
||||||
## Recognitions
|
## Recognitions
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@ protected function schedule(Schedule $schedule): void
|
|||||||
$schedule->command('horizon:snapshot')->everyFiveMinutes();
|
$schedule->command('horizon:snapshot')->everyFiveMinutes();
|
||||||
$schedule->job(new CleanupInstanceStuffsJob)->everyTwoMinutes()->onOneServer();
|
$schedule->job(new CleanupInstanceStuffsJob)->everyTwoMinutes()->onOneServer();
|
||||||
$schedule->job(new CheckResaleLicenseJob)->hourly()->onOneServer();
|
$schedule->job(new CheckResaleLicenseJob)->hourly()->onOneServer();
|
||||||
// $schedule->job(new DockerCleanupJob)->everyTenMinutes()->onOneServer();
|
|
||||||
$this->instance_auto_update($schedule);
|
$this->instance_auto_update($schedule);
|
||||||
$this->check_scheduled_backups($schedule);
|
$this->check_scheduled_backups($schedule);
|
||||||
$this->check_resources($schedule);
|
$this->check_resources($schedule);
|
||||||
|
@ -46,15 +46,6 @@ public function link()
|
|||||||
}
|
}
|
||||||
return redirect()->route('login')->with('error', 'Invalid credentials.');
|
return redirect()->route('login')->with('error', 'Invalid credentials.');
|
||||||
}
|
}
|
||||||
public function subscription()
|
|
||||||
{
|
|
||||||
if (!isCloud()) {
|
|
||||||
abort(404);
|
|
||||||
}
|
|
||||||
return view('subscription.index', [
|
|
||||||
'settings' => InstanceSettings::get(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function license()
|
public function license()
|
||||||
{
|
{
|
||||||
|
@ -164,7 +164,7 @@ public function saveServer()
|
|||||||
{
|
{
|
||||||
$this->validate([
|
$this->validate([
|
||||||
'remoteServerName' => 'required',
|
'remoteServerName' => 'required',
|
||||||
'remoteServerHost' => 'required',
|
'remoteServerHost' => 'required|ip',
|
||||||
'remoteServerPort' => 'required|integer',
|
'remoteServerPort' => 'required|integer',
|
||||||
'remoteServerUser' => 'required',
|
'remoteServerUser' => 'required',
|
||||||
]);
|
]);
|
||||||
|
@ -11,19 +11,11 @@ class Dashboard extends Component
|
|||||||
{
|
{
|
||||||
public $projects = [];
|
public $projects = [];
|
||||||
public $servers = [];
|
public $servers = [];
|
||||||
public int $s3s = 0;
|
|
||||||
public int $resources = 0;
|
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->servers = Server::ownedByCurrentTeam()->get();
|
$this->servers = Server::ownedByCurrentTeam()->get();
|
||||||
$this->s3s = S3Storage::ownedByCurrentTeam()->get()->count();
|
$this->projects = Project::ownedByCurrentTeam()->get();
|
||||||
$projects = Project::ownedByCurrentTeam()->get();
|
|
||||||
foreach ($projects as $project) {
|
|
||||||
$this->resources += $project->applications->count();
|
|
||||||
$this->resources += $project->postgresqls->count();
|
|
||||||
}
|
|
||||||
$this->projects = $projects;
|
|
||||||
}
|
}
|
||||||
// public function getIptables()
|
// public function getIptables()
|
||||||
// {
|
// {
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Http\Livewire\Project\New;
|
namespace App\Http\Livewire\Project\New;
|
||||||
|
|
||||||
|
use App\Models\Project;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use Countable;
|
use Countable;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\File;
|
|
||||||
use Illuminate\Support\Facades\Http;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Select extends Component
|
class Select extends Component
|
||||||
@ -24,7 +23,8 @@ class Select extends Component
|
|||||||
public Collection|array $services = [];
|
public Collection|array $services = [];
|
||||||
public bool $loadingServices = true;
|
public bool $loadingServices = true;
|
||||||
public bool $loading = false;
|
public bool $loading = false;
|
||||||
|
public $environments = [];
|
||||||
|
public ?string $selectedEnvironment = null;
|
||||||
public ?string $existingPostgresqlUrl = null;
|
public ?string $existingPostgresqlUrl = null;
|
||||||
|
|
||||||
protected $queryString = [
|
protected $queryString = [
|
||||||
@ -37,8 +37,18 @@ public function mount()
|
|||||||
if (isDev()) {
|
if (isDev()) {
|
||||||
$this->existingPostgresqlUrl = 'postgres://coolify:password@coolify-db:5432';
|
$this->existingPostgresqlUrl = 'postgres://coolify:password@coolify-db:5432';
|
||||||
}
|
}
|
||||||
|
$projectUuid = data_get($this->parameters, 'project_uuid');
|
||||||
|
$this->environments = Project::whereUuid($projectUuid)->first()->environments;
|
||||||
|
$this->selectedEnvironment = data_get($this->parameters, 'environment_name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updatedSelectedEnvironment()
|
||||||
|
{
|
||||||
|
return redirect()->route('project.resources.new', [
|
||||||
|
'project_uuid' => $this->parameters['project_uuid'],
|
||||||
|
'environment_name' => $this->selectedEnvironment,
|
||||||
|
]);
|
||||||
|
}
|
||||||
// public function addExistingPostgresql()
|
// public function addExistingPostgresql()
|
||||||
// {
|
// {
|
||||||
// try {
|
// try {
|
||||||
|
@ -11,13 +11,13 @@ class ByIp extends Component
|
|||||||
{
|
{
|
||||||
public $private_keys;
|
public $private_keys;
|
||||||
public $limit_reached;
|
public $limit_reached;
|
||||||
public int|null $private_key_id = null;
|
public ?int $private_key_id = null;
|
||||||
public $new_private_key_name;
|
public $new_private_key_name;
|
||||||
public $new_private_key_description;
|
public $new_private_key_description;
|
||||||
public $new_private_key_value;
|
public $new_private_key_value;
|
||||||
|
|
||||||
public string $name;
|
public string $name;
|
||||||
public string|null $description = null;
|
public ?string $description = null;
|
||||||
public string $ip;
|
public string $ip;
|
||||||
public string $user = 'root';
|
public string $user = 'root';
|
||||||
public int $port = 22;
|
public int $port = 22;
|
||||||
@ -26,16 +26,16 @@ class ByIp extends Component
|
|||||||
protected $rules = [
|
protected $rules = [
|
||||||
'name' => 'required|string',
|
'name' => 'required|string',
|
||||||
'description' => 'nullable|string',
|
'description' => 'nullable|string',
|
||||||
'ip' => 'required',
|
'ip' => 'required|ip',
|
||||||
'user' => 'required|string',
|
'user' => 'required|string',
|
||||||
'port' => 'required|integer',
|
'port' => 'required|integer',
|
||||||
];
|
];
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'name' => 'name',
|
'name' => 'Name',
|
||||||
'description' => 'description',
|
'description' => 'Description',
|
||||||
'ip' => 'ip',
|
'ip' => 'IP Address',
|
||||||
'user' => 'user',
|
'user' => 'User',
|
||||||
'port' => 'port',
|
'port' => 'Port',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
|
28
app/Http/Livewire/Server/Proxy/Logs.php
Normal file
28
app/Http/Livewire/Server/Proxy/Logs.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire\Server\Proxy;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Logs extends Component
|
||||||
|
{
|
||||||
|
public ?Server $server = null;
|
||||||
|
public $parameters = [];
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$this->parameters = get_route_parameters();
|
||||||
|
try {
|
||||||
|
$this->server = Server::ownedByCurrentTeam(['name', 'proxy'])->whereUuid(request()->server_uuid)->first();
|
||||||
|
if (is_null($this->server)) {
|
||||||
|
return redirect()->route('server.all');
|
||||||
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.server.proxy.logs');
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,11 @@ class Show extends Component
|
|||||||
{
|
{
|
||||||
public ?Server $server = null;
|
public ?Server $server = null;
|
||||||
public $parameters = [];
|
public $parameters = [];
|
||||||
|
protected $listeners = ['proxyStatusUpdated'];
|
||||||
|
public function proxyStatusUpdated()
|
||||||
|
{
|
||||||
|
$this->server->refresh();
|
||||||
|
}
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->parameters = get_route_parameters();
|
$this->parameters = get_route_parameters();
|
||||||
|
30
app/Http/Livewire/Subscription/Show.php
Normal file
30
app/Http/Livewire/Subscription/Show.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire\Subscription;
|
||||||
|
|
||||||
|
use App\Models\InstanceSettings;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Show extends Component
|
||||||
|
{
|
||||||
|
public InstanceSettings $settings;
|
||||||
|
public bool $alreadySubscribed = false;
|
||||||
|
public function mount() {
|
||||||
|
if (!isCloud()) {
|
||||||
|
return redirect('/');
|
||||||
|
}
|
||||||
|
$this->settings = InstanceSettings::get();
|
||||||
|
$this->alreadySubscribed = currentTeam()->subscription()->exists();
|
||||||
|
}
|
||||||
|
public function stripeCustomerPortal() {
|
||||||
|
$session = getStripeCustomerPortalSession(currentTeam());
|
||||||
|
if (is_null($session)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return redirect($session->url);
|
||||||
|
}
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.subscription.show')->layout('layouts.subscription');
|
||||||
|
}
|
||||||
|
}
|
@ -620,7 +620,7 @@ private function generate_compose_file()
|
|||||||
'container_name' => $this->container_name,
|
'container_name' => $this->container_name,
|
||||||
'restart' => RESTART_MODE,
|
'restart' => RESTART_MODE,
|
||||||
'environment' => $environment_variables,
|
'environment' => $environment_variables,
|
||||||
'labels' => generateLabelsApplication($this->application, $this->preview),
|
'labels' => generateLabelsApplication($this->application, $this->preview, $ports),
|
||||||
'expose' => $ports,
|
'expose' => $ports,
|
||||||
'networks' => [
|
'networks' => [
|
||||||
$this->destination->network,
|
$this->destination->network,
|
||||||
|
27
app/View/Components/Server/Sidebar.php
Normal file
27
app/View/Components/Server/Sidebar.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\View\Components\Server;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\View\Component;
|
||||||
|
|
||||||
|
class Sidebar extends Component
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new component instance.
|
||||||
|
*/
|
||||||
|
public function __construct(public Server $server, public $parameters)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the view / contents that represent the component.
|
||||||
|
*/
|
||||||
|
public function render(): View|Closure|string
|
||||||
|
{
|
||||||
|
return view('components.server.sidebar');
|
||||||
|
}
|
||||||
|
}
|
@ -147,7 +147,7 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica
|
|||||||
}
|
}
|
||||||
return $labels;
|
return $labels;
|
||||||
}
|
}
|
||||||
function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled)
|
function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled, $onlyPort = null)
|
||||||
{
|
{
|
||||||
$labels = collect([]);
|
$labels = collect([]);
|
||||||
$labels->push('traefik.enable=true');
|
$labels->push('traefik.enable=true');
|
||||||
@ -158,7 +158,9 @@ function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled)
|
|||||||
$path = $url->getPath();
|
$path = $url->getPath();
|
||||||
$schema = $url->getScheme();
|
$schema = $url->getScheme();
|
||||||
$port = $url->getPort();
|
$port = $url->getPort();
|
||||||
|
if (is_null($port) && !is_null($onlyPort)) {
|
||||||
|
$port = $onlyPort;
|
||||||
|
}
|
||||||
$http_label = "{$uuid}-http";
|
$http_label = "{$uuid}-http";
|
||||||
$https_label = "{$uuid}-https";
|
$https_label = "{$uuid}-https";
|
||||||
|
|
||||||
@ -203,9 +205,12 @@ function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled)
|
|||||||
|
|
||||||
return $labels;
|
return $labels;
|
||||||
}
|
}
|
||||||
function generateLabelsApplication(Application $application, ?ApplicationPreview $preview = null): array
|
function generateLabelsApplication(Application $application, ?ApplicationPreview $preview = null, $ports): array
|
||||||
{
|
{
|
||||||
|
$onlyPort = null;
|
||||||
|
if (count($ports) === 1) {
|
||||||
|
$onlyPort = $ports[0];
|
||||||
|
}
|
||||||
$pull_request_id = data_get($preview, 'pull_request_id', 0);
|
$pull_request_id = data_get($preview, 'pull_request_id', 0);
|
||||||
$container_name = generateApplicationContainerName($application, $pull_request_id);
|
$container_name = generateApplicationContainerName($application, $pull_request_id);
|
||||||
$appId = $application->id;
|
$appId = $application->id;
|
||||||
@ -221,7 +226,7 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview
|
|||||||
$domains = Str::of(data_get($application, 'fqdn'))->explode(',');
|
$domains = Str::of(data_get($application, 'fqdn'))->explode(',');
|
||||||
}
|
}
|
||||||
// Add Traefik labels no matter which proxy is selected
|
// Add Traefik labels no matter which proxy is selected
|
||||||
$labels = $labels->merge(fqdnLabelsForTraefik($domains, $application->settings->is_force_https_enabled));
|
$labels = $labels->merge(fqdnLabelsForTraefik($domains, $application->settings->is_force_https_enabled,$onlyPort));
|
||||||
}
|
}
|
||||||
return $labels->all();
|
return $labels->all();
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,8 @@ function generate_default_proxy_configuration(Server $server)
|
|||||||
];
|
];
|
||||||
if (isDev()) {
|
if (isDev()) {
|
||||||
$config['services']['traefik']['command'][] = "--log.level=debug";
|
$config['services']['traefik']['command'][] = "--log.level=debug";
|
||||||
|
$config['services']['traefik']['command'][] = "--accesslog.filepath=/traefik/access.log";
|
||||||
|
$config['services']['traefik']['command'][] = "--accesslog.bufferingsize=100";
|
||||||
}
|
}
|
||||||
$config = Yaml::dump($config, 4, 2);
|
$config = Yaml::dump($config, 4, 2);
|
||||||
SaveConfiguration::run($server, $config);
|
SaveConfiguration::run($server, $config);
|
||||||
|
@ -110,7 +110,10 @@ function getStripeCustomerPortalSession(Team $team)
|
|||||||
{
|
{
|
||||||
Stripe::setApiKey(config('subscription.stripe_api_key'));
|
Stripe::setApiKey(config('subscription.stripe_api_key'));
|
||||||
$return_url = route('team.index');
|
$return_url = route('team.index');
|
||||||
$stripe_customer_id = $team->subscription->stripe_customer_id;
|
$stripe_customer_id = data_get($team,'subscription.stripe_customer_id');
|
||||||
|
if (!$stripe_customer_id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
$session = \Stripe\BillingPortal\Session::create([
|
$session = \Stripe\BillingPortal\Session::create([
|
||||||
'customer' => $stripe_customer_id,
|
'customer' => $stripe_customer_id,
|
||||||
'return_url' => $return_url,
|
'return_url' => $return_url,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'docs' => 'https://coolify.io/contact',
|
'docs' => 'https://coolify.io/docs/contact',
|
||||||
'self_hosted' => env('SELF_HOSTED', true),
|
'self_hosted' => env('SELF_HOSTED', true),
|
||||||
'waitlist' => env('WAITLIST', false),
|
'waitlist' => env('WAITLIST', false),
|
||||||
'license_url' => 'https://licenses.coollabs.io',
|
'license_url' => 'https://licenses.coollabs.io',
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
// 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.73',
|
'release' => '4.0.0-beta.74',
|
||||||
// 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.73';
|
return '4.0.0-beta.74';
|
||||||
|
@ -34,14 +34,16 @@ services:
|
|||||||
POSTGRES_DB: "${DB_DATABASE:-coolify}"
|
POSTGRES_DB: "${DB_DATABASE:-coolify}"
|
||||||
POSTGRES_HOST_AUTH_METHOD: "trust"
|
POSTGRES_HOST_AUTH_METHOD: "trust"
|
||||||
volumes:
|
volumes:
|
||||||
- coolify-pg-data-dev:/var/lib/postgresql/data
|
- ./_data/coolify/_volumes/database/:/var/lib/postgresql/data
|
||||||
|
# - coolify-pg-data-dev:/var/lib/postgresql/data
|
||||||
redis:
|
redis:
|
||||||
ports:
|
ports:
|
||||||
- "${FORWARD_REDIS_PORT:-6379}:6379"
|
- "${FORWARD_REDIS_PORT:-6379}:6379"
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
volumes:
|
volumes:
|
||||||
- coolify-redis-data-dev:/data
|
- ./_data/coolify/_volumes/redis/:/data
|
||||||
|
# - coolify-redis-data-dev:/data
|
||||||
vite:
|
vite:
|
||||||
image: node:19
|
image: node:19
|
||||||
working_dir: /var/www/html
|
working_dir: /var/www/html
|
||||||
@ -56,7 +58,8 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- /:/host
|
- /:/host
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
- coolify-data-dev:/data/coolify
|
- ./_data/coolify/:/data/coolify
|
||||||
|
# - coolify-data-dev:/data/coolify
|
||||||
mailpit:
|
mailpit:
|
||||||
image: "axllent/mailpit:latest"
|
image: "axllent/mailpit:latest"
|
||||||
container_name: coolify-mail
|
container_name: coolify-mail
|
||||||
@ -76,7 +79,8 @@ services:
|
|||||||
MINIO_ACCESS_KEY: "${MINIO_ACCESS_KEY:-minioadmin}"
|
MINIO_ACCESS_KEY: "${MINIO_ACCESS_KEY:-minioadmin}"
|
||||||
MINIO_SECRET_KEY: "${MINIO_SECRET_KEY:-minioadmin}"
|
MINIO_SECRET_KEY: "${MINIO_SECRET_KEY:-minioadmin}"
|
||||||
volumes:
|
volumes:
|
||||||
- coolify-minio-data-dev:/data
|
- ./_data/coolify/_volumes/minio/:/data
|
||||||
|
# - coolify-minio-data-dev:/data
|
||||||
networks:
|
networks:
|
||||||
- coolify
|
- coolify
|
||||||
|
|
||||||
|
20
resources/views/components/server/sidebar.blade.php
Normal file
20
resources/views/components/server/sidebar.blade.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<div>
|
||||||
|
@if ($server->isFunctional())
|
||||||
|
<div class="flex h-full pr-4">
|
||||||
|
<div class="flex flex-col gap-4 min-w-fit">
|
||||||
|
<a class="{{ request()->routeIs('server.proxy') ? 'text-white' : '' }}"
|
||||||
|
href="{{ route('server.proxy', $parameters) }}">
|
||||||
|
<button>Configuration</button>
|
||||||
|
</a>
|
||||||
|
@if (data_get($server, 'proxy.type') !== 'NONE')
|
||||||
|
<a class="{{ request()->routeIs('server.proxy.logs') ? 'text-white' : '' }}"
|
||||||
|
href="{{ route('server.proxy.logs', $parameters) }}">
|
||||||
|
<button>Logs</button>
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<div>Server is not validated. Validate first.</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
@ -200,7 +200,7 @@
|
|||||||
label="Description" id="remoteServerDescription" />
|
label="Description" id="remoteServerDescription" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<x-forms.input required placeholder="Hostname or IP address" label="Hostname or IP Address"
|
<x-forms.input required placeholder="127.0.0.1" label="IP Address"
|
||||||
id="remoteServerHost" />
|
id="remoteServerHost" />
|
||||||
<x-forms.input required placeholder="Port number of your server. Default is 22."
|
<x-forms.input required placeholder="Port number of your server. Default is 22."
|
||||||
label="Port" id="remoteServerPort" />
|
label="Port" id="remoteServerPort" />
|
||||||
|
@ -14,27 +14,7 @@
|
|||||||
<span>Your subscription has been activated! Welcome onboard!</span>
|
<span>Your subscription has been activated! Welcome onboard!</span>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
<div class="w-full rounded stats stats-vertical lg:stats-horizontal">
|
|
||||||
<div class="stat">
|
|
||||||
<div class="stat-title">Servers</div>
|
|
||||||
<div class="stat-value">{{ $servers->count() }} </div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stat">
|
|
||||||
<div class="stat-title">Projects</div>
|
|
||||||
<div class="stat-value">{{ $projects->count() }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stat">
|
|
||||||
<div class="stat-title">Resources</div>
|
|
||||||
<div class="stat-value">{{ $resources }}</div>
|
|
||||||
<div class="stat-desc">Applications, databases, etc...</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat">
|
|
||||||
<div class="stat-title">S3 Storages</div>
|
|
||||||
<div class="stat-value">{{ $s3s }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<h3 class="pb-4">Projects</h3>
|
<h3 class="pb-4">Projects</h3>
|
||||||
|
|
||||||
@if ($projects->count() === 1)
|
@if ($projects->count() === 1)
|
||||||
@ -60,6 +40,10 @@
|
|||||||
{{ $project->description }}</div>
|
{{ $project->description }}</div>
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
|
<a class="mx-4 rounded group-hover:text-white hover:no-underline "
|
||||||
|
href="{{ route('project.resources.new', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => data_get($project, 'environments.0.name', 'production')]) }}">
|
||||||
|
<span class="font-bold hover:text-warning">+ New Resource</span>
|
||||||
|
</a>
|
||||||
<a class="mx-4 rounded group-hover:text-white"
|
<a class="mx-4 rounded group-hover:text-white"
|
||||||
href="{{ route('project.edit', ['project_uuid' => data_get($project, 'uuid')]) }}">
|
href="{{ route('project.edit', ['project_uuid' => data_get($project, 'uuid')]) }}">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon hover:text-warning" viewBox="0 0 24 24"
|
<svg xmlns="http://www.w3.org/2000/svg" class="icon hover:text-warning" viewBox="0 0 24 24"
|
||||||
@ -108,11 +92,11 @@
|
|||||||
</a>
|
</a>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function gotoProject(uuid) {
|
function gotoProject(uuid) {
|
||||||
window.location.href = '/project/' + uuid;
|
window.location.href = '/project/' + uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
{{-- <x-forms.button wire:click='getIptables'>Get IPTABLES</x-forms.button> --}}
|
{{-- <x-forms.button wire:click='getIptables'>Get IPTABLES</x-forms.button> --}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
<div x-data x-init="$wire.loadThings">
|
<div x-data x-init="$wire.loadThings">
|
||||||
|
<div class="flex gap-2 ">
|
||||||
<h1>New Resource</h1>
|
<h1>New Resource</h1>
|
||||||
|
<div class="w-96">
|
||||||
|
<x-forms.select wire:model="selectedEnvironment">
|
||||||
|
@foreach ($environments as $environment)
|
||||||
|
<option value="{{ $environment->name }}">Environment: {{ $environment->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</x-forms.select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="pb-4 ">Deploy resources, like Applications, Databases, Services...</div>
|
<div class="pb-4 ">Deploy resources, like Applications, Databases, Services...</div>
|
||||||
<div class="flex flex-col gap-2 pt-10">
|
<div class="flex flex-col gap-2 pt-10">
|
||||||
@if ($current_step === 'type')
|
@if ($current_step === 'type')
|
||||||
|
@ -65,8 +65,8 @@
|
|||||||
@endif
|
@endif
|
||||||
<div class="text-xs">{{ $application->status }}</div>
|
<div class="text-xs">{{ $application->status }}</div>
|
||||||
</a>
|
</a>
|
||||||
<a class="flex gap-2 p-1 mx-4 text-xs font-bold rounded hover:no-underline hover:text-warning"
|
<a class="flex gap-2 p-1 mx-4 font-bold rounded group-hover:text-white hover:no-underline"
|
||||||
href="{{ route('project.service.logs', [...$parameters, 'service_name' => $application->name]) }}">Logs</a>
|
href="{{ route('project.service.logs', [...$parameters, 'service_name' => $application->name]) }}"><span class="hover:text-warning">Logs</span></a>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
@foreach ($databases as $database)
|
@foreach ($databases as $database)
|
||||||
@ -94,8 +94,8 @@
|
|||||||
@endif
|
@endif
|
||||||
<div class="text-xs">{{ $database->status }}</div>
|
<div class="text-xs">{{ $database->status }}</div>
|
||||||
</a>
|
</a>
|
||||||
<a class="flex gap-2 p-1 mx-4 text-xs font-bold rounded hover:no-underline hover:text-warning"
|
<a class="flex gap-2 p-1 mx-4 font-bold rounded hover:no-underline group-hover:text-white"
|
||||||
href="{{ route('project.service.logs', [...$parameters, 'service_name' => $database->name]) }}">Logs</a>
|
href="{{ route('project.service.logs', [...$parameters, 'service_name' => $database->name]) }}"><span class="hover:text-warning">Logs</span></a>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<x-forms.input id="ip" label="IP Address" required
|
<x-forms.input id="ip" label="IP Address" required
|
||||||
helper="Could be IP Address (127.0.0.1) or Domain Name (duckduckgo.com)." />
|
helper="An IP Address (127.0.0.1). No domain names." />
|
||||||
<x-forms.input id="user" label="User" required />
|
<x-forms.input id="user" label ="User" required />
|
||||||
<x-forms.input type="number" id="port" label="Port" required />
|
<x-forms.input type="number" id="port" label="Port" required />
|
||||||
</div>
|
</div>
|
||||||
<x-forms.select label="Private Key" id="private_key_id">
|
<x-forms.select label="Private Key" id="private_key_id">
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
<div>
|
<div>
|
||||||
@if ($server->isFunctional())
|
|
||||||
@if (data_get($server, 'proxy.type'))
|
@if (data_get($server, 'proxy.type'))
|
||||||
<div x-init="$wire.loadProxyConfiguration">
|
<div x-init="$wire.loadProxyConfiguration">
|
||||||
@if ($selectedProxy === 'TRAEFIK_V2')
|
@if ($selectedProxy === 'TRAEFIK_V2')
|
||||||
<form wire:submit.prevent='submit'>
|
<form wire:submit.prevent='submit'>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<h2>Proxy</h2>
|
<h2>Configuration</h2>
|
||||||
<x-forms.button type="submit">Save</x-forms.button>
|
<x-forms.button type="submit">Save</x-forms.button>
|
||||||
@if ($server->proxy->status === 'exited')
|
@if ($server->proxy->status === 'exited')
|
||||||
<x-forms.button wire:click.prevent="change_proxy">Switch Proxy</x-forms.button>
|
<x-forms.button wire:click.prevent="change_proxy">Switch Proxy</x-forms.button>
|
||||||
@ -38,19 +37,19 @@
|
|||||||
</form>
|
</form>
|
||||||
@elseif($selectedProxy === 'NONE')
|
@elseif($selectedProxy === 'NONE')
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<h2>Proxy</h2>
|
<h2>Configuration</h2>
|
||||||
<x-forms.button wire:click.prevent="change_proxy">Switch Proxy</x-forms.button>
|
<x-forms.button wire:click.prevent="change_proxy">Switch Proxy</x-forms.button>
|
||||||
</div>
|
</div>
|
||||||
<div class="pt-3 pb-4">None</div>
|
<div class="pt-3 pb-4">Custom (None) Proxy Selected</div>
|
||||||
@else
|
@else
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<h2>Proxy</h2>
|
<h2>Configuration</h2>
|
||||||
<x-forms.button wire:click.prevent="change_proxy">Switch Proxy</x-forms.button>
|
<x-forms.button wire:click.prevent="change_proxy">Switch Proxy</x-forms.button>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@else
|
@else
|
||||||
<div>
|
<div>
|
||||||
<h2>Proxy</h2>
|
<h2>Configuration</h2>
|
||||||
<div class="subtitle">Select a proxy you would like to use on this server.</div>
|
<div class="subtitle">Select a proxy you would like to use on this server.</div>
|
||||||
<div class="grid gap-4">
|
<div class="grid gap-4">
|
||||||
<x-forms.button class="box" wire:click="select_proxy('NONE')">
|
<x-forms.button class="box" wire:click="select_proxy('NONE')">
|
||||||
@ -69,7 +68,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@else
|
|
||||||
<div>Server is not validated. Validate first.</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
|
9
resources/views/livewire/server/proxy/logs.blade.php
Normal file
9
resources/views/livewire/server/proxy/logs.blade.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<div>
|
||||||
|
<x-server.navbar :server="$server" :parameters="$parameters" />
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<x-server.sidebar :server="$server" :parameters="$parameters" />
|
||||||
|
<div class="w-full">
|
||||||
|
<livewire:project.shared.get-logs :server="$server" container="coolify-proxy" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,4 +1,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<x-server.navbar :server="$server" :parameters="$parameters" />
|
<x-server.navbar :server="$server" :parameters="$parameters" />
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<x-server.sidebar :server="$server" :parameters="$parameters" />
|
||||||
|
<div class="w-full">
|
||||||
<livewire:server.proxy :server="$server" />
|
<livewire:server.proxy :server="$server" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
49
resources/views/livewire/subscription/show.blade.php
Normal file
49
resources/views/livewire/subscription/show.blade.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
@if ($settings->is_resale_license_active)
|
||||||
|
@if (auth()->user()->isAdminFromSession())
|
||||||
|
<div class="flex justify-center mx-10">
|
||||||
|
<div x-data>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<h1>Subscription</h1>
|
||||||
|
<livewire:switch-team />
|
||||||
|
@if (subscriptionProvider() === 'stripe' && $alreadySubscribed)
|
||||||
|
<x-forms.button wire:click='stripeCustomerPortal'>Manage My Subscription</x-forms.button>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center pb-8">
|
||||||
|
<span>Currently active team: <span
|
||||||
|
class="text-warning">{{ session('currentTeam.name') }}</span></span>
|
||||||
|
</div>
|
||||||
|
@if (request()->query->get('cancelled'))
|
||||||
|
<div class="mb-6 rounded alert alert-error">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none"
|
||||||
|
viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
|
</svg>
|
||||||
|
<span>Something went wrong with your subscription. Please try again or contact
|
||||||
|
support.</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if (config('subscription.provider') !== null)
|
||||||
|
<livewire:subscription.pricing-plans />
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<div class="flex flex-col justify-center mx-10">
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<h1>Subscription</h1>
|
||||||
|
<livewire:switch-team />
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center pb-8">
|
||||||
|
<span>Currently active team: <span class="text-warning">{{ session('currentTeam.name') }}</span></span>
|
||||||
|
</div>
|
||||||
|
<div>You are not an admin or have been removed from this team. If this does not make sense, please <span
|
||||||
|
class="text-white underline cursor-pointer" wire:click="help" onclick="help.showModal()">contact
|
||||||
|
us</span>.</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@else
|
||||||
|
<div class="px-10">Resale license is not active. Please contact your instance admin.</div>
|
||||||
|
@endif
|
@ -1,46 +0,0 @@
|
|||||||
<x-layout-subscription>
|
|
||||||
@if ($settings->is_resale_license_active)
|
|
||||||
@if (auth()->user()->isAdminFromSession())
|
|
||||||
<div class="flex justify-center mx-10">
|
|
||||||
<div x-data>
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<h1>Subscription</h1>
|
|
||||||
<livewire:switch-team />
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center pb-8">
|
|
||||||
<span>Currently active team: <span
|
|
||||||
class="text-warning">{{ session('currentTeam.name') }}</span></span>
|
|
||||||
</div>
|
|
||||||
@if (request()->query->get('cancelled'))
|
|
||||||
<div class="mb-6 rounded alert alert-error">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none"
|
|
||||||
viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
||||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
<span>Something went wrong with your subscription. Please try again or contact
|
|
||||||
support.</span>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@if (config('subscription.provider') !== null)
|
|
||||||
<livewire:subscription.pricing-plans />
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
<div class="flex flex-col justify-center mx-10">
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<h1>Subscription</h1>
|
|
||||||
<livewire:switch-team />
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center pb-8">
|
|
||||||
<span>Currently active team: <span
|
|
||||||
class="text-warning">{{ session('currentTeam.name') }}</span></span>
|
|
||||||
</div>
|
|
||||||
<div>You are not an admin or have been removed from this team. If this does not make sense, please <span class="text-white underline cursor-pointer" wire:click="help" onclick="help.showModal()">contact us</span>.</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@else
|
|
||||||
<div class="px-10" >Resale license is not active. Please contact your instance admin.</div>
|
|
||||||
@endif
|
|
||||||
</x-layout-subscription>
|
|
@ -5,7 +5,6 @@
|
|||||||
use App\Http\Controllers\DatabaseController;
|
use App\Http\Controllers\DatabaseController;
|
||||||
use App\Http\Controllers\MagicController;
|
use App\Http\Controllers\MagicController;
|
||||||
use App\Http\Controllers\ProjectController;
|
use App\Http\Controllers\ProjectController;
|
||||||
use App\Http\Controllers\ServerController;
|
|
||||||
use App\Http\Livewire\Boarding\Index as BoardingIndex;
|
use App\Http\Livewire\Boarding\Index as BoardingIndex;
|
||||||
use App\Http\Livewire\Project\Service\Index as ServiceIndex;
|
use App\Http\Livewire\Project\Service\Index as ServiceIndex;
|
||||||
use App\Http\Livewire\Project\Service\Show as ServiceShow;
|
use App\Http\Livewire\Project\Service\Show as ServiceShow;
|
||||||
@ -17,7 +16,9 @@
|
|||||||
use App\Http\Livewire\Server\Destination\Show as DestinationShow;
|
use App\Http\Livewire\Server\Destination\Show as DestinationShow;
|
||||||
use App\Http\Livewire\Server\PrivateKey\Show as PrivateKeyShow;
|
use App\Http\Livewire\Server\PrivateKey\Show as PrivateKeyShow;
|
||||||
use App\Http\Livewire\Server\Proxy\Show as ProxyShow;
|
use App\Http\Livewire\Server\Proxy\Show as ProxyShow;
|
||||||
|
use App\Http\Livewire\Server\Proxy\Logs as ProxyLogs;
|
||||||
use App\Http\Livewire\Server\Show;
|
use App\Http\Livewire\Server\Show;
|
||||||
|
use App\Http\Livewire\Subscription\Show as SubscriptionShow;
|
||||||
use App\Http\Livewire\Waitlist\Index as WaitlistIndex;
|
use App\Http\Livewire\Waitlist\Index as WaitlistIndex;
|
||||||
use App\Models\GithubApp;
|
use App\Models\GithubApp;
|
||||||
use App\Models\GitlabApp;
|
use App\Models\GitlabApp;
|
||||||
@ -122,6 +123,7 @@
|
|||||||
Route::get('/server/new', Create::class)->name('server.create');
|
Route::get('/server/new', Create::class)->name('server.create');
|
||||||
Route::get('/server/{server_uuid}', Show::class)->name('server.show');
|
Route::get('/server/{server_uuid}', Show::class)->name('server.show');
|
||||||
Route::get('/server/{server_uuid}/proxy', ProxyShow::class)->name('server.proxy');
|
Route::get('/server/{server_uuid}/proxy', ProxyShow::class)->name('server.proxy');
|
||||||
|
Route::get('/server/{server_uuid}/proxy/logs', ProxyLogs::class)->name('server.proxy.logs');
|
||||||
Route::get('/server/{server_uuid}/private-key', PrivateKeyShow::class)->name('server.private-key');
|
Route::get('/server/{server_uuid}/private-key', PrivateKeyShow::class)->name('server.private-key');
|
||||||
Route::get('/server/{server_uuid}/destinations', DestinationShow::class)->name('server.destinations');
|
Route::get('/server/{server_uuid}/destinations', DestinationShow::class)->name('server.destinations');
|
||||||
});
|
});
|
||||||
@ -133,8 +135,7 @@
|
|||||||
Route::middleware(['throttle:force-password-reset'])->group(function () {
|
Route::middleware(['throttle:force-password-reset'])->group(function () {
|
||||||
Route::get('/force-password-reset', [Controller::class, 'force_passoword_reset'])->name('auth.force-password-reset');
|
Route::get('/force-password-reset', [Controller::class, 'force_passoword_reset'])->name('auth.force-password-reset');
|
||||||
});
|
});
|
||||||
Route::get('/subscription', [Controller::class, 'subscription'])->name('subscription.index');
|
Route::get('/subscription', SubscriptionShow::class)->name('subscription.index');
|
||||||
// Route::get('/help', Help::class)->name('help');
|
|
||||||
Route::get('/settings', [Controller::class, 'settings'])->name('settings.configuration');
|
Route::get('/settings', [Controller::class, 'settings'])->name('settings.configuration');
|
||||||
Route::get('/settings/license', [Controller::class, 'license'])->name('settings.license');
|
Route::get('/settings/license', [Controller::class, 'license'])->name('settings.license');
|
||||||
Route::get('/profile', fn () => view('profile', ['request' => request()]))->name('profile');
|
Route::get('/profile', fn () => view('profile', ['request' => request()]))->name('profile');
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"version": "3.12.36"
|
"version": "3.12.36"
|
||||||
},
|
},
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.73"
|
"version": "4.0.0-beta.74"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user