commit
2978042162
@ -20,7 +20,7 @@ public function handle(Service $service)
|
|||||||
$commands[] = "docker network inspect $service->uuid >/dev/null 2>&1 || docker network create --attachable $service->uuid";
|
$commands[] = "docker network inspect $service->uuid >/dev/null 2>&1 || docker network create --attachable $service->uuid";
|
||||||
$commands[] = 'echo Starting service.';
|
$commands[] = 'echo Starting service.';
|
||||||
$commands[] = "echo 'Pulling images.'";
|
$commands[] = "echo 'Pulling images.'";
|
||||||
$commands[] = 'docker compose pull';
|
$commands[] = 'docker compose pull --policy always';
|
||||||
$commands[] = "echo 'Starting containers.'";
|
$commands[] = "echo 'Starting containers.'";
|
||||||
$commands[] = 'docker compose up -d --remove-orphans --force-recreate --build';
|
$commands[] = 'docker compose up -d --remove-orphans --force-recreate --build';
|
||||||
$commands[] = "docker network connect $service->uuid coolify-proxy >/dev/null 2>&1 || true";
|
$commands[] = "docker network connect $service->uuid coolify-proxy >/dev/null 2>&1 || true";
|
||||||
|
@ -15,7 +15,7 @@ public function handle(Service $resource)
|
|||||||
|
|
||||||
$commands[] = 'cd '.$resource->workdir();
|
$commands[] = 'cd '.$resource->workdir();
|
||||||
$commands[] = "echo 'Saved configuration files to {$resource->workdir()}.'";
|
$commands[] = "echo 'Saved configuration files to {$resource->workdir()}.'";
|
||||||
$commands[] = 'docker compose pull';
|
$commands[] = 'docker compose pull --policy always';
|
||||||
|
|
||||||
$server = data_get($resource, 'server');
|
$server = data_get($resource, 'server');
|
||||||
|
|
||||||
|
@ -462,7 +462,7 @@ private function deploy_docker_compose_buildpack()
|
|||||||
if ($this->env_filename) {
|
if ($this->env_filename) {
|
||||||
$command .= " --env-file {$this->workdir}/{$this->env_filename}";
|
$command .= " --env-file {$this->workdir}/{$this->env_filename}";
|
||||||
}
|
}
|
||||||
$command .= " --project-name {$this->application->uuid} --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} build";
|
$command .= " --project-name {$this->application->uuid} --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} build --pull";
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, $command), 'hidden' => true],
|
[executeInDocker($this->deployment_uuid, $command), 'hidden' => true],
|
||||||
);
|
);
|
||||||
@ -1624,12 +1624,15 @@ private function generate_compose_file()
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
if (data_get($this->application, 'swarm_placement_constraints')) {
|
||||||
|
$swarm_placement_constraints = Yaml::parse(base64_decode(data_get($this->application, 'swarm_placement_constraints')));
|
||||||
|
$docker_compose['services'][$this->container_name]['deploy'] = array_merge(
|
||||||
|
$docker_compose['services'][$this->container_name]['deploy'],
|
||||||
|
$swarm_placement_constraints
|
||||||
|
);
|
||||||
|
}
|
||||||
if (data_get($this->application, 'settings.is_swarm_only_worker_nodes')) {
|
if (data_get($this->application, 'settings.is_swarm_only_worker_nodes')) {
|
||||||
$docker_compose['services'][$this->container_name]['deploy']['placement'] = [
|
$docker_compose['services'][$this->container_name]['deploy']['placement']['constraints'][] = 'node.role == worker';
|
||||||
'constraints' => [
|
|
||||||
'node.role == worker',
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
if ($this->pull_request_id !== 0) {
|
if ($this->pull_request_id !== 0) {
|
||||||
$docker_compose['services'][$this->container_name]['deploy']['replicas'] = 1;
|
$docker_compose['services'][$this->container_name]['deploy']['replicas'] = 1;
|
||||||
@ -2028,23 +2031,6 @@ private function stop_running_container(bool $force = false)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function build_by_compose_file()
|
|
||||||
{
|
|
||||||
$this->application_deployment_queue->addLogEntry('Pulling & building required images.');
|
|
||||||
if ($this->application->build_pack === 'dockerimage') {
|
|
||||||
$this->application_deployment_queue->addLogEntry('Pulling latest images from the registry.');
|
|
||||||
$this->execute_remote_command(
|
|
||||||
[executeInDocker($this->deployment_uuid, "docker compose --project-name {$this->application->uuid} --project-directory {$this->workdir} pull"), 'hidden' => true],
|
|
||||||
[executeInDocker($this->deployment_uuid, "{$this->coolify_variables} docker compose --project-name {$this->application->uuid} --project-directory {$this->workdir} build"), 'hidden' => true],
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$this->execute_remote_command(
|
|
||||||
[executeInDocker($this->deployment_uuid, "{$this->coolify_variables} docker compose --project-name {$this->application->uuid} --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} build"), 'hidden' => true],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$this->application_deployment_queue->addLogEntry('New images built.');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function start_by_compose_file()
|
private function start_by_compose_file()
|
||||||
{
|
{
|
||||||
if ($this->application->build_pack === 'dockerimage') {
|
if ($this->application->build_pack === 'dockerimage') {
|
||||||
|
@ -53,6 +53,12 @@ class GithubPrivateRepository extends Component
|
|||||||
|
|
||||||
public ?string $publish_directory = null;
|
public ?string $publish_directory = null;
|
||||||
|
|
||||||
|
// In case of docker compose
|
||||||
|
public ?string $base_directory = null;
|
||||||
|
|
||||||
|
public ?string $docker_compose_location = '/docker-compose.yaml';
|
||||||
|
// End of docker compose
|
||||||
|
|
||||||
protected int $page = 1;
|
protected int $page = 1;
|
||||||
|
|
||||||
public $build_pack = 'nixpacks';
|
public $build_pack = 'nixpacks';
|
||||||
@ -68,6 +74,16 @@ public function mount()
|
|||||||
$this->github_apps = GithubApp::private();
|
$this->github_apps = GithubApp::private();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updatedBaseDirectory()
|
||||||
|
{
|
||||||
|
if ($this->base_directory) {
|
||||||
|
$this->base_directory = rtrim($this->base_directory, '/');
|
||||||
|
if (! str($this->base_directory)->startsWith('/')) {
|
||||||
|
$this->base_directory = '/'.$this->base_directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function updatedBuildPack()
|
public function updatedBuildPack()
|
||||||
{
|
{
|
||||||
if ($this->build_pack === 'nixpacks') {
|
if ($this->build_pack === 'nixpacks') {
|
||||||
@ -184,6 +200,10 @@ public function submit()
|
|||||||
if ($this->build_pack === 'dockerfile' || $this->build_pack === 'dockerimage') {
|
if ($this->build_pack === 'dockerfile' || $this->build_pack === 'dockerimage') {
|
||||||
$application->health_check_enabled = false;
|
$application->health_check_enabled = false;
|
||||||
}
|
}
|
||||||
|
if ($this->build_pack === 'dockercompose') {
|
||||||
|
$application['docker_compose_location'] = $this->docker_compose_location;
|
||||||
|
$application['base_directory'] = $this->base_directory;
|
||||||
|
}
|
||||||
$fqdn = generateFqdn($destination->server, $application->uuid);
|
$fqdn = generateFqdn($destination->server, $application->uuid);
|
||||||
$application->fqdn = $fqdn;
|
$application->fqdn = $fqdn;
|
||||||
|
|
||||||
|
@ -33,6 +33,12 @@ class GithubPrivateRepositoryDeployKey extends Component
|
|||||||
|
|
||||||
public ?string $publish_directory = null;
|
public ?string $publish_directory = null;
|
||||||
|
|
||||||
|
// In case of docker compose
|
||||||
|
public ?string $base_directory = null;
|
||||||
|
|
||||||
|
public ?string $docker_compose_location = '/docker-compose.yaml';
|
||||||
|
// End of docker compose
|
||||||
|
|
||||||
public string $repository_url;
|
public string $repository_url;
|
||||||
|
|
||||||
public string $branch;
|
public string $branch;
|
||||||
@ -163,6 +169,10 @@ public function submit()
|
|||||||
if ($this->build_pack === 'dockerfile' || $this->build_pack === 'dockerimage') {
|
if ($this->build_pack === 'dockerfile' || $this->build_pack === 'dockerimage') {
|
||||||
$application_init['health_check_enabled'] = false;
|
$application_init['health_check_enabled'] = false;
|
||||||
}
|
}
|
||||||
|
if ($this->build_pack === 'dockercompose') {
|
||||||
|
$application_init['docker_compose_location'] = $this->docker_compose_location;
|
||||||
|
$application_init['base_directory'] = $this->base_directory;
|
||||||
|
}
|
||||||
$application = Application::create($application_init);
|
$application = Application::create($application_init);
|
||||||
$application->settings->is_static = $this->is_static;
|
$application->settings->is_static = $this->is_static;
|
||||||
$application->settings->save();
|
$application->settings->save();
|
||||||
|
@ -33,6 +33,12 @@ class PublicGitRepository extends Component
|
|||||||
|
|
||||||
public ?string $publish_directory = null;
|
public ?string $publish_directory = null;
|
||||||
|
|
||||||
|
// In case of docker compose
|
||||||
|
public ?string $base_directory = null;
|
||||||
|
|
||||||
|
public ?string $docker_compose_location = '/docker-compose.yaml';
|
||||||
|
// End of docker compose
|
||||||
|
|
||||||
public string $git_branch = 'main';
|
public string $git_branch = 'main';
|
||||||
|
|
||||||
public int $rate_limit_remaining = 0;
|
public int $rate_limit_remaining = 0;
|
||||||
@ -59,6 +65,8 @@ class PublicGitRepository extends Component
|
|||||||
'is_static' => 'required|boolean',
|
'is_static' => 'required|boolean',
|
||||||
'publish_directory' => 'nullable|string',
|
'publish_directory' => 'nullable|string',
|
||||||
'build_pack' => 'required|string',
|
'build_pack' => 'required|string',
|
||||||
|
'base_directory' => 'nullable|string',
|
||||||
|
'docker_compose_location' => 'nullable|string',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
@ -67,6 +75,8 @@ class PublicGitRepository extends Component
|
|||||||
'is_static' => 'static',
|
'is_static' => 'static',
|
||||||
'publish_directory' => 'publish directory',
|
'publish_directory' => 'publish directory',
|
||||||
'build_pack' => 'build pack',
|
'build_pack' => 'build pack',
|
||||||
|
'base_directory' => 'base directory',
|
||||||
|
'docker_compose_location' => 'docker compose location',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
@ -79,6 +89,16 @@ public function mount()
|
|||||||
$this->query = request()->query();
|
$this->query = request()->query();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updatedBaseDirectory()
|
||||||
|
{
|
||||||
|
if ($this->base_directory) {
|
||||||
|
$this->base_directory = rtrim($this->base_directory, '/');
|
||||||
|
if (! str($this->base_directory)->startsWith('/')) {
|
||||||
|
$this->base_directory = '/'.$this->base_directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function updatedBuildPack()
|
public function updatedBuildPack()
|
||||||
{
|
{
|
||||||
if ($this->build_pack === 'nixpacks') {
|
if ($this->build_pack === 'nixpacks') {
|
||||||
@ -261,6 +281,10 @@ public function submit()
|
|||||||
if ($this->build_pack === 'dockerfile' || $this->build_pack === 'dockerimage') {
|
if ($this->build_pack === 'dockerfile' || $this->build_pack === 'dockerimage') {
|
||||||
$application_init['health_check_enabled'] = false;
|
$application_init['health_check_enabled'] = false;
|
||||||
}
|
}
|
||||||
|
if ($this->build_pack === 'dockercompose') {
|
||||||
|
$application_init['docker_compose_location'] = $this->docker_compose_location;
|
||||||
|
$application_init['base_directory'] = $this->base_directory;
|
||||||
|
}
|
||||||
$application = Application::create($application_init);
|
$application = Application::create($application_init);
|
||||||
|
|
||||||
$application->settings->is_static = $this->is_static;
|
$application->settings->is_static = $this->is_static;
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
use App\Models\LocalPersistentVolume;
|
use App\Models\LocalPersistentVolume;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Visus\Cuid2\Cuid2;
|
|
||||||
|
|
||||||
class Show extends Component
|
class Show extends Component
|
||||||
{
|
{
|
||||||
@ -12,8 +11,6 @@ class Show extends Component
|
|||||||
|
|
||||||
public bool $isReadOnly = false;
|
public bool $isReadOnly = false;
|
||||||
|
|
||||||
public ?string $modalId = null;
|
|
||||||
|
|
||||||
public bool $isFirst = true;
|
public bool $isFirst = true;
|
||||||
|
|
||||||
public bool $isService = false;
|
public bool $isService = false;
|
||||||
@ -32,11 +29,6 @@ class Show extends Component
|
|||||||
'host_path' => 'host',
|
'host_path' => 'host',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function mount()
|
|
||||||
{
|
|
||||||
$this->modalId = new Cuid2(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function submit()
|
public function submit()
|
||||||
{
|
{
|
||||||
$this->validate();
|
$this->validate();
|
||||||
|
@ -1081,45 +1081,55 @@ public function loadComposeFile($isInit = false)
|
|||||||
'git read-tree -mu HEAD',
|
'git read-tree -mu HEAD',
|
||||||
"cat .$workdir$composeFile",
|
"cat .$workdir$composeFile",
|
||||||
]);
|
]);
|
||||||
$composeFileContent = instant_remote_process($commands, $this->destination->server, false);
|
try {
|
||||||
if (! $composeFileContent) {
|
$composeFileContent = instant_remote_process($commands, $this->destination->server);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
if (str($e->getMessage())->contains('No such file')) {
|
||||||
|
throw new \RuntimeException("Docker Compose file not found at: $workdir$composeFile<br><br>Check if you used the right extension (.yaml or .yml) in the compose file name.");
|
||||||
|
}
|
||||||
|
if (str($e->getMessage())->contains('fatal: repository') && str($e->getMessage())->contains('does not exist')) {
|
||||||
|
if ($this->deploymentType() === 'deploy_key') {
|
||||||
|
throw new \RuntimeException('Your deploy key does not have access to the repository. Please check your deploy key and try again.');
|
||||||
|
}
|
||||||
|
throw new \RuntimeException('Repository does not exist. Please check your repository URL and try again.');
|
||||||
|
}
|
||||||
|
throw new \RuntimeException($e->getMessage());
|
||||||
|
} finally {
|
||||||
$this->docker_compose_location = $initialDockerComposeLocation;
|
$this->docker_compose_location = $initialDockerComposeLocation;
|
||||||
$this->save();
|
$this->save();
|
||||||
$commands = collect([
|
$commands = collect([
|
||||||
"rm -rf /tmp/{$uuid}",
|
"rm -rf /tmp/{$uuid}",
|
||||||
]);
|
]);
|
||||||
instant_remote_process($commands, $this->destination->server, false);
|
instant_remote_process($commands, $this->destination->server, false);
|
||||||
throw new \RuntimeException("Docker Compose file not found at: $workdir$composeFile<br><br>Check if you used the right extension (.yaml or .yml) in the compose file name.");
|
}
|
||||||
} else {
|
if ($composeFileContent) {
|
||||||
$this->docker_compose_raw = $composeFileContent;
|
$this->docker_compose_raw = $composeFileContent;
|
||||||
$this->save();
|
$this->save();
|
||||||
}
|
$parsedServices = $this->parseCompose();
|
||||||
|
if ($this->docker_compose_domains) {
|
||||||
$commands = collect([
|
$json = collect(json_decode($this->docker_compose_domains));
|
||||||
"rm -rf /tmp/{$uuid}",
|
$names = collect(data_get($parsedServices, 'services'))->keys()->toArray();
|
||||||
]);
|
$jsonNames = $json->keys()->toArray();
|
||||||
instant_remote_process($commands, $this->destination->server, false);
|
$diff = array_diff($jsonNames, $names);
|
||||||
$parsedServices = $this->parseCompose();
|
$json = $json->filter(function ($value, $key) use ($diff) {
|
||||||
if ($this->docker_compose_domains) {
|
return ! in_array($key, $diff);
|
||||||
$json = collect(json_decode($this->docker_compose_domains));
|
});
|
||||||
$names = collect(data_get($parsedServices, 'services'))->keys()->toArray();
|
if ($json) {
|
||||||
$jsonNames = $json->keys()->toArray();
|
$this->docker_compose_domains = json_encode($json);
|
||||||
$diff = array_diff($jsonNames, $names);
|
} else {
|
||||||
$json = $json->filter(function ($value, $key) use ($diff) {
|
$this->docker_compose_domains = null;
|
||||||
return ! in_array($key, $diff);
|
}
|
||||||
});
|
$this->save();
|
||||||
if ($json) {
|
|
||||||
$this->docker_compose_domains = json_encode($json);
|
|
||||||
} else {
|
|
||||||
$this->docker_compose_domains = null;
|
|
||||||
}
|
}
|
||||||
$this->save();
|
|
||||||
|
return [
|
||||||
|
'parsedServices' => $parsedServices,
|
||||||
|
'initialDockerComposeLocation' => $this->docker_compose_location,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
throw new \RuntimeException("Docker Compose file not found at: $workdir$composeFile<br><br>Check if you used the right extension (.yaml or .yml) in the compose file name.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
|
||||||
'parsedServices' => $parsedServices,
|
|
||||||
'initialDockerComposeLocation' => $this->docker_compose_location,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseContainerLabels(?ApplicationPreview $preview = null)
|
public function parseContainerLabels(?ApplicationPreview $preview = null)
|
||||||
|
@ -88,6 +88,9 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
try {
|
try {
|
||||||
$name = data_get($resource, 'name');
|
$name = data_get($resource, 'name');
|
||||||
$dockerComposeRaw = data_get($resource, 'service.docker_compose_raw');
|
$dockerComposeRaw = data_get($resource, 'service.docker_compose_raw');
|
||||||
|
if (! $dockerComposeRaw) {
|
||||||
|
throw new \Exception('No compose file found or not a valid YAML file.');
|
||||||
|
}
|
||||||
$dockerCompose = Yaml::parse($dockerComposeRaw);
|
$dockerCompose = Yaml::parse($dockerComposeRaw);
|
||||||
|
|
||||||
// Switch Image
|
// Switch Image
|
||||||
@ -106,7 +109,7 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
if ($resourceFqdns->count() === 1) {
|
if ($resourceFqdns->count() === 1) {
|
||||||
$resourceFqdns = $resourceFqdns->first();
|
$resourceFqdns = $resourceFqdns->first();
|
||||||
$variableName = 'SERVICE_FQDN_'.str($resource->name)->upper()->replace('-', '');
|
$variableName = 'SERVICE_FQDN_'.str($resource->name)->upper()->replace('-', '');
|
||||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'LIKE', "{$variableName}_%")->first();
|
||||||
$fqdn = Url::fromString($resourceFqdns);
|
$fqdn = Url::fromString($resourceFqdns);
|
||||||
$port = $fqdn->getPort();
|
$port = $fqdn->getPort();
|
||||||
$path = $fqdn->getPath();
|
$path = $fqdn->getPath();
|
||||||
@ -125,7 +128,7 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$variableName = 'SERVICE_URL_'.str($resource->name)->upper()->replace('-', '');
|
$variableName = 'SERVICE_URL_'.str($resource->name)->upper()->replace('-', '');
|
||||||
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
|
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', 'LIKE', "{$variableName}_%")->first();
|
||||||
$url = Url::fromString($fqdn);
|
$url = Url::fromString($fqdn);
|
||||||
$port = $url->getPort();
|
$port = $url->getPort();
|
||||||
$path = $url->getPath();
|
$path = $url->getPath();
|
||||||
|
@ -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.313',
|
'release' => '4.0.0-beta.314',
|
||||||
// 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.313';
|
return '4.0.0-beta.314';
|
||||||
|
BIN
public/svgs/docmost.png
Normal file
BIN
public/svgs/docmost.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
1
public/svgs/drupal.svg
Normal file
1
public/svgs/drupal.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="220.03239mm" height="167.50914mm" viewBox="0 0 623.71387 474.82906"><title>Risorsa 28</title><g id="Livello_2" data-name="Livello 2"><g id="Livello_1-2" data-name="Livello 1"><path d="M292.12129,345.00234h-26.212l.04275,49.04508c0,14.33211-6.14488,25.92692-20.477,25.92692-14.33924,0-20.54117-11.59481-20.54117-25.92692V345.04868H198.78953l-.00713,48.99874c0,28.32213,18.20655,51.27636,46.53223,51.27636,28.31849,0,46.79948-22.95423,46.79948-51.27636Z" style="fill:#009cde"/><rect x="528.48024" y="315.11614" width="26.08367" height="127.67755" style="fill:#009cde"/><polygon points="573.823 319.826 573.823 315.239 594.15 315.239 594.15 319.826 586.715 319.826 586.715 340.043 581.261 340.043 581.261 319.826 573.823 319.826" style="fill:#009cde"/><polygon points="604.673 315.24 610.476 332.295 610.544 332.295 616.029 315.24 623.714 315.24 623.714 340.044 618.606 340.044 618.606 322.465 618.535 322.465 612.458 340.044 608.252 340.044 602.175 322.64 602.103 322.64 602.103 340.044 596.999 340.044 596.999 315.24 604.673 315.24" style="fill:#009cde"/><path d="M177.46784,343.93624c-22.48375-5.18962-36.66617,17.148-37.25785,18.34557-.28871.58814-.2994.93035-1.29384.90533-.82337-.01773-.916-.90533-.916-.90533l-2.79086-17.08726H111.84157v97.51614h26.19419v-52.784c0-4.3128,11.61256-24.993,34.11766-19.67153,11.38088,2.69467,16.21054,7.52436,16.21054,7.52436V348.07087a41.85,41.85,0,0,0-10.89612-4.13463" style="fill:#009cde"/><path d="M353.05258,368.64446a26.13539,26.13539,0,1,1-26.13,26.13,26.13748,26.13748,0,0,1,26.13-26.13M327.664,474.82906V439.74191l.00712.00718.00713-13.14169s.03921-1.05141.98729-1.06218c.84474-.01066,1.03368.549,1.24041,1.06218,1.98529,4.94369,12.90641,23.76689,37.14374,17.86435A51.631,51.631,0,1,0,301.402,394.77446v80.0546Z" style="fill:#009cde"/><path d="M492.37655,394.77479a26.13539,26.13539,0,1,1-26.1336-26.13,26.139,26.139,0,0,1,26.1336,26.13m-.74494,47.9793H517.8935v-47.9793a51.62918,51.62918,0,1,0-65.64764,49.69381c24.23739,5.906,35.15845-12.92066,37.14374-17.86087.20673-.5132.39208-1.07284,1.24041-1.06566.94808.01425.98729,1.06566.98729,1.06566" style="fill:#009cde"/><path d="M36.905,337.16373h-10.529v83.26605l10.81417.278c22.18076,0,36.46656-2.01733,36.46656-41.90208,0-38.24519-12.61057-41.642-36.75172-41.642m-7.1108,105.38619H0V315.0649H31.96836c38.70852,0,68.06785,7.10374,68.06785,63.74083,0,56.09518-31.09872,63.74419-70.24206,63.74419" style="fill:#009cde"/><path d="M336.513,60.04433C316.67656,40.21728,297.75071,21.31654,292.11812,0c-5.63286,21.31654-24.56176,40.21728-44.39487,60.04433-29.74983,29.731-63.47995,63.42669-63.47995,113.96434a107.878,107.878,0,1,0,215.756,0c0-50.53435-33.72736-84.23329-63.48628-113.96434M230.09481,199.146c-6.61462-.22461-31.02654-42.30194,14.26152-87.1038l29.96891,32.73593a2.56174,2.56174,0,0,1-.20005,3.82276c-7.15132,7.33453-37.63207,37.90055-41.42061,48.46955-.782,2.18152-1.92407,2.099-2.60977,2.07556m62.02662,55.45668a37.10175,37.10175,0,0,1-37.102-37.102c0-9.39381,3.73446-17.765,9.24757-24.50685,6.68995-8.18054,27.84947-31.18907,27.84947-31.18907s20.83558,23.34627,27.79953,31.111a36.28369,36.28369,0,0,1,9.30744,24.58494,37.10209,37.10209,0,0,1-37.102,37.102m71.01314-60.16628c-.79965,1.74885-2.61363,4.66848-5.062,4.75761-4.36413.15894-4.83045-2.07721-8.05609-6.8511-7.08179-10.47987-68.88406-75.07043-80.44365-87.56214-10.16779-10.987-1.43181-18.733,2.62052-22.79219,5.084-5.09314,19.92417-19.92418,19.92417-19.92418s44.24974,41.984,62.6825,70.67071,12.08027,53.50972,8.33451,61.70129" style="fill:#009cde"/></g></g></svg>
|
After Width: | Height: | Size: 3.5 KiB |
6
public/svgs/plane.svg
Normal file
6
public/svgs/plane.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<svg width="155" height="155" viewBox="0 0 155 155" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="37" y="64" width="27" height="27" fill="#4075FC"/>
|
||||||
|
<rect x="91" y="64" width="27" height="27" fill="#4075FC"/>
|
||||||
|
<rect x="64" y="91" width="27" height="27" fill="#4075FC"/>
|
||||||
|
<rect x="64" y="36" width="54" height="28" fill="#4075FC"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 346 B |
@ -62,6 +62,15 @@ class="loading loading-xs dark:text-warning loading-spinner"></span>
|
|||||||
<x-forms.input id="publish_directory" required label="Publish Directory" />
|
<x-forms.input id="publish_directory" required label="Publish Directory" />
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@if ($build_pack === 'dockercompose')
|
||||||
|
<x-forms.input placeholder="/" wire:model.blur="base_directory" label="Base Directory"
|
||||||
|
helper="Directory to use as root. Useful for monorepos." />
|
||||||
|
<x-forms.input placeholder="/docker-compose.yaml" id="docker_compose_location"
|
||||||
|
label="Docker Compose Location"
|
||||||
|
helper="It is calculated together with the Base Directory:<br><span class='dark:text-warning'>{{ Str::start($base_directory . $docker_compose_location, '/') }}</span>" />
|
||||||
|
Compose file location in your repository:<span
|
||||||
|
class='dark:text-warning'>{{ Str::start($base_directory . $docker_compose_location, '/') }}</span>
|
||||||
|
@endif
|
||||||
@if ($show_is_static)
|
@if ($show_is_static)
|
||||||
<x-forms.input type="number" required id="port" label="Port" :readonly="$is_static || $build_pack === 'static'" />
|
<x-forms.input type="number" required id="port" label="Port" :readonly="$is_static || $build_pack === 'static'" />
|
||||||
<div class="w-52">
|
<div class="w-52">
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="pb-4">Deploy any public or private Git repositories through a GitHub App.</div>
|
<div class="pb-4">Deploy any public or private Git repositories through a GitHub App.</div>
|
||||||
|
|
||||||
@if ($github_apps->count() !== 0)
|
@if ($github_apps->count() !== 0)
|
||||||
<h2 class="pt-4 pb-4">Select a Github App</h2>
|
<h2 class="pt-4 pb-4">Select a Github App</h2>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
@ -92,6 +91,16 @@
|
|||||||
helper="If there is a build process involved (like Svelte, React, Next, etc..), please specify the output directory for the build assets." />
|
helper="If there is a build process involved (like Svelte, React, Next, etc..), please specify the output directory for the build assets." />
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@if ($build_pack === 'dockercompose')
|
||||||
|
<x-forms.input placeholder="/" wire:model.blur="base_directory"
|
||||||
|
label="Base Directory"
|
||||||
|
helper="Directory to use as root. Useful for monorepos." />
|
||||||
|
<x-forms.input placeholder="/docker-compose.yaml" id="docker_compose_location"
|
||||||
|
label="Docker Compose Location"
|
||||||
|
helper="It is calculated together with the Base Directory:<br><span class='dark:text-warning'>{{ Str::start($base_directory . $docker_compose_location, '/') }}</span>" />
|
||||||
|
Compose file location in your repository:<span
|
||||||
|
class='dark:text-warning'>{{ Str::start($base_directory . $docker_compose_location, '/') }}</span>
|
||||||
|
@endif
|
||||||
@if ($show_is_static)
|
@if ($show_is_static)
|
||||||
<x-forms.input type="number" id="port" label="Port" :readonly="$is_static || $build_pack === 'static'"
|
<x-forms.input type="number" id="port" label="Port" :readonly="$is_static || $build_pack === 'static'"
|
||||||
helper="The port your application listens on." />
|
helper="The port your application listens on." />
|
||||||
|
@ -13,10 +13,6 @@
|
|||||||
</div>
|
</div>
|
||||||
@if (!$branch_found)
|
@if (!$branch_found)
|
||||||
<div class="px-2 pt-4">
|
<div class="px-2 pt-4">
|
||||||
<div class="flex flex-col pb-4">
|
|
||||||
<div>Preselect branch (eg: main):</div>
|
|
||||||
<div class='text-helper'>https://github.com/coollabsio/coolify-examples/tree/main</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
For example application deployments, checkout <a class="underline dark:text-white"
|
For example application deployments, checkout <a class="underline dark:text-white"
|
||||||
href="https://github.com/coollabsio/coolify-examples/" target="_blank">Coolify
|
href="https://github.com/coollabsio/coolify-examples/" target="_blank">Coolify
|
||||||
@ -51,6 +47,15 @@
|
|||||||
helper="If there is a build process involved (like Svelte, React, Next, etc..), please specify the output directory for the build assets." />
|
helper="If there is a build process involved (like Svelte, React, Next, etc..), please specify the output directory for the build assets." />
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@if ($build_pack === 'dockercompose')
|
||||||
|
<x-forms.input placeholder="/" wire:model.blur="base_directory" label="Base Directory"
|
||||||
|
helper="Directory to use as root. Useful for monorepos." />
|
||||||
|
<x-forms.input placeholder="/docker-compose.yaml" id="docker_compose_location"
|
||||||
|
label="Docker Compose Location"
|
||||||
|
helper="It is calculated together with the Base Directory:<br><span class='dark:text-warning'>{{ Str::start($base_directory . $docker_compose_location, '/') }}</span>" />
|
||||||
|
Compose file location in your repository:<span
|
||||||
|
class='dark:text-warning'>{{ Str::start($base_directory . $docker_compose_location, '/') }}</span>
|
||||||
|
@endif
|
||||||
@if ($show_is_static)
|
@if ($show_is_static)
|
||||||
<x-forms.input type="number" id="port" label="Port" :readonly="$is_static || $build_pack === 'static'"
|
<x-forms.input type="number" id="port" label="Port" :readonly="$is_static || $build_pack === 'static'"
|
||||||
helper="The port your application listens on." />
|
helper="The port your application listens on." />
|
||||||
@ -59,10 +64,12 @@
|
|||||||
helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
|
helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@if ($build_pack === 'dockercompose' && isDev())
|
{{-- @if ($build_pack === 'dockercompose' && isDev())
|
||||||
<div class="dark:text-warning">If you choose Docker Compose based deployments, you cannot change it afterwards.</div>
|
<div class="dark:text-warning">If you choose Docker Compose based deployments, you cannot
|
||||||
<x-forms.checkbox instantSave label="New Compose Services (only in dev mode)" id="new_compose_services"></x-forms.checkbox>
|
change it afterwards.</div>
|
||||||
@endif
|
<x-forms.checkbox instantSave label="New Compose Services (only in dev mode)"
|
||||||
|
id="new_compose_services"></x-forms.checkbox>
|
||||||
|
@endif --}}
|
||||||
</div>
|
</div>
|
||||||
<x-forms.button wire:click.prevent='submit'>
|
<x-forms.button wire:click.prevent='submit'>
|
||||||
Continue
|
Continue
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<x-forms.checkbox id="is_multiline" label="Is Multiline?" />
|
<x-forms.checkbox id="is_multiline" label="Is Multiline?" />
|
||||||
@if (!$shared)
|
@if (!$shared)
|
||||||
<x-forms.checkbox id="is_literal"
|
<x-forms.checkbox id="is_literal"
|
||||||
helper="This means that when you use $VARIABLES in a value, it should be interpreted as the actual characters '$VARIABLES' and not as the value of a variable named VARIABLE.<br><br>Useful if you have $ sign in your value and there are some characters after it, but you would not like to interpolate it form another value. In this case, you should set this to true."
|
helper="This means that when you use $VARIABLES in a value, it should be interpreted as the actual characters '$VARIABLES' and not as the value of a variable named VARIABLE.<br><br>Useful if you have $ sign in your value and there are some characters after it, but you would not like to interpolate it from another value. In this case, you should set this to true."
|
||||||
label="Is Literal?" />
|
label="Is Literal?" />
|
||||||
@endif
|
@endif
|
||||||
<x-forms.button type="submit" @click="slideOverOpen=false">
|
<x-forms.button type="submit" @click="slideOverOpen=false">
|
||||||
|
@ -55,7 +55,7 @@ class="font-bold dark:text-warning text-coollabs">{{ $env->key }}</span>.
|
|||||||
@if ($env->is_shared)
|
@if ($env->is_shared)
|
||||||
<x-forms.checkbox instantSave id="env.is_build_time" label="Build Variable?" />
|
<x-forms.checkbox instantSave id="env.is_build_time" label="Build Variable?" />
|
||||||
<x-forms.checkbox instantSave id="env.is_literal"
|
<x-forms.checkbox instantSave id="env.is_literal"
|
||||||
helper="This means that when you use $VARIABLES in a value, it should be interpreted as the actual characters '$VARIABLES' and not as the value of a variable named VARIABLE.<br><br>Useful if you have $ sign in your value and there are some characters after it, but you would not like to interpolate it form another value. In this case, you should set this to true."
|
helper="This means that when you use $VARIABLES in a value, it should be interpreted as the actual characters '$VARIABLES' and not as the value of a variable named VARIABLE.<br><br>Useful if you have $ sign in your value and there are some characters after it, but you would not like to interpolate it from another value. In this case, you should set this to true."
|
||||||
label="Is Literal?" />
|
label="Is Literal?" />
|
||||||
@else
|
@else
|
||||||
@if ($isSharedVariable)
|
@if ($isSharedVariable)
|
||||||
@ -65,7 +65,7 @@ class="font-bold dark:text-warning text-coollabs">{{ $env->key }}</span>.
|
|||||||
<x-forms.checkbox instantSave id="env.is_multiline" label="Is Multiline?" />
|
<x-forms.checkbox instantSave id="env.is_multiline" label="Is Multiline?" />
|
||||||
@if (!data_get($env, 'is_multiline'))
|
@if (!data_get($env, 'is_multiline'))
|
||||||
<x-forms.checkbox instantSave id="env.is_literal"
|
<x-forms.checkbox instantSave id="env.is_literal"
|
||||||
helper="This means that when you use $VARIABLES in a value, it should be interpreted as the actual characters '$VARIABLES' and not as the value of a variable named VARIABLE.<br><br>Useful if you have $ sign in your value and there are some characters after it, but you would not like to interpolate it form another value. In this case, you should set this to true."
|
helper="This means that when you use $VARIABLES in a value, it should be interpreted as the actual characters '$VARIABLES' and not as the value of a variable named VARIABLE.<br><br>Useful if you have $ sign in your value and there are some characters after it, but you would not like to interpolate it from another value. In this case, you should set this to true."
|
||||||
label="Is Literal?" />
|
label="Is Literal?" />
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
|
@ -15,15 +15,17 @@
|
|||||||
<x-forms.input id="storage.host_path" readonly helper="Directory on the host system."
|
<x-forms.input id="storage.host_path" readonly helper="Directory on the host system."
|
||||||
label="Source Path"
|
label="Source Path"
|
||||||
helper="Warning: Changing the source path after the initial start could cause problems. Only use it when you know what are you doing." />
|
helper="Warning: Changing the source path after the initial start could cause problems. Only use it when you know what are you doing." />
|
||||||
|
<x-forms.input id="storage.mount_path" label="Destination Path"
|
||||||
|
helper="Directory inside the container." required readonly />
|
||||||
@else
|
@else
|
||||||
<x-forms.input id="storage.host_path" helper="Directory on the host system." label="Source Path"
|
<x-forms.input id="storage.host_path" helper="Directory on the host system." label="Source Path"
|
||||||
helper="Warning: Changing the source path after the initial start could cause problems. Only use it when you know what are you doing." />
|
helper="Warning: Changing the source path after the initial start could cause problems. Only use it when you know what are you doing." />
|
||||||
|
<x-forms.input id="storage.mount_path" label="Destination Path"
|
||||||
|
helper="Directory inside the container." required readonly />
|
||||||
|
<x-forms.button type="submit">
|
||||||
|
Update
|
||||||
|
</x-forms.button>
|
||||||
@endif
|
@endif
|
||||||
<x-forms.input id="storage.mount_path" label="Destination Path" helper="Directory inside the container."
|
|
||||||
required readonly />
|
|
||||||
<x-forms.button type="submit">
|
|
||||||
Update
|
|
||||||
</x-forms.button>
|
|
||||||
@else
|
@else
|
||||||
<x-forms.input id="storage.name" required readonly />
|
<x-forms.input id="storage.name" required readonly />
|
||||||
<x-forms.input id="storage.host_path" readonly />
|
<x-forms.input id="storage.host_path" readonly />
|
||||||
|
@ -1,16 +1,45 @@
|
|||||||
<form wire:submit='createGitHubApp' class="flex flex-col w-full gap-2">
|
<form wire:submit='createGitHubApp' class="flex flex-col w-full gap-2">
|
||||||
|
<div class="pb-2">This is required, if you would like to get full integration (commit / pull request
|
||||||
|
deployments, etc)
|
||||||
|
with GitHub.</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<x-forms.input id="name" label="Name" required />
|
<x-forms.input id="name" label="Name" required />
|
||||||
<x-forms.input helper="If empty, your GitHub user will be used." id="organization" label="Organization" />
|
<x-forms.input helper="If empty, your GitHub user will be used."
|
||||||
|
placeholder="If empty, your GitHub user will be used." id="organization" label="Organization (on GitHub)" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div x-data="{
|
||||||
<x-forms.input id="html_url" label="HTML Url" required />
|
activeAccordion: '',
|
||||||
<x-forms.input id="api_url" label="API Url" required />
|
setActiveAccordion(id) {
|
||||||
</div>
|
this.activeAccordion = (this.activeAccordion == id) ? '' : id
|
||||||
<div class="flex gap-2">
|
}
|
||||||
<x-forms.input id="custom_user" label="Custom Git User" required />
|
}" class="relative w-full py-2 mx-auto overflow-hidden text-sm font-normal rounded-md">
|
||||||
<x-forms.input id="custom_port" type="number" label="Custom Git Port" required />
|
<div x-data="{ id: $id('accordion') }" class="cursor-pointer group">
|
||||||
|
<button @click="setActiveAccordion(id)"
|
||||||
|
class="flex items-center justify-between w-full px-1 py-2 text-left select-none hover:dark:text-white hover:bg-white/5"
|
||||||
|
type="button">
|
||||||
|
<h4>Advanced</h4>
|
||||||
|
<svg class="w-4 h-4 duration-200 ease-out" :class="{ 'rotate-180': activeAccordion == id }"
|
||||||
|
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor"
|
||||||
|
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<polyline points="6 9 12 15 18 9"></polyline>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<div x-show="activeAccordion==id" x-collapse x-cloak class="px-2">
|
||||||
|
<div class="py-2">Self-hosted / Enterprise GitHub details.</div>
|
||||||
|
<div class="flex flex-col gap-2 pt-0 opacity-70">
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<x-forms.input id="html_url" label="HTML Url" required />
|
||||||
|
<x-forms.input id="api_url" label="API Url" required />
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<x-forms.input id="custom_user" label="Custom Git User" required />
|
||||||
|
<x-forms.input id="custom_port" type="number" label="Custom Git Port" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (!isCloud())
|
@if (!isCloud())
|
||||||
<x-forms.checkbox id="is_system_wide" label="System Wide" />
|
<x-forms.checkbox id="is_system_wide" label="System Wide" />
|
||||||
@endif
|
@endif
|
||||||
|
58
templates/compose/docmost.yaml
Normal file
58
templates/compose/docmost.yaml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# documentation: https://docmost.com/docs/
|
||||||
|
# slogan: Open-source collaborative wiki and documentation software
|
||||||
|
# tags: documentation, opensource, wiki, confluence, knowledge-base, notion, realtime-collaboration, notion-alternative
|
||||||
|
# logo: svgs/docmost.png
|
||||||
|
# port: 3000
|
||||||
|
|
||||||
|
services:
|
||||||
|
docmost:
|
||||||
|
image: "docmost/docmost:latest"
|
||||||
|
depends_on:
|
||||||
|
postgresql:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_DOCMOST_3000
|
||||||
|
- APP_SECRET=$SERVICE_BASE64_APPKEY
|
||||||
|
- APP_URL=$SERVICE_FQDN_DOCMOST_3000
|
||||||
|
- DATABASE_URL=postgresql://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql/docmost?schema=public
|
||||||
|
- REDIS_URL=redis://redis:6379
|
||||||
|
volumes:
|
||||||
|
- "docmost:/app/data/storage"
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- curl
|
||||||
|
- "-f"
|
||||||
|
- "http://127.0.0.1:3000"
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 20
|
||||||
|
postgresql:
|
||||||
|
image: "postgres:16-alpine"
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||||
|
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||||
|
- POSTGRES_DB=docmost
|
||||||
|
volumes:
|
||||||
|
- "postgresql-data:/var/lib/postgresql/data"
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD-SHELL
|
||||||
|
- "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
|
||||||
|
interval: 5s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 20
|
||||||
|
redis:
|
||||||
|
image: "redis:7.2-alpine"
|
||||||
|
volumes:
|
||||||
|
- "redis-data:/data"
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD
|
||||||
|
- redis-cli
|
||||||
|
- PING
|
||||||
|
interval: 5s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 20
|
53
templates/compose/drupal-with-postgresql.yaml
Normal file
53
templates/compose/drupal-with-postgresql.yaml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# documentation: https://www.drupal.org/about
|
||||||
|
# slogan: Drupal is a free and open-source web content management system written in PHP and distributed under the GNU General Public License.
|
||||||
|
# tags: cms, blog, content, management, postgresql
|
||||||
|
# logo: svgs/drupal.svg
|
||||||
|
|
||||||
|
services:
|
||||||
|
drupal:
|
||||||
|
image: "drupal:10-apache"
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_DRUPAL
|
||||||
|
- DB_HOST=postgres
|
||||||
|
- DB_NAME=postgres
|
||||||
|
- DB_USER=postgres
|
||||||
|
- DB_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||||
|
volumes:
|
||||||
|
- type: volume
|
||||||
|
source: drupal_modules
|
||||||
|
target: /var/www/html/modules
|
||||||
|
is_directory: true
|
||||||
|
- type: volume
|
||||||
|
source: drupal_profiles
|
||||||
|
target: /var/www/html/profiles
|
||||||
|
is_directory: true
|
||||||
|
- type: volume
|
||||||
|
source: drupal_themes
|
||||||
|
target: /var/www/html/themes
|
||||||
|
is_directory: true
|
||||||
|
- type: volume
|
||||||
|
source: drupal_sites
|
||||||
|
target: /var/www/html/sites
|
||||||
|
is_directory: true
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD-SHELL
|
||||||
|
- "curl -f http://localhost:80 || exit 1"
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
postgres:
|
||||||
|
image: "postgres:16"
|
||||||
|
environment:
|
||||||
|
- POSTGRES_DB=postgres
|
||||||
|
- POSTGRES_USER=postgres
|
||||||
|
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
- CMD-SHELL
|
||||||
|
- "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
|
||||||
|
interval: 5s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 20
|
@ -15,7 +15,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- minio-data:/data
|
- minio-data:/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
|
test: ["CMD", "mc", "ready", "local"]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
retries: 10
|
retries: 10
|
||||||
|
190
templates/compose/plane.yaml
Normal file
190
templates/compose/plane.yaml
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
# documentation: https://docs.plane.so/self-hosting/methods/docker-compose
|
||||||
|
# slogan: The open source project management tool
|
||||||
|
# tags: plane,project-management,tool,open,source,api,nextjs,redis,postgresql,django,pm
|
||||||
|
# logo: svgs/plane.svg
|
||||||
|
|
||||||
|
x-app-env: &app-env
|
||||||
|
environment:
|
||||||
|
- WEB_URL=http://localhost
|
||||||
|
- DEBUG=${DEBUG:-0}
|
||||||
|
- CORS_ALLOWED_ORIGINS=http://localhost
|
||||||
|
# Gunicorn Workers
|
||||||
|
- GUNICORN_WORKERS=${GUNICORN_WORKERS:-1}
|
||||||
|
#DB SETTINGS
|
||||||
|
- PGHOST=plane-db
|
||||||
|
- PGDATABASE=plane
|
||||||
|
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||||
|
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||||
|
- POSTGRES_DB=plane
|
||||||
|
- POSTGRES_PORT=5432
|
||||||
|
- PGDATA=/var/lib/postgresql/data
|
||||||
|
- DATABASE_URL=postgresql://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@plane-db/plane
|
||||||
|
# REDIS SETTINGS
|
||||||
|
- REDIS_HOST=plane-redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
- REDIS_URL=${REDIS_URL:-redis://plane-redis:6379/}
|
||||||
|
# Application secret
|
||||||
|
- SECRET_KEY=$SERVICE_PASSWORD_64_SECRETKEY
|
||||||
|
# DATA STORE SETTINGS
|
||||||
|
- USE_MINIO=${USE_MINIO:-1}
|
||||||
|
- AWS_REGION=${AWS_REGION}
|
||||||
|
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
|
||||||
|
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
|
||||||
|
- AWS_S3_ENDPOINT_URL=${AWS_S3_ENDPOINT_URL:-http://plane-minio:9000}
|
||||||
|
- AWS_S3_BUCKET_NAME=${AWS_S3_BUCKET_NAME:-uploads}
|
||||||
|
- MINIO_ROOT_USER=$SERVICE_USER_MINIO
|
||||||
|
- MINIO_ROOT_PASSWORD=$SERVICE_PASSWORD_MINIO
|
||||||
|
- BUCKET_NAME=${BUCKET_NAME:-uploads}
|
||||||
|
- FILE_SIZE_LIMIT=${FILE_SIZE_LIMIT:-5242880}
|
||||||
|
# Admin and Space URLs
|
||||||
|
- ADMIN_BASE_URL=${ADMIN_BASE_URL}
|
||||||
|
- SPACE_BASE_URL=${SPACE_BASE_URL}
|
||||||
|
- APP_BASE_URL=${APP_BASE_URL}
|
||||||
|
|
||||||
|
services:
|
||||||
|
proxy:
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_PLANE
|
||||||
|
- FILE_SIZE_LIMIT=${FILE_SIZE_LIMIT:-5242880}
|
||||||
|
image: makeplane/plane-proxy:stable
|
||||||
|
depends_on:
|
||||||
|
- web
|
||||||
|
- api
|
||||||
|
- space
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
|
||||||
|
web:
|
||||||
|
<<: *app-env
|
||||||
|
image: makeplane/plane-frontend:stable
|
||||||
|
command: node web/server.js web
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- worker
|
||||||
|
healthcheck:
|
||||||
|
test: "wget -qO- http://`hostname`:3000"
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
space:
|
||||||
|
<<: *app-env
|
||||||
|
image: makeplane/plane-space:stable
|
||||||
|
command: node space/server.js space
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- worker
|
||||||
|
- web
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "echo", "hey whats up"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
|
||||||
|
admin:
|
||||||
|
<<: *app-env
|
||||||
|
image: makeplane/plane-admin:stable
|
||||||
|
command: node admin/server.js admin
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- web
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "echo", "hey whats up"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
|
||||||
|
api:
|
||||||
|
<<: *app-env
|
||||||
|
image: makeplane/plane-backend:stable
|
||||||
|
command: ./bin/docker-entrypoint-api.sh
|
||||||
|
volumes:
|
||||||
|
- logs_api:/code/plane/logs
|
||||||
|
depends_on:
|
||||||
|
- plane-db
|
||||||
|
- plane-redis
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "echo", "hey whats up"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
|
||||||
|
worker:
|
||||||
|
<<: *app-env
|
||||||
|
image: makeplane/plane-backend:stable
|
||||||
|
command: ./bin/docker-entrypoint-worker.sh
|
||||||
|
volumes:
|
||||||
|
- logs_worker:/code/plane/logs
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- plane-db
|
||||||
|
- plane-redis
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "echo", "hey whats up"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
|
||||||
|
beat-worker:
|
||||||
|
<<: *app-env
|
||||||
|
image: makeplane/plane-backend:stable
|
||||||
|
command: ./bin/docker-entrypoint-beat.sh
|
||||||
|
volumes:
|
||||||
|
- logs_beat-worker:/code/plane/logs
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
- plane-db
|
||||||
|
- plane-redis
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "echo", "hey whats up"]
|
||||||
|
interval: 2s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 15
|
||||||
|
|
||||||
|
migrator:
|
||||||
|
<<: *app-env
|
||||||
|
image: makeplane/plane-backend:stable
|
||||||
|
restart: "no"
|
||||||
|
command: ./bin/docker-entrypoint-migrator.sh
|
||||||
|
volumes:
|
||||||
|
- logs_migrator:/code/plane/logs
|
||||||
|
depends_on:
|
||||||
|
- plane-db
|
||||||
|
- plane-redis
|
||||||
|
|
||||||
|
plane-db:
|
||||||
|
<<: *app-env
|
||||||
|
image: postgres:15.5-alpine
|
||||||
|
command: postgres -c 'max_connections=1000'
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
plane-redis:
|
||||||
|
<<: *app-env
|
||||||
|
image: valkey/valkey:7.2.5-alpine
|
||||||
|
volumes:
|
||||||
|
- redisdata:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
plane-minio:
|
||||||
|
<<: *app-env
|
||||||
|
image: minio/minio:latest
|
||||||
|
command: server /export --console-address ":9090"
|
||||||
|
volumes:
|
||||||
|
- uploads:/export
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mc", "ready", "local"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
@ -53,7 +53,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- minio-data:/data
|
- minio-data:/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
|
test: ["CMD", "mc", "ready", "local"]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
retries: 10
|
retries: 10
|
||||||
|
37
templates/compose/vikunja-with-postgresql.yaml
Normal file
37
templates/compose/vikunja-with-postgresql.yaml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# documentation: https://vikunja.io
|
||||||
|
# slogan: The open-source, self-hostable to-do app. Organize everything, on all platforms.
|
||||||
|
# tags: productivity,todo
|
||||||
|
# logo: svgs/vikunja.svg
|
||||||
|
# port: 3456
|
||||||
|
|
||||||
|
services:
|
||||||
|
vikunja:
|
||||||
|
image: vikunja/vikunja
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_VIKUNJA
|
||||||
|
- VIKUNJA_SERVICE_PUBLICURL=$SERVICE_FQDN_VIKUNJA
|
||||||
|
- VIKUNJA_SERVICE_JWTSECRET=$SERVICE_PASSWORD_JWTSECRET
|
||||||
|
- VIKUNJA_SERVICE_ENABLEREGISTRATION=true
|
||||||
|
- VIKUNJA_DATABASE_TYPE=postgres
|
||||||
|
- VIKUNJA_DATABASE_HOST=postgresql
|
||||||
|
- VIKUNJA_DATABASE_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
|
||||||
|
- VIKUNJA_DATABASE_USER=${SERVICE_USER_POSTGRESQL}
|
||||||
|
- VIKUNJA_DATABASE_DATABASE=${POSTGRESQL_DATABASE}
|
||||||
|
volumes:
|
||||||
|
- vikunja-data:/app/vikunja/
|
||||||
|
depends_on:
|
||||||
|
postgresql:
|
||||||
|
condition: service_healthy
|
||||||
|
postgresql:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
volumes:
|
||||||
|
- vikunja-postgresql-data:/var/lib/postgresql/data
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=${SERVICE_USER_POSTGRESQL}
|
||||||
|
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
|
||||||
|
- POSTGRES_DB=${POSTGRESQL_DATABASE}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
@ -12,10 +12,16 @@ services:
|
|||||||
- VIKUNJA_SERVICE_PUBLICURL=$SERVICE_FQDN_VIKUNJA
|
- VIKUNJA_SERVICE_PUBLICURL=$SERVICE_FQDN_VIKUNJA
|
||||||
- VIKUNJA_SERVICE_JWTSECRET=$SERVICE_PASSWORD_JWTSECRET
|
- VIKUNJA_SERVICE_JWTSECRET=$SERVICE_PASSWORD_JWTSECRET
|
||||||
- VIKUNJA_SERVICE_ENABLEREGISTRATION=true
|
- VIKUNJA_SERVICE_ENABLEREGISTRATION=true
|
||||||
|
- VIKUNJA_DATABASE_PATH=/db/vikunja.db
|
||||||
|
- VIKUNJA_DATABASE_TYPE=sqlite
|
||||||
volumes:
|
volumes:
|
||||||
- vikunja-data:/app/vikunja/
|
- vikunja-data:/app/vikunja/
|
||||||
healthcheck:
|
- vikunja-sqlite-data:/db
|
||||||
test: ["CMD", "wget", "--spider", "http://127.0.0.1:3456"]
|
depends_on:
|
||||||
interval: 5s
|
- init
|
||||||
timeout: 20s
|
init:
|
||||||
retries: 10
|
image: busybox
|
||||||
|
restart: no
|
||||||
|
volumes:
|
||||||
|
- vikunja-sqlite-data:/db
|
||||||
|
command: ["sh", "-c", "touch /db/vikunja.db && chown -R 1000 /db"]
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"coolify": {
|
"coolify": {
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.313"
|
"version": "4.0.0-beta.314"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user