Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v4.0.0-beta.389 #4926

Merged
merged 21 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ea5363a
feat(service): Update affine.yaml with AI environment variables (#4918)
LeoMartinDev Jan 22, 2025
3d68996
Update service-templates.json
peaklabs-dev Jan 22, 2025
ac5d0aa
feat(service): Add new service Flipt (#4875)
zairigimad Jan 22, 2025
7cc90f0
fix(ui): metrics stuck in loading state
peaklabs-dev Jan 22, 2025
08e6c68
fix(ui): use `wire:navigate` to navigate to the server settings page
peaklabs-dev Jan 22, 2025
b5e88ad
fix(service): Plunk API & health check endpoint (#4925)
arxkdev Jan 22, 2025
b02c08f
Merge branch 'main' into next
peaklabs-dev Jan 22, 2025
0d85f57
chore(versions): update coolify versions to v4.0.0-beta.389
peaklabs-dev Jan 22, 2025
131216d
fix(service): infinite loading and lag with invoiceninja service (#4876)
PwnedC99 Jan 22, 2025
f10a345
fix(service): invoiceninja service
peaklabs-dev Jan 22, 2025
616076e
docs: add TECH_STACK.md (#4883)
zaaakher Jan 22, 2025
e155f39
feat(docs): update tech stack
peaklabs-dev Jan 22, 2025
3f2f1cf
chore(core): EnvironmentVariable Model now extends BaseModel to remov…
peaklabs-dev Jan 22, 2025
aeb57d2
fix(workflows): `Waiting for changes` label should also be considered…
peaklabs-dev Jan 22, 2025
1b62e1f
fix(workflows): remove tags only if the PR has been merged into the m…
peaklabs-dev Jan 22, 2025
007e291
fix(terminal): terminal shows that it is not available, even though i…
peaklabs-dev Jan 23, 2025
09d64d4
feat(terminal): show terminal unavailable if the container does not h…
peaklabs-dev Jan 23, 2025
cc640ad
fix(labels): docker labels do not generated correctly
peaklabs-dev Jan 23, 2025
1072a0c
feat(ui): improve deployment UI
peaklabs-dev Jan 23, 2025
edd4512
fix(helper): downgrade Nixpacks to v1.29.0
peaklabs-dev Jan 23, 2025
ec9f8de
fix(labels): generate labels when they are empty not when they are al…
peaklabs-dev Jan 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/chore-manage-stale-issues-and-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ jobs:
id: stale
with:
stale-issue-message: 'This issue will be automatically closed in a few days if no response is received. Please provide an update with the requested information.'
stale-pr-message: 'This pull request will be automatically closed in a few days if no response is received. Please update your PR or comment if you would like to continue working on it.'
stale-pr-message: 'This pull request requires attention. If no changes or response is received within the next few days, it will be automatically closed. Please update your PR or leave a comment with the requested information.'
close-issue-message: 'This issue has been automatically closed due to inactivity.'
close-pr-message: 'This pull request has been automatically closed due to inactivity.'
close-pr-message: 'Thank you for your contribution. Due to inactivity, this PR was automatically closed. If you would like to continue working on this change in the future, feel free to reopen this PR or submit a new one.'
days-before-stale: 14
days-before-close: 7
stale-issue-label: '⏱︎ Stale'
stale-pr-label: '⏱︎ Stale'
only-labels: '💤 Waiting for feedback'
only-labels: '💤 Waiting for feedback, 💤 Waiting for changes'
remove-stale-when-updated: true
operations-per-run: 100
labels-to-remove-when-unstale: '⏱︎ Stale, 💤 Waiting for feedback'
labels-to-remove-when-unstale: '⏱︎ Stale, 💤 Waiting for feedback, 💤 Waiting for changes'
close-issue-reason: 'not_planned'
exempt-all-milestones: false
16 changes: 10 additions & 6 deletions .github/workflows/chore-remove-labels-and-assignees-on-close.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ jobs:
script: |
const { owner, repo } = context.repo;

async function processIssue(issueNumber) {
async function processIssue(issueNumber, isFromPR = false, prBaseBranch = null) {
try {
if (isFromPR && prBaseBranch !== 'main') {
return;
}

const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({
owner,
repo,
Expand Down Expand Up @@ -59,19 +63,19 @@ jobs:
}
}

if (context.eventName === 'issues' || context.eventName === 'pull_request' || context.eventName === 'pull_request_target') {
const issue = context.payload.issue || context.payload.pull_request;
await processIssue(issue.number);
if (context.eventName === 'issues') {
await processIssue(context.payload.issue.number);
}

if (context.eventName === 'pull_request' || context.eventName === 'pull_request_target') {
const pr = context.payload.pull_request;
if (pr.body) {
await processIssue(pr.number);
if (pr.merged && pr.base.ref === 'main' && pr.body) {
const issueReferences = pr.body.match(/#(\d+)/g);
if (issueReferences) {
for (const reference of issueReferences) {
const issueNumber = parseInt(reference.substring(1));
await processIssue(issueNumber);
await processIssue(issueNumber, true, pr.base.ref);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

You can ask for guidance anytime on our [Discord server](https://coollabs.io/discord) in the `#contribute` channel.

To understand the tech stack, please refer to the [Tech Stack](TECH_STACK.md) document.

## Table of Contents

1. [Setup Development Environment](#1-setup-development-environment)
Expand Down
29 changes: 29 additions & 0 deletions TECH_STACK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Coolify Technology Stack

## Frontend

- Livewire and Alpine.js
- Blade (PHP templating engine)
- Tailwind CSS
- Monaco Editor (Code editor component)
- XTerm.js (Terminal component)

## Backend

- Laravel 11 (PHP Framework)
- PostgreSQL 15 (Database)
- Redis 7 (Caching & Real-time features)
- Soketi (WebSocket Server)

## DevOps & Infrastructure

- Docker & Docker Compose
- Nginx (Web Server)
- S6 Overlay (Process Supervisor)
- GitHub Actions (CI/CD)

## Languages

- PHP 8.4
- JavaScript
- Shell/Bash scripts
3 changes: 2 additions & 1 deletion app/Livewire/Project/Application/General.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ public function generateNginxConfiguration()
public function resetDefaultLabels($manualReset = false)
{
try {
if ($this->application->settings->is_container_label_readonly_enabled && ! $manualReset) {
if (! $this->application->settings->is_container_label_readonly_enabled && ! $manualReset) {
return;
}
$this->customLabels = str(implode('|coolify|', generateLabelsApplication($this->application)))->replace('|coolify|', "\n");
Expand Down Expand Up @@ -324,6 +324,7 @@ public function checkFqdns($showToaster = true)
}
check_domain_usage(resource: $this->application);
$this->application->fqdn = $domains->implode(',');
$this->resetDefaultLabels(false);
}
}

Expand Down
15 changes: 10 additions & 5 deletions app/Livewire/Project/Shared/ExecuteContainerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,16 @@ public function loadContainers()
private function checkShellAvailability(Server $server, string $container): bool
{
$escapedContainer = escapeshellarg($container);
$result = instant_remote_process([
"docker exec {$escapedContainer} which bash || docker exec {$escapedContainer} which sh",
], $server, false);

return ! empty($result);
try {
instant_remote_process([
"docker exec {$escapedContainer} bash -c 'exit 0' 2>/dev/null || ".
"docker exec {$escapedContainer} sh -c 'exit 0' 2>/dev/null",
], $server);

return true;
} catch (\Throwable) {
return false;
}
}

#[On('connectToServer')]
Expand Down
23 changes: 23 additions & 0 deletions app/Livewire/Project/Shared/Terminal.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

class Terminal extends Component
{
public bool $hasShell = true;

public function getListeners()
{
$teamId = auth()->user()->currentTeam()->id;
Expand All @@ -23,6 +25,21 @@ public function closeTerminal()
$this->dispatch('reloadWindow');
}

private function checkShellAvailability(Server $server, string $container): bool
{
$escapedContainer = escapeshellarg($container);
try {
instant_remote_process([
"docker exec {$escapedContainer} bash -c 'exit 0' 2>/dev/null || ".
"docker exec {$escapedContainer} sh -c 'exit 0' 2>/dev/null",
], $server);

return true;
} catch (\Throwable) {
return false;
}
}

#[On('send-terminal-command')]
public function sendTerminalCommand($isContainer, $identifier, $serverUuid)
{
Expand All @@ -40,6 +57,12 @@ public function sendTerminalCommand($isContainer, $identifier, $serverUuid)
return;
}

// Check shell availability
$this->hasShell = $this->checkShellAvailability($server, $identifier);
if (! $this->hasShell) {
return;
}

// Escape the identifier for shell usage
$escapedIdentifier = escapeshellarg($identifier);
$command = SshMultiplexingHelper::generateSshCommand($server, "docker exec -it {$escapedIdentifier} sh -c 'PATH=\$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && if [ -f ~/.profile ]; then . ~/.profile; fi && if [ -n \"\$SHELL\" ]; then exec \$SHELL; else sh; fi'");
Expand Down
10 changes: 1 addition & 9 deletions app/Models/EnvironmentVariable.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

use App\Models\EnvironmentVariable as ModelsEnvironmentVariable;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use OpenApi\Attributes as OA;
use Visus\Cuid2\Cuid2;

#[OA\Schema(
description: 'Environment Variable model',
Expand All @@ -30,7 +28,7 @@
'updated_at' => ['type' => 'string'],
]
)]
class EnvironmentVariable extends Model
class EnvironmentVariable extends BaseModel
{
protected $guarded = [];

Expand All @@ -49,12 +47,6 @@ class EnvironmentVariable extends Model

protected static function booted()
{
static::creating(function (Model $model) {
if (! $model->uuid) {
$model->uuid = (string) new Cuid2;
}
});

static::created(function (EnvironmentVariable $environment_variable) {
if ($environment_variable->resourceable_type === Application::class && ! $environment_variable->is_preview) {
$found = ModelsEnvironmentVariable::where('key', $environment_variable->key)
Expand Down
4 changes: 2 additions & 2 deletions config/constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

return [
'coolify' => [
'version' => '4.0.0-beta.388',
'helper_version' => '1.0.5',
'version' => '4.0.0-beta.389',
'helper_version' => '1.0.6',
'realtime_version' => '1.0.5',
'self_hosted' => env('SELF_HOSTED', true),
'autoupdate' => env('AUTOUPDATE'),
Expand Down
2 changes: 1 addition & 1 deletion docker/coolify-helper/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ARG DOCKER_BUILDX_VERSION=0.19.3
# https://github.com/buildpacks/pack/releases
ARG PACK_VERSION=0.36.2
# https://github.com/railwayapp/nixpacks/releases
ARG NIXPACKS_VERSION=1.32.0
ARG NIXPACKS_VERSION=1.29.0
# https://github.com/minio/mc/releases
ARG MINIO_VERSION=RELEASE.2024-11-21T17-21-54Z

Expand Down
21 changes: 21 additions & 0 deletions public/svgs/flipt.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion resources/views/components/server/sidebar.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<a wire:navigate class="menu-item {{ $activeMenu === 'log-drains' ? 'menu-item-active' : '' }}"
href="{{ route('server.log-drains', ['server_uuid' => $server->uuid]) }}">Log
Drains</a>
<a wire:navigate class="menu-item {{ $activeMenu === 'metrics' ? 'menu-item-active' : '' }}"
<a class="menu-item {{ $activeMenu === 'metrics' ? 'menu-item-active' : '' }}"
href="{{ route('server.charts', ['server_uuid' => $server->uuid]) }}">Metrics</a>
@endif
@if (!$server->isLocalhost())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@
href="{{ route('project.application.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Resource Operations</a>
<a class="menu-item" wire:current.exact="menu-item-active"
href="{{ route('project.application.metrics', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Metrics</a>
href="{{ route('project.application.metrics', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}" >Metrics</a>
<a class="menu-item" wire:current.exact="menu-item-active"
href="{{ route('project.application.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}"
wire:navigate>Tags</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@
@if(data_get($deployment, 'status') !== 'queued')
<div class="text-gray-600 dark:text-gray-400 text-sm">
Started: {{ formatDateInServerTimezone(data_get($deployment, 'created_at'), data_get($application, 'destination.server')) }}
@if($deployment->status !== 'in_progress' && $deployment->status !== 'cancelled-by-user' && $deployment->status !== 'failed')
@if($deployment->status !== 'in_progress' && $deployment->status !== 'cancelled-by-user')
<br>Ended: {{ formatDateInServerTimezone(data_get($deployment, 'finished_at'), data_get($application, 'destination.server')) }}
<br>Duration: {{ calculateDuration(data_get($deployment, 'created_at'), data_get($deployment, 'finished_at')) }}
<br>Finished {{ \Carbon\Carbon::parse(data_get($deployment, 'finished_at'))->diffForHumans() }}
@elseif($deployment->status === 'in_progress')
<br>Running for: {{ calculateDuration(data_get($deployment, 'created_at'), now()) }}
@endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<h3 class="py-4">Executions</h3>
<x-forms.button wire:click='cleanupFailed'>Cleanup Failed Backups</x-forms.button>
</div>
<div class="flex flex-col gap-4">
<div wire:poll.5000ms="refreshBackupExecutions" class="flex flex-col gap-4">
@forelse($executions as $execution)
<div wire:key="{{ data_get($execution, 'id') }}" @class([
'flex flex-col border-l-2 transition-colors p-4 bg-white dark:bg-coolgray-100 text-black dark:text-white',
Expand Down Expand Up @@ -40,6 +40,7 @@
@if(data_get($execution, 'status') !== 'running')
<br>Ended: {{ formatDateInServerTimezone(data_get($execution, 'finished_at'), $this->server()) }}
<br>Duration: {{ calculateDuration(data_get($execution, 'created_at'), data_get($execution, 'finished_at')) }}
<br>Finished {{ \Carbon\Carbon::parse(data_get($execution, 'finished_at'))->diffForHumans() }}
@endif
</div>
<div class="text-gray-600 dark:text-gray-400 text-sm">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
href="{{ route('project.database.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>Resource Operations</a>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.database.metrics', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>Metrics</a>
href="{{ route('project.database.metrics', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Metrics</a>
<a class='menu-item' wire:current.exact="menu-item-active"
href="{{ route('project.database.tags', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}"
wire:navigate>Tags</a>
Expand Down
2 changes: 1 addition & 1 deletion resources/views/livewire/project/shared/metrics.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@elseif(!$resource->destination->server->isMetricsEnabled())
<div class="alert alert-warning">Metrics are only available for servers with Sentinel & Metrics enabled!</div>
<div> Go to <a class="underline dark:text-white"
href="{{ route('server.show', $resource->destination->server->uuid) }}">Server settings</a> to
wire:navigate href="{{ route('server.show', $resource->destination->server->uuid) }}">Server settings</a> to
enable
it.</div>
@else
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="flex flex-col gap-2" x-data="{
<div class="flex flex-col gap-2" wire:poll.5000ms="refreshExecutions" x-data="{
init() {
let interval;
$wire.$watch('isPollingActive', value => {
Expand Down Expand Up @@ -48,6 +48,7 @@
@if(data_get($execution, 'status') !== 'running')
<br>Ended: {{ formatDateInServerTimezone(data_get($execution, 'finished_at'), data_get($task, 'application.destination.server') ?? data_get($task, 'service.destination.server')) }}
<br>Duration: {{ calculateDuration(data_get($execution, 'created_at'), data_get($execution, 'finished_at')) }}
<br>Finished {{ \Carbon\Carbon::parse(data_get($execution, 'finished_at'))->diffForHumans() }}
@endif
</div>
</a>
Expand Down
Loading
Loading