Skip to content

Commit d4d9268

Browse files
authored
Merge pull request coollabsio#3506 from coollabsio/next
v4.0.0-beta.342
2 parents e42c7e2 + 62459f9 commit d4d9268

File tree

177 files changed

+3100
-2109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

177 files changed

+3100
-2109
lines changed

.env.development.example

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ APP_KEY=
66
APP_URL=http://localhost
77
APP_PORT=8000
88
APP_DEBUG=true
9-
SSH_MUX_ENABLED=false
9+
SSH_MUX_ENABLED=true
1010

1111
# PostgreSQL Database Configuration
1212
DB_DATABASE=coolify
@@ -19,11 +19,7 @@ DB_PORT=5432
1919
# Set to true to enable Ray
2020
RAY_ENABLED=false
2121
# Set custom ray port
22-
RAY_PORT=
23-
24-
# Clockwork Configuration
25-
CLOCKWORK_ENABLED=false
26-
CLOCKWORK_QUEUE_COLLECT=true
22+
# RAY_PORT=
2723

2824
# Enable Laravel Telescope for debugging
2925
TELESCOPE_ENABLED=false

.github/pull_request_template.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
1-
> Always use `next` branch as destination branch for PRs, not `main`
1+
## Submit Checklist (REMOVE THIS SECTION BEFORE SUBMITTING)
2+
- [ ] I have selected the `next` branch as the destination for my PR, not `main`.
3+
- [ ] I have listed all changes in the `Changes` section.
4+
- [ ] I have filled out the `Issues` section with the issue/discussion link(s) (if applicable).
5+
- [ ] I have tested my changes.
6+
- [ ] I have considered backwards compatibility.
7+
- [ ] I have removed this checklist and any unused sections.
8+
9+
## Changes
10+
-
11+
12+
## Issues
13+
- fix #

.github/workflows/remove-labels-and-assignees-on-close.yml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
github-token: ${{ secrets.GITHUB_TOKEN }}
1919
script: |
2020
const { owner, repo } = context.repo;
21-
21+
2222
async function processIssue(issueNumber) {
2323
try {
2424
const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({
@@ -65,11 +65,14 @@ jobs:
6565
}
6666
6767
if (context.eventName === 'pull_request' || context.eventName === 'pull_request_target') {
68-
const { data: closedIssues } = await github.rest.search.issuesAndPullRequests({
69-
q: `repo:${owner}/${repo} is:issue is:closed linked:${context.payload.pull_request.number}`,
70-
per_page: 100
71-
});
72-
for (const issue of closedIssues.items) {
73-
await processIssue(issue.number);
68+
const pr = context.payload.pull_request;
69+
if (pr.body) {
70+
const issueReferences = pr.body.match(/#(\d+)/g);
71+
if (issueReferences) {
72+
for (const reference of issueReferences) {
73+
const issueNumber = parseInt(reference.substring(1));
74+
await processIssue(issueNumber);
75+
}
76+
}
7477
}
7578
}

CONTRIBUTING.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@ You can ask for guidance anytime on our [Discord server](https://coollabs.io/dis
66

77
## Table of Contents
88

9-
1. [Setup Development Environment](#1-setup-development-environment)
10-
2. [Verify Installation](#2-verify-installation-optional)
11-
3. [Fork and Setup Local Repository](#3-fork-and-setup-local-repository)
12-
4. [Set up Environment Variables](#4-set-up-environment-variables)
13-
5. [Start Coolify](#5-start-coolify)
14-
6. [Start Development](#6-start-development)
15-
7. [Development Notes](#7-development-notes)
16-
8. [Create a Pull Request](#8-create-a-pull-request)
17-
9. [Additional Contribution Guidelines](#additional-contribution-guidelines)
9+
- [Contributing to Coolify](#contributing-to-coolify)
10+
- [Table of Contents](#table-of-contents)
11+
- [1. Setup Development Environment](#1-setup-development-environment)
12+
- [2. Verify Installation (Optional)](#2-verify-installation-optional)
13+
- [3. Fork and Setup Local Repository](#3-fork-and-setup-local-repository)
14+
- [4. Set up Environment Variables](#4-set-up-environment-variables)
15+
- [5. Start Coolify](#5-start-coolify)
16+
- [6. Start Development](#6-start-development)
17+
- [7. Development Notes](#7-development-notes)
18+
- [8. Create a Pull Request](#8-create-a-pull-request)
19+
- [Additional Contribution Guidelines](#additional-contribution-guidelines)
20+
- [Contributing a New Service](#contributing-a-new-service)
21+
- [Contributing to Documentation](#contributing-to-documentation)
1822

1923
## 1. Setup Development Environment
2024

app/Actions/Application/StopApplication.php

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,43 @@
22

33
namespace App\Actions\Application;
44

5+
use App\Actions\Server\CleanupDocker;
56
use App\Models\Application;
67
use Lorisleiva\Actions\Concerns\AsAction;
78

89
class StopApplication
910
{
1011
use AsAction;
1112

12-
public function handle(Application $application, bool $previewDeployments = false)
13+
public function handle(Application $application, bool $previewDeployments = false, bool $dockerCleanup = true)
1314
{
14-
if ($application->destination->server->isSwarm()) {
15-
instant_remote_process(["docker stack rm {$application->uuid}"], $application->destination->server);
16-
17-
return;
18-
}
19-
20-
$servers = collect([]);
21-
$servers->push($application->destination->server);
22-
$application->additional_servers->map(function ($server) use ($servers) {
23-
$servers->push($server);
24-
});
25-
foreach ($servers as $server) {
15+
try {
16+
$server = $application->destination->server;
2617
if (! $server->isFunctional()) {
2718
return 'Server is not functional';
2819
}
29-
if ($previewDeployments) {
30-
$containers = getCurrentApplicationContainerStatus($server, $application->id, includePullrequests: true);
31-
} else {
32-
$containers = getCurrentApplicationContainerStatus($server, $application->id, 0);
33-
}
34-
if ($containers->count() > 0) {
35-
foreach ($containers as $container) {
36-
$containerName = data_get($container, 'Names');
37-
if ($containerName) {
38-
instant_remote_process(command: ["docker stop --time=30 $containerName"], server: $server, throwError: false);
39-
instant_remote_process(command: ["docker rm $containerName"], server: $server, throwError: false);
40-
instant_remote_process(command: ["docker rm -f {$containerName}"], server: $server, throwError: false);
41-
}
42-
}
20+
ray('Stopping application: '.$application->name);
21+
22+
if ($server->isSwarm()) {
23+
instant_remote_process(["docker stack rm {$application->uuid}"], $server);
24+
25+
return;
4326
}
27+
28+
$containersToStop = $application->getContainersToStop($previewDeployments);
29+
$application->stopContainers($containersToStop, $server);
30+
4431
if ($application->build_pack === 'dockercompose') {
45-
// remove network
46-
$uuid = $application->uuid;
47-
instant_remote_process(["docker network disconnect {$uuid} coolify-proxy"], $server, false);
48-
instant_remote_process(["docker network rm {$uuid}"], $server, false);
32+
$application->delete_connected_networks($application->uuid);
4933
}
34+
35+
if ($dockerCleanup) {
36+
CleanupDocker::dispatch($server, true);
37+
}
38+
} catch (\Exception $e) {
39+
ray($e->getMessage());
40+
41+
return $e->getMessage();
5042
}
5143
}
5244
}

app/Actions/CoolifyTask/RunRemoteProcess.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use App\Enums\ActivityTypes;
66
use App\Enums\ProcessStatus;
7+
use App\Helpers\SshMultiplexingHelper;
78
use App\Jobs\ApplicationDeploymentJob;
89
use App\Models\Server;
910
use Illuminate\Process\ProcessResult;
@@ -137,7 +138,7 @@ protected function getCommand(): string
137138
$command = $this->activity->getExtraProperty('command');
138139
$server = Server::whereUuid($server_uuid)->firstOrFail();
139140

140-
return generateSshCommand($server, $command);
141+
return SshMultiplexingHelper::generateSshCommand($server, $command);
141142
}
142143

143144
protected function handleOutput(string $type, string $output)

app/Actions/Database/StartDragonfly.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function handle(StandaloneDragonfly $database)
2323
$startCommand = "dragonfly --requirepass {$this->database->dragonfly_password}";
2424

2525
$container_name = $this->database->uuid;
26-
$this->configuration_dir = database_configuration_dir() . '/' . $container_name;
26+
$this->configuration_dir = database_configuration_dir().'/'.$container_name;
2727

2828
$this->commands = [
2929
"echo 'Starting {$database->name}.'",
@@ -75,7 +75,7 @@ public function handle(StandaloneDragonfly $database)
7575
],
7676
],
7777
];
78-
if (!is_null($this->database->limits_cpuset)) {
78+
if (! is_null($this->database->limits_cpuset)) {
7979
data_set($docker_compose, "services.{$container_name}.cpuset", $this->database->limits_cpuset);
8080
}
8181
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
@@ -118,10 +118,10 @@ private function generate_local_persistent_volumes()
118118
$local_persistent_volumes = [];
119119
foreach ($this->database->persistentStorages as $persistentStorage) {
120120
if ($persistentStorage->host_path !== '' && $persistentStorage->host_path !== null) {
121-
$local_persistent_volumes[] = $persistentStorage->host_path . ':' . $persistentStorage->mount_path;
121+
$local_persistent_volumes[] = $persistentStorage->host_path.':'.$persistentStorage->mount_path;
122122
} else {
123123
$volume_name = $persistentStorage->name;
124-
$local_persistent_volumes[] = $volume_name . ':' . $persistentStorage->mount_path;
124+
$local_persistent_volumes[] = $volume_name.':'.$persistentStorage->mount_path;
125125
}
126126
}
127127

@@ -152,7 +152,7 @@ private function generate_environment_variables()
152152
$environment_variables->push("$env->key=$env->real_value");
153153
}
154154

155-
if ($environment_variables->filter(fn($env) => str($env)->contains('REDIS_PASSWORD'))->isEmpty()) {
155+
if ($environment_variables->filter(fn ($env) => str($env)->contains('REDIS_PASSWORD'))->isEmpty()) {
156156
$environment_variables->push("REDIS_PASSWORD={$this->database->dragonfly_password}");
157157
}
158158

app/Actions/Database/StartKeydb.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function handle(StandaloneKeydb $database)
2424
$startCommand = "keydb-server --requirepass {$this->database->keydb_password} --appendonly yes";
2525

2626
$container_name = $this->database->uuid;
27-
$this->configuration_dir = database_configuration_dir() . '/' . $container_name;
27+
$this->configuration_dir = database_configuration_dir().'/'.$container_name;
2828

2929
$this->commands = [
3030
"echo 'Starting {$database->name}.'",
@@ -74,7 +74,7 @@ public function handle(StandaloneKeydb $database)
7474
],
7575
],
7676
];
77-
if (!is_null($this->database->limits_cpuset)) {
77+
if (! is_null($this->database->limits_cpuset)) {
7878
data_set($docker_compose, "services.{$container_name}.cpuset", $this->database->limits_cpuset);
7979
}
8080
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
@@ -94,10 +94,10 @@ public function handle(StandaloneKeydb $database)
9494
if (count($volume_names) > 0) {
9595
$docker_compose['volumes'] = $volume_names;
9696
}
97-
if (!is_null($this->database->keydb_conf) || !empty($this->database->keydb_conf)) {
97+
if (! is_null($this->database->keydb_conf) || ! empty($this->database->keydb_conf)) {
9898
$docker_compose['services'][$container_name]['volumes'][] = [
9999
'type' => 'bind',
100-
'source' => $this->configuration_dir . '/keydb.conf',
100+
'source' => $this->configuration_dir.'/keydb.conf',
101101
'target' => '/etc/keydb/keydb.conf',
102102
'read_only' => true,
103103
];
@@ -125,10 +125,10 @@ private function generate_local_persistent_volumes()
125125
$local_persistent_volumes = [];
126126
foreach ($this->database->persistentStorages as $persistentStorage) {
127127
if ($persistentStorage->host_path !== '' && $persistentStorage->host_path !== null) {
128-
$local_persistent_volumes[] = $persistentStorage->host_path . ':' . $persistentStorage->mount_path;
128+
$local_persistent_volumes[] = $persistentStorage->host_path.':'.$persistentStorage->mount_path;
129129
} else {
130130
$volume_name = $persistentStorage->name;
131-
$local_persistent_volumes[] = $volume_name . ':' . $persistentStorage->mount_path;
131+
$local_persistent_volumes[] = $volume_name.':'.$persistentStorage->mount_path;
132132
}
133133
}
134134

@@ -159,7 +159,7 @@ private function generate_environment_variables()
159159
$environment_variables->push("$env->key=$env->real_value");
160160
}
161161

162-
if ($environment_variables->filter(fn($env) => str($env)->contains('REDIS_PASSWORD'))->isEmpty()) {
162+
if ($environment_variables->filter(fn ($env) => str($env)->contains('REDIS_PASSWORD'))->isEmpty()) {
163163
$environment_variables->push("REDIS_PASSWORD={$this->database->keydb_password}");
164164
}
165165

app/Actions/Database/StartMariadb.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function handle(StandaloneMariadb $database)
2121
$this->database = $database;
2222

2323
$container_name = $this->database->uuid;
24-
$this->configuration_dir = database_configuration_dir() . '/' . $container_name;
24+
$this->configuration_dir = database_configuration_dir().'/'.$container_name;
2525

2626
$this->commands = [
2727
"echo 'Starting {$database->name}.'",
@@ -69,7 +69,7 @@ public function handle(StandaloneMariadb $database)
6969
],
7070
],
7171
];
72-
if (!is_null($this->database->limits_cpuset)) {
72+
if (! is_null($this->database->limits_cpuset)) {
7373
data_set($docker_compose, "services.{$container_name}.cpuset", $this->database->limits_cpuset);
7474
}
7575
if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) {
@@ -89,10 +89,10 @@ public function handle(StandaloneMariadb $database)
8989
if (count($volume_names) > 0) {
9090
$docker_compose['volumes'] = $volume_names;
9191
}
92-
if (!is_null($this->database->mariadb_conf) || !empty($this->database->mariadb_conf)) {
92+
if (! is_null($this->database->mariadb_conf) || ! empty($this->database->mariadb_conf)) {
9393
$docker_compose['services'][$container_name]['volumes'][] = [
9494
'type' => 'bind',
95-
'source' => $this->configuration_dir . '/custom-config.cnf',
95+
'source' => $this->configuration_dir.'/custom-config.cnf',
9696
'target' => '/etc/mysql/conf.d/custom-config.cnf',
9797
'read_only' => true,
9898
];
@@ -120,10 +120,10 @@ private function generate_local_persistent_volumes()
120120
$local_persistent_volumes = [];
121121
foreach ($this->database->persistentStorages as $persistentStorage) {
122122
if ($persistentStorage->host_path !== '' && $persistentStorage->host_path !== null) {
123-
$local_persistent_volumes[] = $persistentStorage->host_path . ':' . $persistentStorage->mount_path;
123+
$local_persistent_volumes[] = $persistentStorage->host_path.':'.$persistentStorage->mount_path;
124124
} else {
125125
$volume_name = $persistentStorage->name;
126-
$local_persistent_volumes[] = $volume_name . ':' . $persistentStorage->mount_path;
126+
$local_persistent_volumes[] = $volume_name.':'.$persistentStorage->mount_path;
127127
}
128128
}
129129

@@ -154,18 +154,18 @@ private function generate_environment_variables()
154154
$environment_variables->push("$env->key=$env->real_value");
155155
}
156156

157-
if ($environment_variables->filter(fn($env) => str($env)->contains('MARIADB_ROOT_PASSWORD'))->isEmpty()) {
157+
if ($environment_variables->filter(fn ($env) => str($env)->contains('MARIADB_ROOT_PASSWORD'))->isEmpty()) {
158158
$environment_variables->push("MARIADB_ROOT_PASSWORD={$this->database->mariadb_root_password}");
159159
}
160160

161-
if ($environment_variables->filter(fn($env) => str($env)->contains('MARIADB_DATABASE'))->isEmpty()) {
161+
if ($environment_variables->filter(fn ($env) => str($env)->contains('MARIADB_DATABASE'))->isEmpty()) {
162162
$environment_variables->push("MARIADB_DATABASE={$this->database->mariadb_database}");
163163
}
164164

165-
if ($environment_variables->filter(fn($env) => str($env)->contains('MARIADB_USER'))->isEmpty()) {
165+
if ($environment_variables->filter(fn ($env) => str($env)->contains('MARIADB_USER'))->isEmpty()) {
166166
$environment_variables->push("MARIADB_USER={$this->database->mariadb_user}");
167167
}
168-
if ($environment_variables->filter(fn($env) => str($env)->contains('MARIADB_PASSWORD'))->isEmpty()) {
168+
if ($environment_variables->filter(fn ($env) => str($env)->contains('MARIADB_PASSWORD'))->isEmpty()) {
169169
$environment_variables->push("MARIADB_PASSWORD={$this->database->mariadb_password}");
170170
}
171171

0 commit comments

Comments
 (0)