Skip to content

Commit

Permalink
Merge pull request coollabsio#1347 from coollabsio/next
Browse files Browse the repository at this point in the history
v4.0.0-beta.97
  • Loading branch information
andrasbacsai authored Oct 20, 2023
2 parents 13a0c2c + 5d9cfc3 commit 69ebff1
Show file tree
Hide file tree
Showing 90 changed files with 1,847 additions and 255 deletions.
12 changes: 9 additions & 3 deletions CONTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
You can ask for guidance anytime on our
[Discord server](https://coollabs.io/discord) in the `#contribution` channel.

## Code Contribution

## 1) Setup your development environment
### 1) Setup your development environment

- You need to have Docker Engine (or equivalent) [installed](https://docs.docker.com/engine/install/) on your system.
- For better DX, install [Spin](https://serversideup.net/open-source/spin/).

## 2) Set your environment variables
### 2) Set your environment variables

- Copy [.env.development.example](./.env.development.example) to .env.

Expand All @@ -23,9 +24,14 @@ You can ask for guidance anytime on our

- Run `./scripts/run setup:dev` - This will generate a secret key for you, delete any existing database layouts, migrate database to the new layout, and seed your database.

## 4) Start development
### 4) Start development
You can login your Coolify instance at `localhost:8000` with `[email protected]` and `password`.

Your horizon (Laravel scheduler): `localhost:8000/horizon` - Only reachable if you logged in with root user.

Mails are caught by Mailpit: `localhost:8025`


## New Service Contribution
Check out the docs [here](https://coolify.io/docs/how-to-add-a-service).

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Coolify is an open-source & self-hostable alternative to Heroku / Netlify / Verc

It helps you to manage your servers, applications, databases on your own hardware, all you need is SSH connection. You can manage VPS, Bare Metal, Raspberry PI's anything.

Image if you could have the ease of a cloud but with your own servers. That is **Coolify**.
Imagine if you could have the ease of a cloud but with your own servers. That is **Coolify**.

No vendor lock-in, which means that all the configuration for your applications/databases/etc are saved to your server. So if you decide to stop using Coolify (oh nooo), you could still manage your running resources. You just lose the automations and all the magic. 🪄️

Expand Down
9 changes: 6 additions & 3 deletions app/Actions/Database/StartDatabaseProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Actions\Database;

use App\Models\StandaloneMongodb;
use App\Models\StandalonePostgresql;
use App\Models\StandaloneRedis;
use Lorisleiva\Actions\Concerns\AsAction;
Expand All @@ -11,13 +12,15 @@ class StartDatabaseProxy
{
use AsAction;

public function handle(StandaloneRedis|StandalonePostgresql $database)
public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb $database)
{
$internalPort = null;
if ($database->getMorphClass()=== 'App\Models\StandaloneRedis') {
if ($database->getMorphClass() === 'App\Models\StandaloneRedis') {
$internalPort = 6379;
} else if ($database->getMorphClass()=== 'App\Models\StandalonePostgresql') {
} else if ($database->getMorphClass() === 'App\Models\StandalonePostgresql') {
$internalPort = 5432;
} else if ($database->getMorphClass() === 'App\Models\StandaloneMongodb') {
$internalPort = 27017;
}
$containerName = "{$database->uuid}-proxy";
$configuration_dir = database_proxy_dir($database->uuid);
Expand Down
163 changes: 163 additions & 0 deletions app/Actions/Database/StartMongodb.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

namespace App\Actions\Database;

use App\Models\StandaloneMongodb;
use Illuminate\Support\Str;
use Symfony\Component\Yaml\Yaml;
use Lorisleiva\Actions\Concerns\AsAction;

class StartMongodb
{
use AsAction;

public StandaloneMongodb $database;
public array $commands = [];
public string $configuration_dir;

public function handle(StandaloneMongodb $database)
{
$this->database = $database;

$startCommand = "mongod";

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

$this->commands = [
"echo '####### Starting {$database->name}.'",
"mkdir -p $this->configuration_dir",
];

$persistent_storages = $this->generate_local_persistent_volumes();
$volume_names = $this->generate_local_persistent_volumes_only_volume_names();
$environment_variables = $this->generate_environment_variables();
$this->add_custom_mongo_conf();

$docker_compose = [
'version' => '3.8',
'services' => [
$container_name => [
'image' => $this->database->image,
'command' => $startCommand,
'container_name' => $container_name,
'environment' => $environment_variables,
'restart' => RESTART_MODE,
'networks' => [
$this->database->destination->network,
],
'labels' => [
'coolify.managed' => 'true',
],
'healthcheck' => [
'test' => [
'CMD-SHELL',
'mongo --eval "printjson(db.serverStatus())" | grep uptime | grep -v grep'
],
'interval' => '5s',
'timeout' => '5s',
'retries' => 10,
'start_period' => '5s'
],
'mem_limit' => $this->database->limits_memory,
'memswap_limit' => $this->database->limits_memory_swap,
'mem_swappiness' => $this->database->limits_memory_swappiness,
'mem_reservation' => $this->database->limits_memory_reservation,
'cpus' => $this->database->limits_cpus,
'cpuset' => $this->database->limits_cpuset,
'cpu_shares' => $this->database->limits_cpu_shares,
]
],
'networks' => [
$this->database->destination->network => [
'external' => true,
'name' => $this->database->destination->network,
'attachable' => true,
]
]
];
if (count($this->database->ports_mappings_array) > 0) {
$docker_compose['services'][$container_name]['ports'] = $this->database->ports_mappings_array;
}
if (count($persistent_storages) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
}
if (count($volume_names) > 0) {
$docker_compose['volumes'] = $volume_names;
}
if (!is_null($this->database->mongo_conf)) {
$docker_compose['services'][$container_name]['volumes'][] = [
'type' => 'bind',
'source' => $this->configuration_dir . '/mongod.conf',
'target' => '/etc/mongo/mongod.conf',
'read_only' => true,
];
$docker_compose['services'][$container_name]['command'] = $startCommand . ' --config /etc/mongo/mongod.conf';
}
$docker_compose = Yaml::dump($docker_compose, 10);
$docker_compose_base64 = base64_encode($docker_compose);
$this->commands[] = "echo '{$docker_compose_base64}' | base64 -d > $this->configuration_dir/docker-compose.yml";
$readme = generate_readme_file($this->database->name, now());
$this->commands[] = "echo '{$readme}' > $this->configuration_dir/README.md";
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
$this->commands[] = "echo '####### {$database->name} started.'";
return remote_process($this->commands, $database->destination->server);
}

private function generate_local_persistent_volumes()
{
$local_persistent_volumes = [];
foreach ($this->database->persistentStorages as $persistentStorage) {
$volume_name = $persistentStorage->host_path ?? $persistentStorage->name;
$local_persistent_volumes[] = $volume_name . ':' . $persistentStorage->mount_path;
}
return $local_persistent_volumes;
}

private function generate_local_persistent_volumes_only_volume_names()
{
$local_persistent_volumes_names = [];
foreach ($this->database->persistentStorages as $persistentStorage) {
if ($persistentStorage->host_path) {
continue;
}
$name = $persistentStorage->name;
$local_persistent_volumes_names[$name] = [
'name' => $name,
'external' => false,
];
}
return $local_persistent_volumes_names;
}

private function generate_environment_variables()
{
$environment_variables = collect();
foreach ($this->database->runtime_environment_variables as $env) {
$environment_variables->push("$env->key=$env->value");
}

if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('MONGO_INITDB_ROOT_USERNAME'))->isEmpty()) {
$environment_variables->push("MONGO_INITDB_ROOT_USERNAME={$this->database->mongo_initdb_root_username}");
}

if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('MONGO_INITDB_ROOT_PASSWORD'))->isEmpty()) {
$environment_variables->push("MONGO_INITDB_ROOT_PASSWORD={$this->database->mongo_initdb_root_password}");
}

if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('MONGO_INITDB_DATABASE'))->isEmpty()) {
$environment_variables->push("MONGO_INITDB_DATABASE={$this->database->mongo_initdb_database}");
}
return $environment_variables->all();
}
private function add_custom_mongo_conf()
{
if (is_null($this->database->mongo_conf)) {
return;
}
$filename = 'mongod.conf';
$content = $this->database->mongo_conf;
$content_base64 = base64_encode($content);
$this->commands[] = "echo '{$content_base64}' | base64 -d > $this->configuration_dir/{$filename}";
}
}
8 changes: 5 additions & 3 deletions app/Actions/Database/StartPostgresql.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace App\Actions\Database;

use App\Models\Server;
use App\Models\StandalonePostgresql;
use Illuminate\Support\Str;
use Symfony\Component\Yaml\Yaml;
Expand All @@ -17,7 +16,7 @@ class StartPostgresql
public array $init_scripts = [];
public string $configuration_dir;

public function handle(Server $server, StandalonePostgresql $database)
public function handle(StandalonePostgresql $database)
{
$this->database = $database;
$container_name = $this->database->uuid;
Expand Down Expand Up @@ -104,7 +103,7 @@ public function handle(Server $server, StandalonePostgresql $database)
$this->commands[] = "echo '{$readme}' > $this->configuration_dir/README.md";
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
$this->commands[] = "echo '####### {$database->name} started.'";
return remote_process($this->commands, $server);
return remote_process($this->commands, $database->destination->server);
}

private function generate_local_persistent_volumes()
Expand Down Expand Up @@ -145,6 +144,9 @@ private function generate_environment_variables()
if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_USER'))->isEmpty()) {
$environment_variables->push("POSTGRES_USER={$this->database->postgres_user}");
}
if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('PGUSER'))->isEmpty()) {
$environment_variables->push("PGUSER={$this->database->postgres_user}");
}

if ($environment_variables->filter(fn ($env) => Str::of($env)->contains('POSTGRES_PASSWORD'))->isEmpty()) {
$environment_variables->push("POSTGRES_PASSWORD={$this->database->postgres_password}");
Expand Down
5 changes: 2 additions & 3 deletions app/Actions/Database/StartRedis.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace App\Actions\Database;

use App\Models\Server;
use App\Models\StandaloneRedis;
use Illuminate\Support\Str;
use Symfony\Component\Yaml\Yaml;
Expand All @@ -17,7 +16,7 @@ class StartRedis
public string $configuration_dir;


public function handle(Server $server, StandaloneRedis $database)
public function handle(StandaloneRedis $database)
{
$this->database = $database;

Expand Down Expand Up @@ -104,7 +103,7 @@ public function handle(Server $server, StandaloneRedis $database)
$this->commands[] = "echo '{$readme}' > $this->configuration_dir/README.md";
$this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d";
$this->commands[] = "echo '####### {$database->name} started.'";
return remote_process($this->commands, $server);
return remote_process($this->commands, $database->destination->server);
}

private function generate_local_persistent_volumes()
Expand Down
4 changes: 2 additions & 2 deletions app/Actions/Database/StopDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

namespace App\Actions\Database;

use App\Models\StandaloneMongodb;
use App\Models\StandalonePostgresql;
use App\Models\StandaloneRedis;
use App\Notifications\Application\StatusChanged;
use Lorisleiva\Actions\Concerns\AsAction;

class StopDatabase
{
use AsAction;

public function handle(StandaloneRedis|StandalonePostgresql $database)
public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb $database)
{
$server = $database->destination->server;
instant_remote_process(
Expand Down
3 changes: 2 additions & 1 deletion app/Actions/Database/StopDatabaseProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Actions\Database;

use App\Models\StandaloneMongodb;
use App\Models\StandalonePostgresql;
use App\Models\StandaloneRedis;
use Lorisleiva\Actions\Concerns\AsAction;
Expand All @@ -10,7 +11,7 @@ class StopDatabaseProxy
{
use AsAction;

public function handle(StandaloneRedis|StandalonePostgresql $database)
public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb $database)
{
instant_remote_process(["docker rm -f {$database->uuid}-proxy"], $database->destination->server);
$database->is_public = false;
Expand Down
Loading

0 comments on commit 69ebff1

Please sign in to comment.