Compare commits

...

63 Commits

Author SHA1 Message Date
Andras Bacsai
c9a52c552b Merge pull request #3389 from coollabsio/next
v4.0.0-beta.333
2024-09-11 14:26:58 +02:00
Andras Bacsai
72f0118506 chore: Add reminder to backup .env file during installation script 2024-09-11 14:26:10 +02:00
Andras Bacsai
bc13ad6b82 chore: Copy .env file to backup location during installation script 2024-09-11 14:25:40 +02:00
Andras Bacsai
b145691e1e chore: Add reminder to backup .env file before running install script again 2024-09-11 14:25:16 +02:00
Andras Bacsai
5d476e3924 chore: Update server check job middleware to use server ID instead of UUID 2024-09-11 14:23:19 +02:00
Andras Bacsai
577927a20b Merge pull request #3386 from coollabsio/fix-#3343
fix: Disable mux_enabled during server validation
2024-09-11 10:23:33 +02:00
Andras Bacsai
409d5ef60e Merge pull request #3379 from peaklabs-dev/fix-#3343
Fix: Onboarding fails if SSH server uses other port than 22 and other onboarding improvements
2024-09-11 10:22:32 +02:00
Andras Bacsai
f1a1deff26 fix: Disable mux_enabled during server validation 2024-09-11 10:21:18 +02:00
Andras Bacsai
9d42a7f146 Merge pull request #3384 from fizikiukas/patch-1
Update Hostinger link in README
2024-09-11 08:50:46 +02:00
Valentinas Čirba
826b64d056 Update README.md 2024-09-11 07:57:16 +03:00
peaklabs-dev
2c9491d81c Fix: Do not change localhost server name on revalidation 2024-09-10 17:43:16 +02:00
peaklabs-dev
d378bb94be Fix: remote servers with port and user 2024-09-10 17:29:53 +02:00
peaklabs-dev
d74cfd09ce Fixes 2024-09-10 17:18:00 +02:00
peaklabs-dev
91c845732e fix set custom port or user during boarding 2024-09-10 16:55:34 +02:00
peaklabs-dev
83698ac8f2 Merge branch 'coollabsio:main' into fix-#3343 2024-09-10 16:35:23 +02:00
Andras Bacsai
f718604ac4 chore: Update .env file with new values 2024-09-10 14:58:26 +02:00
Andras Bacsai
3e188bf947 chore: Copy .env file to .env-{DATE} if it exists 2024-09-10 14:54:22 +02:00
Andras Bacsai
f70160a17c chore: Update version numbers to 4.0.0-beta.333 2024-09-10 14:52:47 +02:00
Andras Bacsai
5722d1a220 Merge pull request #3352 from KalvadTech/alpine_support
Implement support for Alpine Linux
2024-09-10 14:52:25 +02:00
Andras Bacsai
bae9ea79de Merge pull request #3366 from coollabsio/next
v4.0.0-beta.332
2024-09-10 14:41:41 +02:00
peaklabs-dev
f3845ce30a New onboarding error UI and advanced menu 2024-09-10 13:55:58 +02:00
Andras Bacsai
d57c9d8aa0 feat: add elixir finetunes to the deployment job 2024-09-10 12:44:16 +02:00
Andras Bacsai
c7c2924990 fix: Update remoteProcess.php to handle null values in logItem properties 2024-09-10 12:05:10 +02:00
Andras Bacsai
aa30e83f4a fix: delete older versions of the helper image other than the latest one 2024-09-10 11:33:52 +02:00
Andras Bacsai
77455cd444 fix: scp through cloudflare 2024-09-10 10:19:13 +02:00
Andras Bacsai
2777fbc0ec fix: Remove debug statement in shared.php 2024-09-10 08:52:25 +02:00
Andras Bacsai
2c929b300a feat: Expose project description in API response 2024-09-10 08:49:25 +02:00
Andras Bacsai
27ad4441ee formatting 2024-09-10 08:49:20 +02:00
Andras Bacsai
63729c7bbf Merge pull request #3373 from mattstein/api-project-description
feat: Expose project description in API response
2024-09-10 08:49:08 +02:00
Andras Bacsai
1e68444f10 Merge pull request #3374 from Vahor/host-network
fix: don't add `networks` key if `network_mode` is used
2024-09-10 08:42:17 +02:00
Andras Bacsai
f8dfe643f4 chore: Update appwrite.yaml to include OpenSSL key variable assignment 2024-09-10 08:37:57 +02:00
Vahor
66cf6df4b3 skip docker network creation 2024-09-09 23:46:29 +02:00
Vahor
29acc4ee25 fix: don't add networks key if network_mode is used 2024-09-09 23:30:47 +02:00
Matt Stein
f73983e3dd Include project’s description in API response. 2024-09-09 09:44:43 -07:00
Matt Stein
44d417c07e Fix user-facing string case. 2024-09-09 09:38:40 -07:00
Andras Bacsai
1d72f76072 fix: appwrite template + parser 2024-09-09 15:04:51 +02:00
Andras Bacsai
c2f7e85022 Merge pull request #3364 from peaklabs-dev/improve-persist-ssh-sessions
Feat: Implement SSH multiplexing to reduce the number of SSH authentications in remote processes
2024-09-09 11:23:24 +02:00
Andras Bacsai
9e6486fa66 Merge pull request #3367 from peaklabs-dev/default-timezone
Fix: Set a default server timezone
2024-09-09 11:20:10 +02:00
peaklabs-dev
28bcd0023c remove cache 2024-09-09 10:33:57 +02:00
Andras Bacsai
84093afaf6 refactor: Improve environment variable handling in shared.php 2024-09-09 10:16:12 +02:00
Andras Bacsai
40347744e0 chore: Set timeout for ServerCheckJob to 60 seconds 2024-09-09 09:08:43 +02:00
Andras Bacsai
060988d923 fix: reenable overlapping servercheckjob 2024-09-09 09:05:40 +02:00
Andras Bacsai
b093c9757c Merge branch 'next' into improve-persist-ssh-sessions 2024-09-09 08:30:04 +02:00
Loïc Tosser
25976a4870 Merge branch 'next' into alpine_support 2024-09-09 08:48:36 +04:00
peaklabs-dev
4f9e1a3e5e Feat: Cleanup stale multiplexing connections 2024-09-08 19:37:00 +02:00
peaklabs-dev
c8218e6901 Fix: Enabel mux 2024-09-08 19:15:37 +02:00
peaklabs-dev
cc10d08a7c Feat: Implement SSH Multiplexing 2024-09-08 18:13:00 +02:00
peaklabs-dev
e5a980d544 Merge pull request #3361 from coollabsio/main
merge main into next
2024-09-08 15:33:59 +02:00
peaklabs-dev
59c7f2cb56 Fix: Set a default server timezone 2024-09-08 15:24:27 +02:00
Andras Bacsai
d2a306dab9 refactor: Skip returning volume if driver type is cifs or nfs 2024-09-08 13:53:20 +02:00
Andras Bacsai
681a745fc7 chore: Update coolify-helper.yml to include "next" branch in push trigger 2024-09-08 13:09:14 +02:00
Andras Bacsai
abb6655fef chore: Update versions.json to version 1.0.1 2024-09-08 12:42:46 +02:00
Andras Bacsai
aa586a5677 chore: Update docker cleanup schedule to run daily at midnight 2024-09-08 12:40:53 +02:00
Andras Bacsai
87ee3c511c chore: Update docker image pruning command to exclude managed images 2024-09-08 12:38:22 +02:00
Andras Bacsai
a17daf96be chore: Add coolify.managed=true label to Docker image builds 2024-09-08 12:38:16 +02:00
Andras Bacsai
a419496066 testing label 2024-09-08 12:35:11 +02:00
Andras Bacsai
c668d2d1ff chore: Update DATABASE_URL in plunk.yaml to use plunk database 2024-09-07 20:59:51 +02:00
Andras Bacsai
4611332a8f newparser parser parsing parser parse 2024-09-07 20:57:56 +02:00
Andras Bacsai
8b3eed5895 chore: Update version to 4.0.0-beta.332 2024-09-07 20:56:56 +02:00
Andras Bacsai
9861ad4045 refactor: Update cleanup schedule to run daily at midnight 2024-09-07 20:56:52 +02:00
Andras Bacsai
5fb560dbbf chore: Update versions.json and sentry.php to 4.0.0-beta.332 2024-09-07 20:56:26 +02:00
Loïc Tosser
6b475cc1bf refactor: Improve handling of environment variable merging in upgrade script 2024-09-07 11:00:42 +04:00
Loïc Tosser
5ef2d476a4 Implementing support for Alpine Linux 2024-09-07 10:35:26 +04:00
43 changed files with 1773 additions and 1302 deletions

View File

@@ -38,6 +38,8 @@ jobs:
platforms: linux/amd64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
labels: |
coolify.managed=true
aarch64:
runs-on: [ self-hosted, arm64 ]
permissions:
@@ -64,6 +66,8 @@ jobs:
platforms: linux/aarch64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
labels: |
coolify.managed=true
merge-manifest:
runs-on: ubuntu-latest
permissions:
@@ -94,3 +98,4 @@ jobs:
if: always()
with:
webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }}

View File

@@ -2,7 +2,7 @@ name: Coolify Helper Image (v4)
on:
push:
branches: [ "main" ]
branches: [ "main", "next" ]
paths:
- .github/workflows/coolify-helper.yml
- docker/coolify-helper/Dockerfile
@@ -38,6 +38,8 @@ jobs:
platforms: linux/amd64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
labels: |
coolify.managed=true
aarch64:
runs-on: [ self-hosted, arm64 ]
permissions:
@@ -64,6 +66,8 @@ jobs:
platforms: linux/aarch64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
labels: |
coolify.managed=true
merge-manifest:
runs-on: ubuntu-latest
permissions:

View File

@@ -54,7 +54,7 @@ Special thanks to our biggest sponsors!
* [Latitude](https://latitude.sh/?ref=coolify.io) - A cloud computing platform offering bare metal servers and cloud instances for developers and businesses.
* [Brand Dev](https://brand.dev/?ref=coolify.io) - A web development agency specializing in creating custom digital experiences and brand identities.
* [Jobscollider](https://jobscollider.com/remote-jobs?ref=coolify.io) - A job search platform connecting professionals with remote work opportunities across various industries.
* [Hostinger](https://hostinger.com?ref=coolify.io) - A web hosting provider offering affordable hosting solutions, domain registration, and website building tools.
* [Hostinger](https://www.hostinger.com/vps/coolify-hosting?ref=coolify.io) - A web hosting provider offering affordable hosting solutions, domain registration, and website building tools.
* [Glueops](https://www.glueops.dev/?ref=coolify.io) - A DevOps consulting company providing infrastructure automation and cloud optimization services.
* [Ubicloud](https://ubicloud.com/?ref=coolify.io) - An open-source alternative to hyperscale cloud providers, offering high-performance cloud computing services.
* [Juxtdigital](https://juxtdigital.dev/?ref=coolify.io) - A digital agency offering web development, design, and digital marketing services for businesses.

View File

@@ -2,6 +2,7 @@
namespace App\Actions\Server;
use App\Models\InstanceSettings;
use App\Models\Server;
use Lorisleiva\Actions\Concerns\AsAction;
@@ -21,10 +22,16 @@ class CleanupDocker
private function getCommands(): array
{
$settings = InstanceSettings::get();
$helperImageVersion = data_get($settings, 'helper_version');
$helperImage = config('coolify.helper_image');
$helperImageWithVersion = config('coolify.helper_image').':'.$helperImageVersion;
$commonCommands = [
'docker container prune -f --filter "label=coolify.managed=true"',
'docker image prune -af',
'docker image prune -af --filter "label!=coolify.managed=true"',
'docker builder prune -af',
"docker images --filter before=$helperImageWithVersion --filter reference=$helperImage | grep $helperImage | awk '{print $3}' | xargs -r docker rmi",
];
return $commonCommands;

View File

@@ -16,8 +16,10 @@ class StartService
$service->saveComposeConfigs();
$commands[] = 'cd '.$service->workdir();
$commands[] = "echo 'Saved configuration files to {$service->workdir()}.'";
$commands[] = "echo 'Creating Docker network.'";
$commands[] = "docker network inspect $service->uuid >/dev/null 2>&1 || docker network create --attachable $service->uuid";
if($service->networks()->count() > 0){
$commands[] = "echo 'Creating Docker network.'";
$commands[] = "docker network inspect $service->uuid >/dev/null 2>&1 || docker network create --attachable $service->uuid";
}
$commands[] = 'echo Starting service.';
$commands[] = "echo 'Pulling images.'";
$commands[] = 'docker compose pull';

View File

@@ -4,6 +4,7 @@ namespace App\Console;
use App\Jobs\CheckForUpdatesJob;
use App\Jobs\CleanupInstanceStuffsJob;
use App\Jobs\CleanupStaleMultiplexedConnections;
use App\Jobs\DatabaseBackupJob;
use App\Jobs\DockerCleanupJob;
use App\Jobs\PullHelperImageJob;
@@ -29,7 +30,8 @@ class Kernel extends ConsoleKernel
$this->all_servers = Server::all();
$settings = InstanceSettings::get();
$schedule->command('telescope:prune')->daily();
$schedule->job(new CleanupStaleMultiplexedConnections)->hourly();
if (isDev()) {
// Instance Jobs
$schedule->command('horizon:snapshot')->everyMinute();
@@ -39,6 +41,8 @@ class Kernel extends ConsoleKernel
$this->check_resources($schedule);
$this->check_scheduled_tasks($schedule);
$schedule->command('uploads:clear')->everyTwoMinutes();
$schedule->command('telescope:prune')->daily();
} else {
// Instance Jobs
$schedule->command('horizon:snapshot')->everyFiveMinutes();

View File

@@ -86,7 +86,7 @@ class DeployController extends Controller
],
tags: ['Deployments'],
parameters: [
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Deployment Uuid', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Deployment UUID', schema: new OA\Schema(type: 'string')),
],
responses: [
new OA\Response(
@@ -150,7 +150,7 @@ class DeployController extends Controller
responses: [
new OA\Response(
response: 200,
description: 'Get deployment(s) Uuid\'s',
description: 'Get deployment(s) UUID\'s',
content: [
new OA\MediaType(
mediaType: 'application/json',

View File

@@ -11,7 +11,7 @@ class ProjectController extends Controller
{
#[OA\Get(
summary: 'List',
description: 'list projects.',
description: 'List projects.',
path: '/projects',
operationId: 'list-projects',
security: [
@@ -47,7 +47,7 @@ class ProjectController extends Controller
if (is_null($teamId)) {
return invalidTokenResponse();
}
$projects = Project::whereTeamId($teamId)->select('id', 'name', 'uuid')->get();
$projects = Project::whereTeamId($teamId)->select('id', 'name', 'description', 'uuid')->get();
return response()->json(serializeApiResponse($projects),
);
@@ -55,7 +55,7 @@ class ProjectController extends Controller
#[OA\Get(
summary: 'Get',
description: 'Get project by Uuid.',
description: 'Get project by UUID.',
path: '/projects/{uuid}',
operationId: 'get-project-by-uuid',
security: [
@@ -139,7 +139,7 @@ class ProjectController extends Controller
return invalidTokenResponse();
}
if (! $request->uuid) {
return response()->json(['message' => 'Uuid is required.'], 422);
return response()->json(['message' => 'UUID is required.'], 422);
}
if (! $request->environment_name) {
return response()->json(['message' => 'Environment name is required.'], 422);
@@ -341,7 +341,7 @@ class ProjectController extends Controller
}
$uuid = $request->uuid;
if (! $uuid) {
return response()->json(['message' => 'Uuid is required.'], 422);
return response()->json(['message' => 'UUID is required.'], 422);
}
$project = Project::whereTeamId($teamId)->whereUuid($uuid)->first();
@@ -417,7 +417,7 @@ class ProjectController extends Controller
}
if (! $request->uuid) {
return response()->json(['message' => 'Uuid is required.'], 422);
return response()->json(['message' => 'UUID is required.'], 422);
}
$project = Project::whereTeamId($teamId)->whereUuid($request->uuid)->first();
if (! $project) {

View File

@@ -75,7 +75,7 @@ class SecurityController extends Controller
],
tags: ['Private Keys'],
parameters: [
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Private Key Uuid', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Private Key UUID', schema: new OA\Schema(type: 'string')),
],
responses: [
new OA\Response(
@@ -323,7 +323,7 @@ class SecurityController extends Controller
],
tags: ['Private Keys'],
parameters: [
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Private Key Uuid', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Private Key UUID', schema: new OA\Schema(type: 'string')),
],
responses: [
new OA\Response(

View File

@@ -107,7 +107,7 @@ class ServersController extends Controller
],
tags: ['Servers'],
parameters: [
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s Uuid', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s UUID', schema: new OA\Schema(type: 'string')),
],
responses: [
new OA\Response(
@@ -185,7 +185,7 @@ class ServersController extends Controller
],
tags: ['Servers'],
parameters: [
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s Uuid', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s UUID', schema: new OA\Schema(type: 'string')),
],
responses: [
new OA\Response(
@@ -263,7 +263,7 @@ class ServersController extends Controller
],
tags: ['Servers'],
parameters: [
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s Uuid', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Server\'s UUID', schema: new OA\Schema(type: 'string')),
],
responses: [
new OA\Response(

View File

@@ -378,7 +378,7 @@ class ServicesController extends Controller
responses: [
new OA\Response(
response: 200,
description: 'Get a service by Uuid.',
description: 'Get a service by UUID.',
content: [
new OA\MediaType(
mediaType: 'application/json',
@@ -436,7 +436,7 @@ class ServicesController extends Controller
responses: [
new OA\Response(
response: 200,
description: 'Delete a service by Uuid',
description: 'Delete a service by UUID',
content: [
new OA\MediaType(
mediaType: 'application/json',

View File

@@ -1066,15 +1066,55 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
$this->environment_variables = $envs;
}
private function elixir_finetunes()
{
if ($this->pull_request_id === 0) {
$envType = 'environment_variables';
} else {
$envType = 'environment_variables_preview';
}
$mix_env = $this->application->{$envType}->where('key', 'MIX_ENV')->first();
if ($mix_env) {
if ($mix_env->is_build_time === false) {
$this->application_deployment_queue->addLogEntry('MIX_ENV environment variable is not set as build time.', type: 'error');
$this->application_deployment_queue->addLogEntry('Please set MIX_ENV environment variable to be build time variable if you facing any issues with the deployment.', type: 'error');
}
} else {
$this->application_deployment_queue->addLogEntry('MIX_ENV environment variable not found.', type: 'error');
$this->application_deployment_queue->addLogEntry('Please add MIX_ENV environment variable and set it to be build time variable if you facing any issues with the deployment.', type: 'error');
}
$secret_key_base = $this->application->{$envType}->where('key', 'SECRET_KEY_BASE')->first();
if ($secret_key_base) {
if ($secret_key_base->is_build_time === false) {
$this->application_deployment_queue->addLogEntry('SECRET_KEY_BASE environment variable is not set as build time.', type: 'error');
$this->application_deployment_queue->addLogEntry('Please set SECRET_KEY_BASE environment variable to be build time variable if you facing any issues with the deployment.', type: 'error');
}
} else {
$this->application_deployment_queue->addLogEntry('SECRET_KEY_BASE environment variable not found.', type: 'error');
$this->application_deployment_queue->addLogEntry('Please add SECRET_KEY_BASE environment variable and set it to be build time variable if you facing any issues with the deployment.', type: 'error');
}
$database_url = $this->application->{$envType}->where('key', 'DATABASE_URL')->first();
if ($database_url) {
if ($database_url->is_build_time === false) {
$this->application_deployment_queue->addLogEntry('DATABASE_URL environment variable is not set as build time.', type: 'error');
$this->application_deployment_queue->addLogEntry('Please set DATABASE_URL environment variable to be build time variable if you facing any issues with the deployment.', type: 'error');
}
} else {
$this->application_deployment_queue->addLogEntry('DATABASE_URL environment variable not found.', type: 'error');
$this->application_deployment_queue->addLogEntry('Please add DATABASE_URL environment variable and set it to be build time variable if you facing any issues with the deployment.', type: 'error');
}
}
private function laravel_finetunes()
{
if ($this->pull_request_id === 0) {
$nixpacks_php_fallback_path = $this->application->environment_variables->where('key', 'NIXPACKS_PHP_FALLBACK_PATH')->first();
$nixpacks_php_root_dir = $this->application->environment_variables->where('key', 'NIXPACKS_PHP_ROOT_DIR')->first();
$envType = 'environment_variables';
} else {
$nixpacks_php_fallback_path = $this->application->environment_variables_preview->where('key', 'NIXPACKS_PHP_FALLBACK_PATH')->first();
$nixpacks_php_root_dir = $this->application->environment_variables_preview->where('key', 'NIXPACKS_PHP_ROOT_DIR')->first();
$envType = 'environment_variables_preview';
}
$nixpacks_php_fallback_path = $this->application->{$envType}->where('key', 'NIXPACKS_PHP_FALLBACK_PATH')->first();
$nixpacks_php_root_dir = $this->application->{$envType}->where('key', 'NIXPACKS_PHP_ROOT_DIR')->first();
if (! $nixpacks_php_fallback_path) {
$nixpacks_php_fallback_path = new EnvironmentVariable;
$nixpacks_php_fallback_path->key = 'NIXPACKS_PHP_FALLBACK_PATH';
@@ -1533,6 +1573,9 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
data_set($parsed, 'variables.NIXPACKS_PHP_FALLBACK_PATH', $variables[0]->value);
data_set($parsed, 'variables.NIXPACKS_PHP_ROOT_DIR', $variables[1]->value);
}
if ($this->nixpacks_type === 'elixir') {
$this->elixir_finetunes();
}
$this->nixpacks_plan = json_encode($parsed, JSON_PRETTY_PRINT);
$this->application_deployment_queue->addLogEntry("Final Nixpacks plan: {$this->nixpacks_plan}", hidden: true);
if ($this->nixpacks_type === 'rust') {

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Jobs;
use App\Models\Server;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Process;
class CleanupStaleMultiplexedConnections implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
Server::chunk(100, function ($servers) {
foreach ($servers as $server) {
$this->cleanupStaleConnection($server);
}
});
}
private function cleanupStaleConnection(Server $server)
{
$muxSocket = "/tmp/mux_{$server->id}";
$checkCommand = "ssh -O check -o ControlPath=$muxSocket {$server->user}@{$server->ip} 2>/dev/null";
$checkProcess = Process::run($checkCommand);
if ($checkProcess->exitCode() !== 0) {
$closeCommand = "ssh -O exit -o ControlPath=$muxSocket {$server->user}@{$server->ip} 2>/dev/null";
Process::run($closeCommand);
}
}
}

View File

@@ -26,6 +26,8 @@ class ServerCheckJob implements ShouldBeEncrypted, ShouldQueue
public $tries = 3;
public $timeout = 60;
public $containers;
public $applications;
@@ -43,15 +45,15 @@ class ServerCheckJob implements ShouldBeEncrypted, ShouldQueue
public function __construct(public Server $server) {}
// public function middleware(): array
// {
// return [(new WithoutOverlapping($this->server->uuid))];
// }
public function middleware(): array
{
return [(new WithoutOverlapping($this->server->id))];
}
// public function uniqueId(): int
// {
// return $this->server->uuid;
// }
public function uniqueId(): int
{
return $this->server->id;
}
public function handle()
{
@@ -124,7 +126,7 @@ class ServerCheckJob implements ShouldBeEncrypted, ShouldQueue
private function checkLogDrainContainer()
{
if(! $this->server->isLogDrainEnabled()) {
if (! $this->server->isLogDrainEnabled()) {
return;
}
$foundLogDrainContainer = $this->containers->filter(function ($value, $key) {

View File

@@ -73,6 +73,8 @@ class Index extends Component
}
$this->privateKeyName = generate_random_name();
$this->remoteServerName = generate_random_name();
$this->remoteServerPort = $this->remoteServerPort;
$this->remoteServerUser = $this->remoteServerUser;
if (isDev()) {
$this->privateKey = '-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
@@ -154,6 +156,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
$this->servers = Server::ownedByCurrentTeam(['name'])->where('id', '!=', 0)->get();
if ($this->servers->count() > 0) {
$this->selectedExistingServer = $this->servers->first()->id;
$this->updateServerDetails();
$this->currentState = 'select-existing-server';
return;
@@ -173,9 +176,18 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
}
$this->selectedExistingPrivateKey = $this->createdServer->privateKey->id;
$this->serverPublicKey = $this->createdServer->privateKey->publicKey();
$this->updateServerDetails();
$this->currentState = 'validate-server';
}
private function updateServerDetails()
{
if ($this->createdServer) {
$this->remoteServerPort = $this->createdServer->port;
$this->remoteServerUser = $this->createdServer->user;
}
}
public function getProxyType()
{
// Set Default Proxy Type
@@ -235,11 +247,12 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
public function saveServer()
{
$this->validate([
'remoteServerName' => 'required',
'remoteServerHost' => 'required',
'remoteServerName' => 'required|string',
'remoteServerHost' => 'required|string',
'remoteServerPort' => 'required|integer',
'remoteServerUser' => 'required',
'remoteServerUser' => 'required|string',
]);
$this->privateKey = formatPrivateKey($this->privateKey);
$foundServer = Server::whereIp($this->remoteServerHost)->first();
if ($foundServer) {
@@ -277,9 +290,12 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
$this->createdServer->settings()->update([
'is_reachable' => true,
]);
$this->serverReachable = true;
} catch (\Throwable $e) {
$this->serverReachable = false;
$this->createdServer->delete();
$this->createdServer->settings()->update([
'is_reachable' => false,
]);
return handleError(error: $e, livewire: $this);
}
@@ -296,6 +312,10 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
]);
$this->getProxyType();
} catch (\Throwable $e) {
$this->createdServer->settings()->update([
'is_usable' => false,
]);
return handleError(error: $e, livewire: $this);
}
}
@@ -349,6 +369,21 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
);
}
public function saveAndValidateServer()
{
$this->validate([
'remoteServerPort' => 'required|integer|min:1|max:65535',
'remoteServerUser' => 'required|string',
]);
$this->createdServer->update([
'port' => $this->remoteServerPort,
'user' => $this->remoteServerUser,
'timezone' => 'UTC',
]);
$this->validateServer();
}
private function createNewPrivateKey()
{
$this->privateKeyName = generate_random_name();

View File

@@ -11,6 +11,7 @@ use OpenApi\Attributes as OA;
'id' => ['type' => 'integer'],
'uuid' => ['type' => 'string'],
'name' => ['type' => 'string'],
'description' => ['type' => 'string'],
'environments' => new OA\Property(
property: 'environments',
type: 'array',

View File

@@ -112,6 +112,16 @@ class Server extends BaseModel
'proxy',
];
protected $fillable = [
'name',
'ip',
'port',
'user',
'description',
'private_key_id',
'team_id',
];
protected $guarded = [];
public static function isReachable()

View File

@@ -1016,10 +1016,20 @@ class Service extends BaseModel
$commands[] = 'rm -f .env || true';
$envs_from_coolify = $this->environment_variables()->get();
foreach ($envs_from_coolify as $env) {
$sorted = $envs_from_coolify->sortBy(function ($env) {
if (str($env->key)->startsWith('SERVICE_')) {
return 1;
}
if (str($env->value)->startsWith('$SERVICE_') || str($env->value)->startsWith('${SERVICE_')) {
return 2;
}
return 3;
});
foreach ($sorted as $env) {
$commands[] = "echo '{$env->key}={$env->real_value}' >> .env";
}
if ($envs_from_coolify->count() === 0) {
if ($sorted->count() === 0) {
$commands[] = 'touch .env';
}
instant_remote_process($commands, $this->server);

View File

@@ -46,6 +46,7 @@ const SUPPORTED_OS = [
'centos fedora rhel ol rocky amzn almalinux',
'sles opensuse-leap opensuse-tumbleweed',
'arch',
'alpine',
];
const SHARED_VARIABLE_TYPES = ['team', 'project', 'environment'];

View File

@@ -95,8 +95,26 @@ function generateScpCommand(Server $server, string $source, string $dest)
$timeout = config('constants.ssh.command_timeout');
$connectionTimeout = config('constants.ssh.connection_timeout');
$serverInterval = config('constants.ssh.server_interval');
$muxPersistTime = config('constants.ssh.mux_persist_time');
$scp_command = "timeout $timeout scp ";
// Check if multiplexing is enabled
$muxEnabled = config('constants.ssh.mux_enabled', true);
// ray('SSH Multiplexing Enabled:', $muxEnabled)->blue();
if ($muxEnabled) {
// Always use multiplexing when enabled
$muxSocket = "/var/www/html/storage/app/ssh/mux/{$server->muxFilename()}";
$scp_command .= "-o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} ";
ensureMultiplexedConnection($server);
// ray('Using SSH Multiplexing')->green();
} else {
// ray('Not using SSH Multiplexing')->red();
}
if (data_get($server, 'settings.is_cloudflare_tunnel')) {
$scp_command .= '-o ProxyCommand="/usr/local/bin/cloudflared access ssh --hostname %h" ';
}
$scp_command .= "-i {$privateKeyLocation} "
.'-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '
.'-o PasswordAuthentication=no '
@@ -145,9 +163,20 @@ function generateSshCommand(Server $server, string $command)
$ssh_command = "timeout $timeout ssh ";
if (config('coolify.mux_enabled') && config('coolify.is_windows_docker_desktop') == false) {
$ssh_command .= "-o ControlMaster=auto -o ControlPersist={$muxPersistTime} -o ControlPath=/var/www/html/storage/app/ssh/mux/{$server->muxFilename()} ";
// Check if multiplexing is enabled
$muxEnabled = config('constants.ssh.mux_enabled', true);
// ray('SSH Multiplexing Enabled:', $muxEnabled)->blue();
if ($muxEnabled) {
// Always use multiplexing when enabled
$muxSocket = "/var/www/html/storage/app/ssh/mux/{$server->muxFilename()}";
$ssh_command .= "-o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} ";
ensureMultiplexedConnection($server);
// ray('Using SSH Multiplexing')->green();
} else {
// ray('Not using SSH Multiplexing')->red();
}
if (data_get($server, 'settings.is_cloudflare_tunnel')) {
$ssh_command .= '-o ProxyCommand="/usr/local/bin/cloudflared access ssh --hostname %h" ';
}
@@ -169,8 +198,98 @@ function generateSshCommand(Server $server, string $command)
return $ssh_command;
}
function ensureMultiplexedConnection(Server $server)
{
static $ensuredConnections = [];
if (isset($ensuredConnections[$server->id])) {
if (! shouldResetMultiplexedConnection($server)) {
// ray('Using Existing Multiplexed Connection')->green();
return;
}
}
$muxSocket = "/var/www/html/storage/app/ssh/mux/{$server->muxFilename()}";
$checkCommand = "ssh -O check -o ControlPath=$muxSocket {$server->user}@{$server->ip} 2>/dev/null";
$process = Process::run($checkCommand);
if ($process->exitCode() === 0) {
// ray('Existing Multiplexed Connection is Valid')->green();
$ensuredConnections[$server->id] = [
'timestamp' => now(),
'muxSocket' => $muxSocket,
];
return;
}
// ray('Establishing New Multiplexed Connection')->orange();
$privateKeyLocation = savePrivateKeyToFs($server);
$connectionTimeout = config('constants.ssh.connection_timeout');
$serverInterval = config('constants.ssh.server_interval');
$muxPersistTime = config('constants.ssh.mux_persist_time');
$establishCommand = "ssh -fNM -o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} "
."-i {$privateKeyLocation} "
.'-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null '
.'-o PasswordAuthentication=no '
."-o ConnectTimeout=$connectionTimeout "
."-o ServerAliveInterval=$serverInterval "
.'-o RequestTTY=no '
.'-o LogLevel=ERROR '
."-p {$server->port} "
."{$server->user}@{$server->ip}";
$establishProcess = Process::run($establishCommand);
if ($establishProcess->exitCode() !== 0) {
throw new \RuntimeException('Failed to establish multiplexed connection: '.$establishProcess->errorOutput());
}
$ensuredConnections[$server->id] = [
'timestamp' => now(),
'muxSocket' => $muxSocket,
];
// ray('Established New Multiplexed Connection')->green();
}
function shouldResetMultiplexedConnection(Server $server)
{
static $ensuredConnections = [];
if (! isset($ensuredConnections[$server->id])) {
return true;
}
$lastEnsured = $ensuredConnections[$server->id]['timestamp'];
$muxPersistTime = config('constants.ssh.mux_persist_time');
$resetInterval = strtotime($muxPersistTime) - time();
return $lastEnsured->addSeconds($resetInterval)->isPast();
}
function resetMultiplexedConnection(Server $server)
{
static $ensuredConnections = [];
if (isset($ensuredConnections[$server->id])) {
$muxSocket = $ensuredConnections[$server->id]['muxSocket'];
$closeCommand = "ssh -O exit -o ControlPath=$muxSocket {$server->user}@{$server->ip}";
Process::run($closeCommand);
unset($ensuredConnections[$server->id]);
}
}
function instant_remote_process(Collection|array $command, Server $server, bool $throwError = true, bool $no_sudo = false): ?string
{
static $processCount = 0;
$processCount++;
$timeout = config('constants.ssh.command_timeout');
if ($command instanceof Collection) {
$command = $command->toArray();
@@ -179,10 +298,18 @@ function instant_remote_process(Collection|array $command, Server $server, bool
$command = parseCommandsByLineForSudo(collect($command), $server);
}
$command_string = implode("\n", $command);
$ssh_command = generateSshCommand($server, $command_string, $no_sudo);
$process = Process::timeout($timeout)->run($ssh_command);
$start_time = microtime(true);
$sshCommand = generateSshCommand($server, $command_string);
$process = Process::timeout($timeout)->run($sshCommand);
$end_time = microtime(true);
$execution_time = ($end_time - $start_time) * 1000; // Convert to milliseconds
// ray('SSH command execution time:', $execution_time.' ms')->orange();
$output = trim($process->output());
$exitCode = $process->exitCode();
if ($exitCode !== 0) {
if (! $throwError) {
return null;
@@ -222,7 +349,6 @@ function decode_remote_command_output(?ApplicationDeploymentQueue $application_d
if (is_null($application_deployment_queue)) {
return collect([]);
}
// ray(data_get($application_deployment_queue, 'logs'));
try {
$decoded = json_decode(
data_get($application_deployment_queue, 'logs'),
@@ -232,7 +358,6 @@ function decode_remote_command_output(?ApplicationDeploymentQueue $application_d
} catch (\JsonException $exception) {
return collect([]);
}
// ray($decoded );
$seenCommands = collect();
$formatted = collect($decoded);
if (! $is_debug_enabled) {
@@ -246,35 +371,35 @@ function decode_remote_command_output(?ApplicationDeploymentQueue $application_d
return $i;
})
->reduce(function ($deploymentLogLines, $logItem) use ($seenCommands) {
$command = $logItem['command'];
$isStderr = $logItem['type'] === 'stderr';
$command = data_get($logItem, 'command');
$isStderr = data_get($logItem, 'type') === 'stderr';
$isNewCommand = ! is_null($command) && ! $seenCommands->first(function ($seenCommand) use ($logItem) {
return $seenCommand['command'] === $logItem['command'] && $seenCommand['batch'] === $logItem['batch'];
return data_get($seenCommand, 'command') === data_get($logItem, 'command') && data_get($seenCommand, 'batch') === data_get($logItem, 'batch');
});
if ($isNewCommand) {
$deploymentLogLines->push([
'line' => $command,
'timestamp' => $logItem['timestamp'],
'timestamp' => data_get($logItem, 'timestamp'),
'stderr' => $isStderr,
'hidden' => $logItem['hidden'],
'hidden' => data_get($logItem, 'hidden'),
'command' => true,
]);
$seenCommands->push([
'command' => $command,
'batch' => $logItem['batch'],
'batch' => data_get($logItem, 'batch'),
]);
}
$lines = explode(PHP_EOL, $logItem['output']);
$lines = explode(PHP_EOL, data_get($logItem, 'output'));
foreach ($lines as $line) {
$deploymentLogLines->push([
'line' => $line,
'timestamp' => $logItem['timestamp'],
'timestamp' => data_get($logItem, 'timestamp'),
'stderr' => $isStderr,
'hidden' => $logItem['hidden'],
'hidden' => data_get($logItem, 'hidden'),
]);
}
@@ -293,6 +418,10 @@ function remove_mux_and_private_key(Server $server)
{
$muxFilename = $server->muxFilename();
$privateKeyLocation = savePrivateKeyToFs($server);
$closeCommand = "ssh -O exit -o ControlPath=/var/www/html/storage/app/ssh/mux/{$muxFilename} {$server->user}@{$server->ip}";
Process::run($closeCommand);
Storage::disk('ssh-mux')->delete($muxFilename);
Storage::disk('ssh-keys')->delete($privateKeyLocation);
}
@@ -302,7 +431,10 @@ function refresh_server_connection(?PrivateKey $private_key = null)
return;
}
foreach ($private_key->servers as $server) {
Storage::disk('ssh-mux')->delete($server->muxFilename());
$muxFilename = $server->muxFilename();
$closeCommand = "ssh -O exit -o ControlPath=/var/www/html/storage/app/ssh/mux/{$muxFilename} {$server->user}@{$server->ip}";
Process::run($closeCommand);
Storage::disk('ssh-mux')->delete($muxFilename);
}
}
@@ -312,24 +444,17 @@ function checkRequiredCommands(Server $server)
foreach ($commands as $command) {
$commandFound = instant_remote_process(["docker run --rm --privileged --net=host --pid=host --ipc=host --volume /:/host busybox chroot /host bash -c 'command -v {$command}'"], $server, false);
if ($commandFound) {
ray($command.' found');
continue;
}
try {
instant_remote_process(["docker run --rm --privileged --net=host --pid=host --ipc=host --volume /:/host busybox chroot /host bash -c 'apt update && apt install -y {$command}'"], $server);
} catch (\Throwable $e) {
ray('could not install '.$command);
ray($e);
break;
}
$commandFound = instant_remote_process(["docker run --rm --privileged --net=host --pid=host --ipc=host --volume /:/host busybox chroot /host bash -c 'command -v {$command}'"], $server, false);
if ($commandFound) {
ray($command.' found');
continue;
}
ray('could not install '.$command);
break;
}
}

View File

@@ -4,6 +4,7 @@ use App\Models\Application;
use App\Models\EnvironmentVariable;
use App\Models\ServiceApplication;
use App\Models\ServiceDatabase;
use Illuminate\Support\Stringable;
use Spatie\Url\Url;
use Symfony\Component\Yaml\Yaml;
@@ -15,9 +16,9 @@ function collectRegex(string $name)
{
return "/{$name}\w+/";
}
function replaceVariables($variable)
function replaceVariables(string $variable): Stringable
{
return $variable->before('}')->replaceFirst('$', '')->replaceFirst('{', '');
return str($variable)->before('}')->replaceFirst('$', '')->replaceFirst('{', '');
}
function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase|Application $oneService, bool $isInit = false)

View File

@@ -1866,7 +1866,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
'key' => $key,
'service_id' => $resource->id,
])->first();
$value = str(replaceVariables($value));
$value = replaceVariables($value);
$key = $value;
if ($value->startsWith('SERVICE_')) {
$foundEnv = EnvironmentVariable::where([
@@ -2627,7 +2627,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
'application_id' => $resource->id,
'is_preview' => false,
])->first();
$value = str(replaceVariables($value));
$value = replaceVariables($value);
$key = $value;
if ($value->startsWith('SERVICE_')) {
$foundEnv = EnvironmentVariable::where([
@@ -2864,6 +2864,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
return collect($finalServices);
}
}
function newParser(Application|Service $resource, int $pull_request_id = 0, ?int $preview_id = null): Collection
{
$isApplication = $resource instanceof Application;
@@ -2920,6 +2921,182 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
}
$parsedServices = collect([]);
ray()->clearAll();
$allMagicEnvironments = collect([]);
foreach ($services as $serviceName => $service) {
$magicEnvironments = collect([]);
$image = data_get_str($service, 'image');
$environment = collect(data_get($service, 'environment', []));
$buildArgs = collect(data_get($service, 'build.args', []));
$environment = $environment->merge($buildArgs);
$isDatabase = isDatabaseImage(data_get_str($service, 'image'));
if ($isService) {
if ($isDatabase) {
$savedService = ServiceDatabase::firstOrCreate([
'name' => $serviceName,
'image' => $image,
'service_id' => $resource->id,
]);
} else {
$savedService = ServiceApplication::firstOrCreate([
'name' => $serviceName,
'image' => $image,
'service_id' => $resource->id,
]);
}
$environment = collect(data_get($service, 'environment', []));
$buildArgs = collect(data_get($service, 'build.args', []));
$environment = $environment->merge($buildArgs);
// convert environment variables to one format
$environment = convertComposeEnvironmentToArray($environment);
// Add Coolify defined environments
$allEnvironments = $resource->environment_variables()->get(['key', 'value']);
$allEnvironments = $allEnvironments->mapWithKeys(function ($item) {
return [$item['key'] => $item['value']];
});
// filter and add magic environments
foreach ($environment as $key => $value) {
// Get all SERVICE_ variables from keys and values
$key = str($key);
$value = str($value);
$regex = '/\$(\{?([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)\}?)/';
preg_match_all($regex, $value, $valueMatches);
if (count($valueMatches[1]) > 0) {
foreach ($valueMatches[1] as $match) {
$match = replaceVariables($match);
if ($match->startsWith('SERVICE_')) {
if ($magicEnvironments->has($match->value())) {
continue;
}
$magicEnvironments->put($match->value(), '');
}
}
}
// Get magic environments where we need to preset the FQDN
if ($key->startsWith('SERVICE_FQDN_')) {
// SERVICE_FQDN_APP or SERVICE_FQDN_APP_3000
$fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value();
if ($isApplication) {
$fqdn = generateFqdn($server, "{$resource->name}-$uuid");
} elseif ($isService) {
if ($fqdnFor) {
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
} else {
$fqdn = generateFqdn($server, "{$savedService->name}-$uuid");
}
}
if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) {
$path = $value->value();
if ($path !== '/') {
$fqdn = "$fqdn$path";
}
}
if ($isApplication && is_null($resource->fqdn)) {
data_forget($resource, 'environment_variables');
data_forget($resource, 'environment_variables_preview');
$resource->fqdn = $fqdn;
$resource->save();
} elseif ($isService && is_null($savedService->fqdn)) {
$savedService->fqdn = $fqdn;
$savedService->save();
}
if (substr_count(str($key)->value(), '_') === 2) {
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
'key' => $key->value(),
$nameOfId => $resource->id,
], [
'value' => $fqdn,
'is_build_time' => false,
'is_preview' => false,
]);
}
if (substr_count(str($key)->value(), '_') === 3) {
$newKey = str($key)->beforeLast('_');
$resource->environment_variables()->where('key', $newKey->value())->where($nameOfId, $resource->id)->firstOrCreate([
'key' => $newKey->value(),
$nameOfId => $resource->id,
], [
'value' => $fqdn,
'is_build_time' => false,
'is_preview' => false,
]);
}
}
}
$allMagicEnvironments = $allMagicEnvironments->merge($magicEnvironments);
if ($magicEnvironments->count() > 0) {
foreach ($magicEnvironments as $key => $value) {
$key = str($key);
$value = replaceVariables($value);
$command = $key->after('SERVICE_')->before('_');
$found = $resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->first();
if ($found) {
continue;
}
if ($command->value() === 'FQDN') {
$fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value();
if (str($fqdnFor)->contains('_')) {
$fqdnFor = str($fqdnFor)->before('_');
}
if ($isApplication) {
$fqdn = generateFqdn($server, "{$resource->name}-$uuid");
} elseif ($isService) {
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
}
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
'key' => $key->value(),
$nameOfId => $resource->id,
], [
'value' => $fqdn,
'is_build_time' => false,
'is_preview' => false,
]);
} elseif ($command->value() === 'URL') {
$fqdnFor = $key->after('SERVICE_URL_')->lower()->value();
if (str($fqdnFor)->contains('_')) {
$fqdnFor = str($fqdnFor)->before('_');
}
if ($isApplication) {
$fqdn = generateFqdn($server, "{$resource->name}-$uuid");
} elseif ($isService) {
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
}
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
'key' => $key->value(),
$nameOfId => $resource->id,
], [
'value' => $fqdn,
'is_build_time' => false,
'is_preview' => false,
]);
} else {
$value = generateEnvValue($command, $resource);
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
'key' => $key->value(),
$nameOfId => $resource->id,
], [
'value' => $value,
'is_build_time' => false,
'is_preview' => false,
]);
}
}
}
}
}
// Parse the rest of the services
foreach ($services as $serviceName => $service) {
$image = data_get_str($service, 'image');
$restart = data_get_str($service, 'restart', RESTART_MODE);
@@ -2932,12 +3109,17 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
}
$volumes = collect(data_get($service, 'volumes', []));
$networks = collect(data_get($service, 'networks', []));
$use_network_mode = data_get($service, 'network_mode') !== null;
$depends_on = collect(data_get($service, 'depends_on', []));
$labels = collect(data_get($service, 'labels', []));
$environment = collect(data_get($service, 'environment', []));
$ports = collect(data_get($service, 'ports', []));
$buildArgs = collect(data_get($service, 'build.args', []));
$environment = $environment->merge($buildArgs);
$environment = convertComposeEnvironmentToArray($environment);
$coolifyEnvironments = collect([]);
$isDatabase = isDatabaseImage(data_get_str($service, 'image'));
$volumesParsed = collect([]);
@@ -3069,10 +3251,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
if ($topLevel->get('volumes')->has($source->value())) {
$temp = $topLevel->get('volumes')->get($source->value());
if (data_get($temp, 'driver_opts.type') === 'cifs') {
return $volume;
continue;
}
if (data_get($temp, 'driver_opts.type') === 'nfs') {
return $volume;
continue;
}
}
$slugWithoutUuid = Str::slug($source, '-');
@@ -3127,32 +3309,34 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$depends_on = $newDependsOn;
}
}
if ($topLevel->get('networks')?->count() > 0) {
foreach ($topLevel->get('networks') as $networkName => $network) {
if ($networkName === 'default') {
continue;
}
// ignore aliases
if ($network['aliases'] ?? false) {
continue;
}
$networkExists = $networks->contains(function ($value, $key) use ($networkName) {
return $value == $networkName || $key == $networkName;
});
if (! $networkExists) {
$networks->put($networkName, null);
if (! $use_network_mode) {
if ($topLevel->get('networks')?->count() > 0) {
foreach ($topLevel->get('networks') as $networkName => $network) {
if ($networkName === 'default') {
continue;
}
// ignore aliases
if ($network['aliases'] ?? false) {
continue;
}
$networkExists = $networks->contains(function ($value, $key) use ($networkName) {
return $value == $networkName || $key == $networkName;
});
if (! $networkExists) {
$networks->put($networkName, null);
}
}
}
}
$baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) {
return $value == $baseNetwork;
});
if (! $baseNetworkExists) {
foreach ($baseNetwork as $network) {
$topLevel->get('networks')->put($network, [
'name' => $network,
'external' => true,
]);
$baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) {
return $value == $baseNetwork;
});
if (! $baseNetworkExists) {
foreach ($baseNetwork as $network) {
$topLevel->get('networks')->put($network, [
'name' => $network,
'external' => true,
]);
}
}
}
@@ -3178,203 +3362,46 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$networks_temp = collect();
foreach ($networks as $key => $network) {
if (gettype($network) === 'string') {
// networks:
// - appwrite
if (! $use_network_mode) {
foreach ($networks as $key => $network) {
if (gettype($network) === 'string') {
// networks:
// - appwrite
$networks_temp->put($network, null);
} elseif (gettype($network) === 'array') {
// networks:
// default:
// ipv4_address: 192.168.203.254
$networks_temp->put($key, $network);
}
}
foreach ($baseNetwork as $key => $network) {
$networks_temp->put($network, null);
} elseif (gettype($network) === 'array') {
// networks:
// default:
// ipv4_address: 192.168.203.254
$networks_temp->put($key, $network);
}
}
foreach ($baseNetwork as $key => $network) {
$networks_temp->put($network, null);
}
if ($isApplication) {
if (data_get($resource, 'settings.connect_to_docker_network')) {
$network = $resource->destination->network;
$networks_temp->put($network, null);
$topLevel->get('networks')->put($network, [
'name' => $network,
'external' => true,
]);
}
}
// convert environment variables to one format
$environment = convertComposeEnvironmentToArray($environment);
// Add Coolify defined environments
$allEnvironments = $resource->environment_variables()->get(['key', 'value']);
$allEnvironments = $allEnvironments->mapWithKeys(function ($item) {
return [$item['key'] => $item['value']];
});
// remove $environment from $allEnvironments
$coolifyDefinedEnvironments = $allEnvironments->diffKeys($environment);
// filter magic environments
$magicEnvironments = $environment->filter(function ($value, $key) {
$regex = '/\$\{(.*?)\}/';
preg_match_all($regex, $value, $matches);
if (count($matches[1]) > 0) {
foreach ($matches[1] as $match) {
if (str($match)->startsWith('SERVICE_') || str($match)->startsWith('SERVICE_')) {
return $match;
}
}
}
$value = str(replaceVariables(str($value)));
return str($key)->startsWith('SERVICE_') || str($value)->startsWith('SERVICE_');
});
foreach ($environment as $key => $value) {
$regex = '/\$\{(.*?)\}/';
preg_match_all($regex, $value, $matches);
if (count($matches[1]) > 0) {
foreach ($matches[1] as $match) {
if (str($match)->startsWith('SERVICE_') || str($match)->startsWith('SERVICE_')) {
$magicEnvironments->put($match, '$'.$match);
}
}
$magicEnvironments->forget($key);
}
}
$normalEnvironments = $environment->diffKeys($magicEnvironments);
if ($magicEnvironments->count() > 0) {
foreach ($magicEnvironments as $key => $value) {
$key = str($key);
$value = str(replaceVariables(str($value)));
$originalValue = $value;
$keyCommand = $key->after('SERVICE_')->before('_');
$valueCommand = $value->after('SERVICE_')->before('_');
if ($key->startsWith('SERVICE_FQDN_')) {
$fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value();
if (str($fqdnFor)->contains('_')) {
$fqdnFor = str($fqdnFor)->before('_');
}
} elseif ($value->startsWith('SERVICE_FQDN_')) {
$fqdnFor = $value->after('SERVICE_FQDN_')->lower()->value();
if (str($fqdnFor)->contains('_')) {
$fqdnFor = str($fqdnFor)->before('_');
}
} else {
$fqdnFor = null;
}
if ($keyCommand->value() === 'FQDN' || $valueCommand->value() === 'FQDN') {
if ($isApplication) {
$fqdn = generateFqdn($server, "{$resource->name}-$uuid");
} elseif ($isService) {
if ($fqdnFor) {
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
} else {
$fqdn = generateFqdn($server, "{$savedService->name}-$uuid");
}
}
if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) {
$path = $value->value();
if ($value === '/') {
$value = "$fqdn";
} else {
$value = "$fqdn$path";
}
} else {
$value = $fqdn;
}
if (! $isDatabase) {
if ($key->startsWith('SERVICE_FQDN_') && ($originalValue->value() === '' || $originalValue->startsWith('/'))) {
if ($isApplication && is_null($resource->fqdn)) {
data_forget($resource, 'environment_variables');
data_forget($resource, 'environment_variables_preview');
$resource->fqdn = $value;
$resource->save();
} elseif ($isService && is_null($savedService->fqdn)) {
if ($key->startsWith('SERVICE_FQDN_')) {
$savedService->fqdn = $value;
$savedService->save();
}
}
}
}
} elseif ($keyCommand->value() === 'URL' || $valueCommand->value() === 'URL') {
if ($isApplication) {
$fqdn = generateFqdn($server, "{$resource->name}-{$uuid}");
} elseif ($isService) {
$fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}");
}
if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) {
$path = $value->value();
$value = "$fqdn$path";
} else {
$value = $fqdn;
}
$value = str($fqdn)->replace('http://', '')->replace('https://', '');
} else {
$generatedValue = generateEnvValue($valueCommand, $resource);
if ($generatedValue) {
$value = $generatedValue;
}
}
if (str($fqdnFor)->startsWith('/')) {
$fqdnFor = null;
}
// Lets save the magic value to the environment variables
if (! $originalValue->startsWith('/')) {
if ($key->startsWith('SERVICE_')) {
$originalValue = $key;
}
$resource->environment_variables()->where('key', $originalValue->value())->where($nameOfId, $resource->id)->firstOrCreate([
'key' => $originalValue->value(),
$nameOfId => $resource->id,
], [
'value' => $value,
'is_build_time' => false,
'is_preview' => false,
if ($isApplication) {
if (data_get($resource, 'settings.connect_to_docker_network')) {
$network = $resource->destination->network;
$networks_temp->put($network, null);
$topLevel->get('networks')->put($network, [
'name' => $network,
'external' => true,
]);
}
// Save the original value to the environment variables
if ($originalValue->startsWith('SERVICE_')) {
$value = "$$originalValue";
}
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
'key' => $key->value(),
$nameOfId => $resource->id,
], [
'value' => "$value",
'is_build_time' => false,
'is_preview' => false,
]);
}
}
$normalEnvironments = $environment->diffKeys($allMagicEnvironments);
$normalEnvironments = $normalEnvironments->filter(function ($value, $key) {
return ! str($value)->startsWith('SERVICE_');
});
foreach ($normalEnvironments as $key => $value) {
$key = str($key);
$value = str($value);
if ($value->startsWith('$') || $value->contains('${')) {
if ($value->contains('${')) {
$value = $value->after('${')->before('}');
}
$value = str(replaceVariables(str($value)));
if ($value->contains(':-')) {
$key = $value->before(':');
$value = $value->after(':-');
} elseif ($value->contains('-')) {
$key = $value->before('-');
$value = $value->after('-');
} elseif ($value->contains(':?')) {
$key = $value->before(':');
$value = $value->after(':?');
} elseif ($value->contains('?')) {
$key = $value->before('?');
$value = $value->after('?');
} else {
$key = $value;
$value = null;
}
$originalValue = $value;
$parsedValue = replaceVariables($value);
if ($value->startsWith('$SERVICE_')) {
$resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
'key' => $key,
$nameOfId => $resource->id,
@@ -3383,6 +3410,57 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
'is_build_time' => false,
'is_preview' => false,
]);
continue;
}
if (! $value->startsWith('$')) {
continue;
}
if ($key->value() === $parsedValue->value()) {
$value = null;
$resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
'key' => $key,
$nameOfId => $resource->id,
], [
'value' => $value,
'is_build_time' => false,
'is_preview' => false,
]);
} else {
if ($value->startsWith('$')) {
if ($value->contains(':-')) {
$value = replaceVariables($value);
$key = $value->before(':');
$value = $value->after(':-');
} elseif ($value->contains('-')) {
$value = replaceVariables($value);
$key = $value->before('-');
$value = $value->after('-');
} elseif ($value->contains(':?')) {
$value = replaceVariables($value);
$key = $value->before(':');
$value = $value->after(':?');
} elseif ($value->contains('?')) {
$value = replaceVariables($value);
$key = $value->before('?');
$value = $value->after('?');
}
if ($originalValue->value() === $value->value()) {
continue;
}
$resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
'key' => $key,
$nameOfId => $resource->id,
], [
'value' => $value,
'is_build_time' => false,
'is_preview' => false,
]);
}
}
}
if ($isApplication) {
@@ -3391,13 +3469,13 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$branch = "pull/{$pullRequestId}/head";
}
if ($originalResource->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
$environment->put('COOLIFY_BRANCH', $branch);
$coolifyEnvironments->put('COOLIFY_BRANCH', $branch);
}
}
// Add COOLIFY_CONTAINER_NAME to environment
if ($resource->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
$environment->put('COOLIFY_CONTAINER_NAME', $containerName);
$coolifyEnvironments->put('COOLIFY_CONTAINER_NAME', $containerName);
}
if ($isApplication) {
@@ -3451,15 +3529,20 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
}
// Add COOLIFY_FQDN & COOLIFY_URL to environment
if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
$environment->put('COOLIFY_URL', $fqdns->implode(','));
$coolifyEnvironments->put('COOLIFY_URL', $fqdns->implode(','));
$urls = $fqdns->map(function ($fqdn) {
return str($fqdn)->replace('http://', '')->replace('https://', '');
});
$environment->put('COOLIFY_FQDN', $urls->implode(','));
$coolifyEnvironments->put('COOLIFY_FQDN', $urls->implode(','));
}
add_coolify_default_environment_variables($resource, $environment, $resource->environment_variables);
add_coolify_default_environment_variables($resource, $coolifyEnvironments, $resource->environment_variables);
if ($environment->count() > 0) {
$environment = $environment->filter(function ($value, $key) {
return ! str($key)->startsWith('SERVICE_FQDN_');
});
}
$serviceLabels = $labels->merge($defaultLabels);
if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
if ($isApplication) {
@@ -3545,17 +3628,19 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
$payload = collect($service)->merge([
'container_name' => $containerName,
'restart' => $restart->value(),
'networks' => $networks_temp,
'labels' => $serviceLabels,
]);
if (! $use_network_mode) {
$payload['networks'] = $networks_temp;
}
if ($ports->count() > 0) {
$payload['ports'] = $ports;
}
if ($volumesParsed->count() > 0) {
$payload['volumes'] = $volumesParsed;
}
if ($environment->count() > 0 || $coolifyDefinedEnvironments->count() > 0) {
$payload['environment'] = $environment->merge($coolifyDefinedEnvironments);
if ($environment->count() > 0 || $coolifyEnvironments->count() > 0) {
$payload['environment'] = $environment->merge($coolifyEnvironments);
}
if ($logging) {
$payload['logging'] = $logging;

View File

@@ -6,7 +6,8 @@ return [
'contact' => 'https://coolify.io/docs/contact',
],
'ssh' => [
'mux_persist_time' => env('SSH_MUX_PERSIST_TIME', '1m'),
'mux_enabled' => env('SSH_MUX_ENABLED', true),
'mux_persist_time' => env('SSH_MUX_PERSIST_TIME', '1h'),
'connection_timeout' => 10,
'server_interval' => 20,
'command_timeout' => 7200,

View File

@@ -7,7 +7,7 @@ return [
// The release version of your application
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
'release' => '4.0.0-beta.331',
'release' => '4.0.0-beta.333',
// When left empty or `null` the Laravel environment will be used
'environment' => config('app.env'),

View File

@@ -1,3 +1,3 @@
<?php
return '4.0.0-beta.331';
return '4.0.0-beta.333';

View File

@@ -0,0 +1,37 @@
<?php
use App\Models\ServerSetting;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('server_settings', function (Blueprint $table) {
$table->string('docker_cleanup_frequency')->default('0 0 * * *')->change();
});
$serverSettings = ServerSetting::all();
foreach ($serverSettings as $serverSetting) {
if ($serverSetting->force_docker_cleanup && $serverSetting->docker_cleanup_frequency === '*/10 * * * *') {
$serverSetting->docker_cleanup_frequency = '0 0 * * *';
$serverSetting->save();
}
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('server_settings', function (Blueprint $table) {
$table->string('docker_cleanup_frequency')->default('*/10 * * * *')->change();
});
}
};

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
class UpdateServerSettingsDefaultTimezone extends Migration
{
public function up()
{
Schema::table('server_settings', function (Blueprint $table) {
$table->string('server_timezone')->default('UTC')->change();
});
DB::table('server_settings')
->whereNull('server_timezone')
->orWhere('server_timezone', '')
->update(['server_timezone' => 'UTC']);
}
public function down()
{
Schema::table('server_settings', function (Blueprint $table) {
$table->string('server_timezone')->default('')->change();
});
}
}

View File

@@ -2831,7 +2831,7 @@ paths:
-
name: uuid
in: path
description: 'Deployment Uuid'
description: 'Deployment UUID'
required: true
schema:
type: string
@@ -2879,7 +2879,7 @@ paths:
type: boolean
responses:
'200':
description: "Get deployment(s) Uuid's"
description: "Get deployment(s) UUID's"
content:
application/json:
schema:
@@ -2993,7 +2993,7 @@ paths:
tags:
- Projects
summary: List
description: 'list projects.'
description: 'List projects.'
operationId: list-projects
responses:
'200':
@@ -3054,7 +3054,7 @@ paths:
tags:
- Projects
summary: Get
description: 'Get project by Uuid.'
description: 'Get project by UUID.'
operationId: get-project-by-uuid
parameters:
-
@@ -3323,7 +3323,7 @@ paths:
-
name: uuid
in: path
description: 'Private Key Uuid'
description: 'Private Key UUID'
required: true
schema:
type: string
@@ -3355,7 +3355,7 @@ paths:
-
name: uuid
in: path
description: 'Private Key Uuid'
description: 'Private Key UUID'
required: true
schema:
type: string
@@ -3475,7 +3475,7 @@ paths:
-
name: uuid
in: path
description: "Server's Uuid"
description: "Server's UUID"
required: true
schema:
type: string
@@ -3595,7 +3595,7 @@ paths:
-
name: uuid
in: path
description: "Server's Uuid"
description: "Server's UUID"
required: true
schema:
type: string
@@ -3627,7 +3627,7 @@ paths:
-
name: uuid
in: path
description: "Server's Uuid"
description: "Server's UUID"
required: true
schema:
type: string
@@ -3784,7 +3784,7 @@ paths:
type: string
responses:
'200':
description: 'Get a service by Uuid.'
description: 'Get a service by UUID.'
content:
application/json:
schema:
@@ -3814,7 +3814,7 @@ paths:
type: string
responses:
'200':
description: 'Delete a service by Uuid'
description: 'Delete a service by UUID'
content:
application/json:
schema:
@@ -3830,108 +3830,6 @@ paths:
security:
-
bearerAuth: []
'/services/{uuid}/start':
get:
tags:
- Services
summary: Start
description: 'Start service. `Post` request is also accepted.'
operationId: start-service-by-uuid
parameters:
-
name: uuid
in: path
description: 'UUID of the service.'
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 'Start service.'
content:
application/json:
schema:
properties:
message: { type: string, example: 'Service starting request queued.' }
type: object
'401':
$ref: '#/components/responses/401'
'400':
$ref: '#/components/responses/400'
'404':
$ref: '#/components/responses/404'
security:
-
bearerAuth: []
'/services/{uuid}/stop':
get:
tags:
- Services
summary: Stop
description: 'Stop service. `Post` request is also accepted.'
operationId: stop-service-by-uuid
parameters:
-
name: uuid
in: path
description: 'UUID of the service.'
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 'Stop service.'
content:
application/json:
schema:
properties:
message: { type: string, example: 'Service stopping request queued.' }
type: object
'401':
$ref: '#/components/responses/401'
'400':
$ref: '#/components/responses/400'
'404':
$ref: '#/components/responses/404'
security:
-
bearerAuth: []
'/services/{uuid}/restart':
get:
tags:
- Services
summary: Restart
description: 'Restart service. `Post` request is also accepted.'
operationId: restart-service-by-uuid
parameters:
-
name: uuid
in: path
description: 'UUID of the service.'
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 'Restart service.'
content:
application/json:
schema:
properties:
message: { type: string, example: 'Service restaring request queued.' }
type: object
'401':
$ref: '#/components/responses/401'
'400':
$ref: '#/components/responses/400'
'404':
$ref: '#/components/responses/404'
security:
-
bearerAuth: []
'/services/{uuid}/envs':
get:
tags:
@@ -4182,6 +4080,108 @@ paths:
security:
-
bearerAuth: []
'/services/{uuid}/start':
get:
tags:
- Services
summary: Start
description: 'Start service. `Post` request is also accepted.'
operationId: start-service-by-uuid
parameters:
-
name: uuid
in: path
description: 'UUID of the service.'
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 'Start service.'
content:
application/json:
schema:
properties:
message: { type: string, example: 'Service starting request queued.' }
type: object
'401':
$ref: '#/components/responses/401'
'400':
$ref: '#/components/responses/400'
'404':
$ref: '#/components/responses/404'
security:
-
bearerAuth: []
'/services/{uuid}/stop':
get:
tags:
- Services
summary: Stop
description: 'Stop service. `Post` request is also accepted.'
operationId: stop-service-by-uuid
parameters:
-
name: uuid
in: path
description: 'UUID of the service.'
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 'Stop service.'
content:
application/json:
schema:
properties:
message: { type: string, example: 'Service stopping request queued.' }
type: object
'401':
$ref: '#/components/responses/401'
'400':
$ref: '#/components/responses/400'
'404':
$ref: '#/components/responses/404'
security:
-
bearerAuth: []
'/services/{uuid}/restart':
get:
tags:
- Services
summary: Restart
description: 'Restart service. `Post` request is also accepted.'
operationId: restart-service-by-uuid
parameters:
-
name: uuid
in: path
description: 'UUID of the service.'
required: true
schema:
type: string
format: uuid
responses:
'200':
description: 'Restart service.'
content:
application/json:
schema:
properties:
message: { type: string, example: 'Service restaring request queued.' }
type: object
'401':
$ref: '#/components/responses/401'
'400':
$ref: '#/components/responses/400'
'404':
$ref: '#/components/responses/404'
security:
-
bearerAuth: []
/teams:
get:
tags:
@@ -4730,6 +4730,8 @@ components:
type: string
name:
type: string
description:
type: string
environments:
description: 'The environments of the project.'
type: array

View File

@@ -59,9 +59,9 @@ if [ $EUID != 0 ]; then
fi
case "$OS_TYPE" in
arch | ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed | almalinux | amzn) ;;
arch | ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed | almalinux | amzn | alpine) ;;
*)
echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now."
echo "This script only supports Debian, Redhat, Arch Linux, Alpine Linux, or SLES based operating systems for now."
exit
;;
esac
@@ -90,6 +90,11 @@ case "$OS_TYPE" in
arch)
pacman -Sy --noconfirm --needed curl wget git jq >/dev/null || true
;;
alpine)
sed -i '/^#.*\/community/s/^#//' /etc/apk/repositories
apk update >/dev/null
apk add curl wget git jq >/dev/null
;;
ubuntu | debian | raspbian)
apt-get update -y >/dev/null
apt-get install -y curl wget git jq >/dev/null
@@ -172,70 +177,74 @@ if [ -x "$(command -v snap)" ]; then
fi
if ! [ -x "$(command -v docker)" ]; then
# Almalinux
if [ "$OS_TYPE" == 'almalinux' ]; then
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
if ! [ -x "$(command -v docker)" ]; then
echo "Docker could not be installed automatically. Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
systemctl start docker
systemctl enable docker
else
set +e
if ! [ -x "$(command -v docker)" ]; then
echo "Docker is not installed. Installing Docker."
# Arch Linux
if [ "$OS_TYPE" = "arch" ]; then
pacman -Sy docker docker-compose --noconfirm
systemctl enable docker.service
case "$OS_TYPE" in
"almalinux")
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
if ! [ -x "$(command -v docker)" ]; then
echo "Docker could not be installed automatically. Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
systemctl start docker
systemctl enable docker
;;
"alpine")
apk add docker docker-cli-compose
rc-update add docker default
service docker start
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with apk. Try to install it manually."
echo "Please visit https://wiki.alpinelinux.org/wiki/Docker for more information."
exit
fi
;;
"arch")
pacman -Sy docker docker-compose --noconfirm
systemctl enable docker.service
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with pacman. Try to install it manually."
echo "Please visit https://wiki.archlinux.org/title/docker for more information."
exit
fi
;;
"amzn")
dnf install docker -y
DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
systemctl start docker
systemctl enable docker
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with dnf. Try to install it manually."
echo "Please visit https://www.cyberciti.biz/faq/how-to-install-docker-on-amazon-linux-2/ for more information."
exit
fi
;;
*)
# Automated Docker installation
curl https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Docker installation failed with Rancher script. Trying with official script."
curl https://get.docker.com | sh -s -- --version ${DOCKER_VERSION}
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with pacman. Try to install it manually."
echo "Please visit https://wiki.archlinux.org/title/docker for more information."
exit
fi
else
# Amazon Linux 2023
if [ "$OS_TYPE" = "amzn" ]; then
dnf install docker -y
DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
systemctl start docker
systemctl enable docker
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with pacman. Try to install it manually."
echo "Please visit https://wiki.archlinux.org/title/docker for more information."
exit
fi
else
# Automated Docker installation
curl https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Docker installation failed with Rancher script. Trying with official script."
curl https://get.docker.com | sh -s -- --version ${DOCKER_VERSION}
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Docker installation failed with official script."
echo "Maybe your OS is not supported?"
echo "Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
fi
echo "Docker installation failed with official script."
echo "Maybe your OS is not supported?"
echo "Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
fi
fi
set -e
fi
esac
fi
echo -e "-------------"
@@ -267,17 +276,50 @@ if ! jq -s '.[0] * .[1]' /etc/docker/daemon.json /etc/docker/daemon.json.coolify
fi
mv "$TEMP_FILE" /etc/docker/daemon.json
restart_docker_service() {
# Check if systemctl is available
if command -v systemctl >/dev/null 2>&1; then
echo "Using systemctl to restart Docker..."
systemctl restart docker
if [ $? -eq 0 ]; then
echo "Docker restarted successfully using systemctl."
else
echo "Failed to restart Docker using systemctl."
return 1
fi
# Check if service command is available
elif command -v service >/dev/null 2>&1; then
echo "Using service command to restart Docker..."
service docker restart
if [ $? -eq 0 ]; then
echo "Docker restarted successfully using service."
else
echo "Failed to restart Docker using service."
return 1
fi
# If neither systemctl nor service is available
else
echo "Neither systemctl nor service command is available on this system."
return 1
fi
}
if [ -s /etc/docker/daemon.json.original-"$DATE" ]; then
DIFF=$(diff <(jq --sort-keys . /etc/docker/daemon.json) <(jq --sort-keys . /etc/docker/daemon.json.original-"$DATE"))
if [ "$DIFF" != "" ]; then
echo "Docker configuration updated, restart docker daemon..."
systemctl restart docker
restart_docker_service
else
echo "Docker configuration is up to date."
fi
else
echo "Docker configuration updated, restart docker daemon..."
systemctl restart docker
restart_docker_service
fi
echo -e "-------------"
@@ -296,28 +338,35 @@ curl -fsSL $CDN/.env.production -o /data/coolify/source/.env.production
curl -fsSL $CDN/upgrade.sh -o /data/coolify/source/upgrade.sh
# Copy .env.example if .env does not exist
if [ ! -f $ENV_FILE ]; then
cp /data/coolify/source/.env.production $ENV_FILE
# Generate a secure APP_ID and APP_KEY
sed -i "s|^APP_ID=.*|APP_ID=$(openssl rand -hex 16)|" "$ENV_FILE"
sed -i "s|^APP_KEY=.*|APP_KEY=base64:$(openssl rand -base64 32)|" "$ENV_FILE"
if [ -f $ENV_FILE ]; then
echo "File exists: $ENV_FILE"
cat $ENV_FILE
echo "Copying .env to .env-$DATE"
cp $ENV_FILE $ENV_FILE-$DATE
else
echo "File does not exist: $ENV_FILE"
echo "Copying .env.production to .env-$DATE"
cp /data/coolify/source/.env.production $ENV_FILE-$DATE
# Generate a secure APP_ID and APP_KEY
sed -i "s|^APP_ID=.*|APP_ID=$(openssl rand -hex 16)|" "$ENV_FILE-$DATE"
sed -i "s|^APP_KEY=.*|APP_KEY=base64:$(openssl rand -base64 32)|" "$ENV_FILE-$DATE"
# Generate a secure Postgres DB username and password
# Causes issues: database "random-user" does not exist
# sed -i "s|^DB_USERNAME=.*|DB_USERNAME=$(openssl rand -hex 16)|" "$ENV_FILE"
sed -i "s|^DB_PASSWORD=.*|DB_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE"
# sed -i "s|^DB_USERNAME=.*|DB_USERNAME=$(openssl rand -hex 16)|" "$ENV_FILE-$DATE"
sed -i "s|^DB_PASSWORD=.*|DB_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE-$DATE"
# Generate a secure Redis password
sed -i "s|^REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE"
sed -i "s|^REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE-$DATE"
# Generate secure Pusher credentials
sed -i "s|^PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|" "$ENV_FILE"
sed -i "s|^PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|" "$ENV_FILE"
sed -i "s|^PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|" "$ENV_FILE"
sed -i "s|^PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE"
sed -i "s|^PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE"
sed -i "s|^PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE"
fi
# Merge .env and .env.production. New values will be added to .env
sort -u -t '=' -k 1,1 /data/coolify/source/.env /data/coolify/source/.env.production | sed '/^$/d' >/data/coolify/source/.env.temp && mv /data/coolify/source/.env.temp /data/coolify/source/.env
awk -F '=' '!seen[$1]++' "$ENV_FILE-$DATE" /data/coolify/source/.env.production > $ENV_FILE
if [ "$AUTOUPDATE" = "false" ]; then
if ! grep -q "AUTOUPDATE=" /data/coolify/source/.env; then
@@ -350,7 +399,7 @@ if ! grep -qw "root@coolify" ~/.ssh/authorized_keys; then
fi
bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}"
rm -f $ENV_FILE-$DATE
echo "Waiting for 20 seconds for Coolify to be ready..."
sleep 20

View File

@@ -11,7 +11,7 @@ curl -fsSL $CDN/docker-compose.prod.yml -o /data/coolify/source/docker-compose.p
curl -fsSL $CDN/.env.production -o /data/coolify/source/.env.production
# Merge .env and .env.production. New values will be added to .env
sort -u -t '=' -k 1,1 /data/coolify/source/.env /data/coolify/source/.env.production | sed '/^$/d' >/data/coolify/source/.env.temp && mv /data/coolify/source/.env.temp /data/coolify/source/.env
awk -F '=' '!seen[$1]++' /data/coolify/source/.env /data/coolify/source/.env.production > /data/coolify/source/.env.tmp && mv /data/coolify/source/.env.tmp /data/coolify/source/.env
# Check if PUSHER_APP_ID or PUSHER_APP_KEY or PUSHER_APP_SECRET is empty in /data/coolify/source/.env
if grep -q "PUSHER_APP_ID=$" /data/coolify/source/.env; then

View File

@@ -28,25 +28,33 @@
<x-highlighted text="Self-hosting with superpowers!" /></span>
</x-slot:question>
<x-slot:explanation>
<p><x-highlighted text="Task automation:" /> You don't need to manage your servers anymore.
<p>
<x-highlighted text="Task automation:" /> You don't need to manage your servers anymore.
Coolify does
it for you.</p>
<p><x-highlighted text="No vendor lock-in:" /> All configurations are stored on your servers, so
everything works without a connection to Coolify (except integrations and automations).</p>
<p><x-highlighted text="Monitoring:" />You can get notified on your favourite platforms
it for you.
</p>
<p>
<x-highlighted text="No vendor lock-in:" /> All configurations are stored on your servers, so
everything works without a connection to Coolify (except integrations and automations).
</p>
<p>
<x-highlighted text="Monitoring:" />You can get notified on your favourite platforms
(Discord,
Telegram, Email, etc.) when something goes wrong, or an action is needed from your side.</p>
Telegram, Email, etc.) when something goes wrong, or an action is needed from your side.
</p>
</x-slot:explanation>
<x-slot:actions>
<x-forms.button class="justify-center lg:w-64 box-boarding" wire:click="explanation">Next
<x-forms.button class="justify-center w-64 box-boarding" wire:click="explanation">Next
</x-forms.button>
</x-slot:actions>
</x-boarding-step>
@elseif ($currentState === 'select-server-type')
<x-boarding-step title="Server">
<x-slot:question>
Do you want to deploy your resources to your <x-highlighted text="Localhost" />
or to a <x-highlighted text="Remote Server" />?
Do you want to deploy your resources to your
<x-highlighted text="Localhost" />
or to a
<x-highlighted text="Remote Server" />?
</x-slot:question>
<x-slot:actions>
<x-forms.button class="justify-center w-64 box-boarding" wire:target="setServerType('localhost')"
@@ -56,32 +64,66 @@
<x-forms.button class="justify-center w-64 box-boarding " wire:target="setServerType('remote')"
wire:click="setServerType('remote')">Remote Server
</x-forms.button>
@if (!$serverReachable)
Localhost is not reachable with the following public key.
<br /> <br />
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for
user or skip the boarding process and add a new private key manually to Coolify and to the
server.
<br />
Check this <a target="_blank" class="underline"
href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further
help.
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
<x-forms.button class="lg:w-64 box-boarding" wire:target="setServerType('localhost')"
wire:click="setServerType('localhost')">Check again
</x-forms.button>
<div class="mt-6 p-4 border border-error rounded-lg text-gray-800 dark:text-gray-200">
<h2 class="text-lg font-bold mb-2">Server is not reachable</h2>
<p class="mb-4">Please check the connection details below and correct them if they are
incorrect.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<x-forms.input placeholder="Default is 22" label="Port" id="remoteServerPort"
wire:model="remoteServerPort" :value="$remoteServerPort" />
<div>
<x-forms.input placeholder="Default is root" label="User" id="remoteServerUser"
wire:model="remoteServerUser" :value="$remoteServerUser" />
<p class="text-xs mt-1">
Non-root user is experimental:
<a class="font-bold underline" target="_blank"
href="https://coolify.io/docs/knowledge-base/server/non-root-user">docs</a>
</p>
</div>
</div>
<div class="mb-4">
<p class="mb-2">If the connection details are correct, please ensure:</p>
<ul class="list-disc list-inside">
<li>The correct public key is in your <code
class="bg-red-200 dark:bg-red-900 px-1 rounded">~/.ssh/authorized_keys</code>
file for the specified user</li>
<li>Or skip the boarding process and manually add a new private key to Coolify and
the server</li>
</ul>
</div>
<p class="mb-4">
For more help, check this <a target="_blank" class="underline font-semibold"
href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a>.
</p>
<x-forms.input readonly id="serverPublicKey" class="mb-4"
label="Current Public Key"></x-forms.input>
<x-forms.button class="w-full box-boarding" wire:click="saveAndValidateServer">
Check Again
</x-forms.button>
</div>
@endif
</x-slot:actions>
<x-slot:explanation>
<p>Servers are the main building blocks, as they will host your applications, databases,
services, called resources. Any CPU intensive process will use the server's CPU where you
are deploying your resources.</p>
<p><x-highlighted text="Localhost" /> is the server where Coolify is running on. It is not
<p>
<x-highlighted text="Localhost" /> is the server where Coolify is running on. It is not
recommended to use one server
for everything.</p>
<p><x-highlighted text="A remote server" /> is a server reachable through SSH. It can be hosted
for everything.
</p>
<p>
<x-highlighted text="A remote server" /> is a server reachable through SSH. It can be hosted
at home, or from any cloud
provider.</p>
provider.
</p>
</x-slot:explanation>
</x-boarding-step>
@elseif ($currentState === 'private-key')
@@ -126,10 +168,7 @@
<div class="flex flex-col gap-4">
<div>
<x-forms.button class="justify-center w-64 box-boarding" wire:click="createNewServer">No
(create
one
for
me)
(create one for me)
</x-forms.button>
</div>
<div>
@@ -145,20 +184,48 @@
</div>
</div>
@if (!$serverReachable)
This server is not reachable with the following public key.
<br /> <br />
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for
user or skip the boarding process and add a new private key manually to Coolify and to the
server.
<br />
Check this <a target="_blank" class="underline"
href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further
help.
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
<x-forms.button class="w-64 box-boarding" wire:target="validateServer"
wire:click="validateServer">Check
again
</x-forms.button>
<div class="mt-6 p-4 bg-red-100 dark:bg-red-950 rounded-lg text-gray-800 dark:text-gray-200">
<h2 class="text-lg font-bold mb-2">Server is not reachable</h2>
<p class="mb-4">Please check the connection details below and correct them if they are
incorrect.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<x-forms.input placeholder="Default is 22" label="Port" id="remoteServerPort"
wire:model="remoteServerPort" :value="$remoteServerPort" />
<div>
<x-forms.input placeholder="Default is root" label="User" id="remoteServerUser"
wire:model="remoteServerUser" :value="$remoteServerUser" />
<p class="text-xs mt-1">
Non-root user is experimental:
<a class="font-bold underline" target="_blank"
href="https://coolify.io/docs/knowledge-base/server/non-root-user">docs</a>
</p>
</div>
</div>
<div class="mb-4">
<p class="mb-2">If the connection details are correct, please ensure:</p>
<ul class="list-disc list-inside">
<li>The correct public key is in your <code
class="bg-red-200 dark:bg-red-900 px-1 rounded">~/.ssh/authorized_keys</code>
file for the specified user</li>
<li>Or skip the boarding process and manually add a new private key to Coolify and
the server</li>
</ul>
</div>
<p class="mb-4">
For more help, check this <a target="_blank" class="underline font-semibold"
href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a>.
</p>
<x-forms.input readonly id="serverPublicKey" class="mb-4"
label="Current Public Key"></x-forms.input>
<x-forms.button class="w-full md:w-auto box-boarding" wire:click="saveAndValidateServer">
Check again
</x-forms.button>
</div>
@endif
</x-slot:actions>
<x-slot:explanation>
@@ -180,8 +247,8 @@
label="Name" id="privateKeyName" />
<x-forms.input placeholder="Description, so others will know more about this."
label="Description" id="privateKeyDescription" />
<x-forms.textarea required placeholder="-----BEGIN OPENSSH PRIVATE KEY-----" label="Private Key"
id="privateKey" />
<x-forms.textarea required placeholder="-----BEGIN OPENSSH PRIVATE KEY-----"
label="Private Key" id="privateKey" />
@if ($privateKeyType === 'create')
<x-forms.textarea rows="7" readonly label="Public Key" id="publicKey" />
<span class="font-bold dark:text-warning">ACTION REQUIRED: Copy the 'Public Key' to your
@@ -209,27 +276,37 @@
<form wire:submit='saveServer' class="flex flex-col w-full gap-4 lg:pr-10">
<div class="flex flex-col gap-2 lg:flex-row">
<x-forms.input required placeholder="Choose a name for your Server. Could be anything."
label="Name" id="remoteServerName" />
label="Name" id="remoteServerName" wire:model="remoteServerName" />
<x-forms.input placeholder="Description, so others will know more about this."
label="Description" id="remoteServerDescription" />
label="Description" id="remoteServerDescription"
wire:model="remoteServerDescription" />
</div>
<div class="flex flex-col gap-2 lg:flex-row ">
<x-forms.input required placeholder="127.0.0.1" label="IP Address" id="remoteServerHost" />
<x-forms.input required placeholder="Port number of your server. Default is 22."
label="Port" id="remoteServerPort" />
<div class="w-full">
<x-forms.input required placeholder="User to connect to your server. Default is root."
label="User" id="remoteServerUser" />
<div class="text-xs dark:text-warning text-coollabs ">Non-root user is experimental: <a
class="font-bold underline" target="_blank"
href="https://coolify.io/docs/knowledge-base/server/non-root-user">docs</a>.
<x-forms.input required placeholder="127.0.0.1" label="IP Address" id="remoteServerHost"
wire:model="remoteServerHost" />
</div>
<div x-data="{ showAdvanced: false }" class="flex flex-col gap-2">
<button @click="showAdvanced = !showAdvanced" type="button"
class="text-left text-sm text-gray-600 dark:text-gray-300 hover:underline">
Advanced Settings
</button>
<div x-show="showAdvanced" class="flex flex-col gap-2 lg:flex-row">
<x-forms.input placeholder="Port number of your server. Default is 22." label="Port"
id="remoteServerPort" wire:model="remoteServerPort" />
<div class="w-full">
<x-forms.input placeholder="Default is root." label="User"
id="remoteServerUser" wire:model="remoteServerUser" />
<div class="text-xs text-gray-600 dark:text-gray-300">Non-root user is
experimental: <a class="font-bold underline" target="_blank"
href="https://coolify.io/docs/knowledge-base/server/non-root-user">docs</a>.
</div>
</div>
</div>
</div>
<div class="lg:w-64">
<x-forms.checkbox
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.<br><span class='dark:text-warning'>Coolify does not install/setup Cloudflare (cloudflared) on your server.</span>"
id="isCloudflareTunnel" label="Cloudflare Tunnel" />
id="isCloudflareTunnel" label="Cloudflare Tunnel" wire:model="isCloudflareTunnel" />
</div>
<x-forms.button type="submit">Continue</x-forms.button>
</form>
@@ -329,5 +406,4 @@
<livewire:help />
</x-modal-input>
</div>
</div>
</section>

View File

@@ -59,9 +59,9 @@ if [ $EUID != 0 ]; then
fi
case "$OS_TYPE" in
arch | ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed | almalinux | amzn) ;;
arch | ubuntu | debian | raspbian | centos | fedora | rhel | ol | rocky | sles | opensuse-leap | opensuse-tumbleweed | almalinux | amzn | alpine) ;;
*)
echo "This script only supports Debian, Redhat, Arch Linux, or SLES based operating systems for now."
echo "This script only supports Debian, Redhat, Arch Linux, Alpine Linux, or SLES based operating systems for now."
exit
;;
esac
@@ -90,6 +90,11 @@ case "$OS_TYPE" in
arch)
pacman -Sy --noconfirm --needed curl wget git jq >/dev/null || true
;;
alpine)
sed -i '/^#.*\/community/s/^#//' /etc/apk/repositories
apk update >/dev/null
apk add curl wget git jq >/dev/null
;;
ubuntu | debian | raspbian)
apt-get update -y >/dev/null
apt-get install -y curl wget git jq >/dev/null
@@ -172,70 +177,74 @@ if [ -x "$(command -v snap)" ]; then
fi
if ! [ -x "$(command -v docker)" ]; then
# Almalinux
if [ "$OS_TYPE" == 'almalinux' ]; then
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
if ! [ -x "$(command -v docker)" ]; then
echo "Docker could not be installed automatically. Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
systemctl start docker
systemctl enable docker
else
set +e
if ! [ -x "$(command -v docker)" ]; then
echo "Docker is not installed. Installing Docker."
# Arch Linux
if [ "$OS_TYPE" = "arch" ]; then
pacman -Sy docker docker-compose --noconfirm
systemctl enable docker.service
case "$OS_TYPE" in
"almalinux")
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
if ! [ -x "$(command -v docker)" ]; then
echo "Docker could not be installed automatically. Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
systemctl start docker
systemctl enable docker
;;
"alpine")
apk add docker docker-cli-compose
rc-update add docker default
service docker start
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with apk. Try to install it manually."
echo "Please visit https://wiki.alpinelinux.org/wiki/Docker for more information."
exit
fi
;;
"arch")
pacman -Sy docker docker-compose --noconfirm
systemctl enable docker.service
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with pacman. Try to install it manually."
echo "Please visit https://wiki.archlinux.org/title/docker for more information."
exit
fi
;;
"amzn")
dnf install docker -y
DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
systemctl start docker
systemctl enable docker
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with dnf. Try to install it manually."
echo "Please visit https://www.cyberciti.biz/faq/how-to-install-docker-on-amazon-linux-2/ for more information."
exit
fi
;;
*)
# Automated Docker installation
curl https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Docker installation failed with Rancher script. Trying with official script."
curl https://get.docker.com | sh -s -- --version ${DOCKER_VERSION}
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with pacman. Try to install it manually."
echo "Please visit https://wiki.archlinux.org/title/docker for more information."
exit
fi
else
# Amazon Linux 2023
if [ "$OS_TYPE" = "amzn" ]; then
dnf install docker -y
DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
systemctl start docker
systemctl enable docker
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Failed to install Docker with pacman. Try to install it manually."
echo "Please visit https://wiki.archlinux.org/title/docker for more information."
exit
fi
else
# Automated Docker installation
curl https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Docker installation failed with Rancher script. Trying with official script."
curl https://get.docker.com | sh -s -- --version ${DOCKER_VERSION}
if [ -x "$(command -v docker)" ]; then
echo "Docker installed successfully."
else
echo "Docker installation failed with official script."
echo "Maybe your OS is not supported?"
echo "Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
fi
echo "Docker installation failed with official script."
echo "Maybe your OS is not supported?"
echo "Please visit https://docs.docker.com/engine/install/ and install Docker manually to continue."
exit 1
fi
fi
fi
set -e
fi
esac
fi
echo -e "-------------"
@@ -267,17 +276,50 @@ if ! jq -s '.[0] * .[1]' /etc/docker/daemon.json /etc/docker/daemon.json.coolify
fi
mv "$TEMP_FILE" /etc/docker/daemon.json
restart_docker_service() {
# Check if systemctl is available
if command -v systemctl >/dev/null 2>&1; then
echo "Using systemctl to restart Docker..."
systemctl restart docker
if [ $? -eq 0 ]; then
echo "Docker restarted successfully using systemctl."
else
echo "Failed to restart Docker using systemctl."
return 1
fi
# Check if service command is available
elif command -v service >/dev/null 2>&1; then
echo "Using service command to restart Docker..."
service docker restart
if [ $? -eq 0 ]; then
echo "Docker restarted successfully using service."
else
echo "Failed to restart Docker using service."
return 1
fi
# If neither systemctl nor service is available
else
echo "Neither systemctl nor service command is available on this system."
return 1
fi
}
if [ -s /etc/docker/daemon.json.original-"$DATE" ]; then
DIFF=$(diff <(jq --sort-keys . /etc/docker/daemon.json) <(jq --sort-keys . /etc/docker/daemon.json.original-"$DATE"))
if [ "$DIFF" != "" ]; then
echo "Docker configuration updated, restart docker daemon..."
systemctl restart docker
restart_docker_service
else
echo "Docker configuration is up to date."
fi
else
echo "Docker configuration updated, restart docker daemon..."
systemctl restart docker
restart_docker_service
fi
echo -e "-------------"
@@ -296,28 +338,35 @@ curl -fsSL $CDN/.env.production -o /data/coolify/source/.env.production
curl -fsSL $CDN/upgrade.sh -o /data/coolify/source/upgrade.sh
# Copy .env.example if .env does not exist
if [ ! -f $ENV_FILE ]; then
cp /data/coolify/source/.env.production $ENV_FILE
# Generate a secure APP_ID and APP_KEY
sed -i "s|^APP_ID=.*|APP_ID=$(openssl rand -hex 16)|" "$ENV_FILE"
sed -i "s|^APP_KEY=.*|APP_KEY=base64:$(openssl rand -base64 32)|" "$ENV_FILE"
if [ -f $ENV_FILE ]; then
echo "File exists: $ENV_FILE"
echo "Copying .env to .env-$DATE"
cp $ENV_FILE $ENV_FILE-$DATE
else
echo "File does not exist: $ENV_FILE"
echo "Copying .env.production to .env-$DATE"
cp /data/coolify/source/.env.production $ENV_FILE-$DATE
# Generate a secure APP_ID and APP_KEY
sed -i "s|^APP_ID=.*|APP_ID=$(openssl rand -hex 16)|" "$ENV_FILE-$DATE"
sed -i "s|^APP_KEY=.*|APP_KEY=base64:$(openssl rand -base64 32)|" "$ENV_FILE-$DATE"
# Generate a secure Postgres DB username and password
# Causes issues: database "random-user" does not exist
# sed -i "s|^DB_USERNAME=.*|DB_USERNAME=$(openssl rand -hex 16)|" "$ENV_FILE"
sed -i "s|^DB_PASSWORD=.*|DB_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE"
# sed -i "s|^DB_USERNAME=.*|DB_USERNAME=$(openssl rand -hex 16)|" "$ENV_FILE-$DATE"
sed -i "s|^DB_PASSWORD=.*|DB_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE-$DATE"
# Generate a secure Redis password
sed -i "s|^REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE"
sed -i "s|^REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -base64 32)|" "$ENV_FILE-$DATE"
# Generate secure Pusher credentials
sed -i "s|^PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|" "$ENV_FILE"
sed -i "s|^PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|" "$ENV_FILE"
sed -i "s|^PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|" "$ENV_FILE"
sed -i "s|^PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE"
sed -i "s|^PUSHER_APP_KEY=.*|PUSHER_APP_KEY=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE"
sed -i "s|^PUSHER_APP_SECRET=.*|PUSHER_APP_SECRET=$(openssl rand -hex 32)|" "$ENV_FILE-$DATE"
fi
# Merge .env and .env.production. New values will be added to .env
sort -u -t '=' -k 1,1 /data/coolify/source/.env /data/coolify/source/.env.production | sed '/^$/d' >/data/coolify/source/.env.temp && mv /data/coolify/source/.env.temp /data/coolify/source/.env
echo "Updating .env with new values (if necessary)..."
awk -F '=' '!seen[$1]++' "$ENV_FILE-$DATE" /data/coolify/source/.env.production > $ENV_FILE
if [ "$AUTOUPDATE" = "false" ]; then
if ! grep -q "AUTOUPDATE=" /data/coolify/source/.env; then
@@ -350,9 +399,13 @@ if ! grep -qw "root@coolify" ~/.ssh/authorized_keys; then
fi
bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}"
rm -f $ENV_FILE-$DATE
echo "Waiting for 20 seconds for Coolify to be ready..."
sleep 20
echo "Please visit http://$(curl -4s https://ifconfig.io):8000 to get started."
echo -e "\nCongratulations! Your Coolify instance is ready to use.\n"
echo -e "Make sure you backup your /data/coolify/source/.env file to a safe location, outside of this server.\n"
cp /data/coolify/source/.env /data/coolify/source/.env.backup
echo -e "Your .env file has been copied to /data/coolify/source/.env.backup\n"

View File

@@ -11,8 +11,7 @@ curl -fsSL $CDN/docker-compose.prod.yml -o /data/coolify/source/docker-compose.p
curl -fsSL $CDN/.env.production -o /data/coolify/source/.env.production
# Merge .env and .env.production. New values will be added to .env
sort -u -t '=' -k 1,1 /data/coolify/source/.env /data/coolify/source/.env.production | sed '/^$/d' >/data/coolify/source/.env.temp && mv /data/coolify/source/.env.temp /data/coolify/source/.env
awk -F '=' '!seen[$1]++' /data/coolify/source/.env /data/coolify/source/.env.production > /data/coolify/source/.env.tmp && mv /data/coolify/source/.env.tmp /data/coolify/source/.env
# Check if PUSHER_APP_ID or PUSHER_APP_KEY or PUSHER_APP_SECRET is empty in /data/coolify/source/.env
if grep -q "PUSHER_APP_ID=$" /data/coolify/source/.env; then
sed -i "s|PUSHER_APP_ID=.*|PUSHER_APP_ID=$(openssl rand -hex 32)|g" /data/coolify/source/.env

View File

@@ -11,23 +11,23 @@ services:
- SERVICE_FQDN_ACTIVEPIECES
- AP_API_KEY=$SERVICE_PASSWORD_64_APIKEY
- AP_ENCRYPTION_KEY=$SERVICE_PASSWORD_ENCRYPTIONKEY
- AP_ENGINE_EXECUTABLE_PATH=dist/packages/engine/main.js
- AP_ENVIRONMENT=prod
- AP_EXECUTION_MODE=UNSANDBOXED
- AP_FRONTEND_URL=$SERVICE_FQDN_ACTIVEPIECES
- AP_ENGINE_EXECUTABLE_PATH=${AP_ENGINE_EXECUTABLE_PATH:-dist/packages/engine/main.js}
- AP_ENVIRONMENT=${AP_ENVIRONMENT:-prod}
- AP_EXECUTION_MODE=${AP_EXECUTION_MODE:-UNSANDBOXED}
- AP_FRONTEND_URL=${SERVICE_FQDN_ACTIVEPIECES}
- AP_JWT_SECRET=$SERVICE_PASSWORD_64_JWT
- AP_POSTGRES_DATABASE=activepieces
- AP_POSTGRES_HOST=postgres
- AP_POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
- AP_POSTGRES_PORT=5432
- AP_POSTGRES_DATABASE=${POSTGRES_DB:-activepieces}
- AP_POSTGRES_HOST=${POSTGRES_HOST:-postgres}
- AP_POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
- AP_POSTGRES_PORT=${POSTGRES_PORT:-5432}
- AP_POSTGRES_USERNAME=$SERVICE_USER_POSTGRES
- AP_REDIS_HOST=redis
- AP_REDIS_PORT=6379
- AP_SANDBOX_RUN_TIME_SECONDS=600
- AP_TELEMETRY_ENABLED=true
- "AP_TEMPLATES_SOURCE_URL=https://cloud.activepieces.com/api/v1/flow-templates"
- AP_TRIGGER_DEFAULT_POLL_INTERVAL=5
- AP_WEBHOOK_TIMEOUT_SECONDS=30
- AP_REDIS_HOST=${REDIS_HOST:-redis}
- AP_REDIS_PORT=${REDIS_PORT:-6379}
- AP_SANDBOX_RUN_TIME_SECONDS=${AP_SANDBOX_RUN_TIME_SECONDS:-600}
- AP_TELEMETRY_ENABLED=${AP_TELEMETRY_ENABLED:-false}
- AP_TEMPLATES_SOURCE_URL=${AP_TEMPLATES_SOURCE_URL:-https://cloud.activepieces.com/api/v1/flow-templates}
- AP_TRIGGER_DEFAULT_POLL_INTERVAL=${AP_TRIGGER_DEFAULT_POLL_INTERVAL:-5}
- AP_WEBHOOK_TIMEOUT_SECONDS=${AP_WEBHOOK_TIMEOUT_SECONDS:-30}
depends_on:
postgres:
condition: service_healthy
@@ -41,9 +41,10 @@ services:
postgres:
image: "postgres:latest"
environment:
- POSTGRES_DB=activepieces
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
- POSTGRES_USER=$SERVICE_USER_POSTGRES
- POSTGRES_DB=${POSTGRES_DB:-activepieces}
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
- POSTGRES_USER=${SERVICE_USER_POSTGRES}
- POSTGRES_PORT=${POSTGRES_PORT:-5432}
volumes:
- "pg-data:/var/lib/postgresql/data"
healthcheck:

View File

@@ -8,11 +8,11 @@ services:
image: index.docker.io/appsmith/appsmith-ce:latest
environment:
- SERVICE_FQDN_APPSMITH
- APPSMITH_MAIL_ENABLED=false
- APPSMITH_DISABLE_TELEMETRY=true
- APPSMITH_DISABLE_INTERCOM=true
- APPSMITH_SENTRY_DSN=
- APPSMITH_SMART_LOOK_ID=
- APPSMITH_MAIL_ENABLED=${APPSMITH_MAIL_ENABLED:-false}
- APPSMITH_DISABLE_TELEMETRY=${APPSMITH_DISABLE_TELEMETRY:-false}
- APPSMITH_DISABLE_INTERCOM=${APPSMITH_DISABLE_INTERCOM:-true}
- APPSMITH_SENTRY_DSN=${APPSMITH_SENTRY_DSN}
- APPSMITH_SMART_LOOK_ID=${APPSMITH_SMART_LOOK_ID}
volumes:
- stacks-data:/appsmith-stacks
healthcheck:

View File

@@ -1,99 +0,0 @@
_APP_ENV=production
_APP_LOCALE=en
_APP_OPTIONS_ABUSE=enabled
_APP_OPTIONS_FORCE_HTTPS=disabled
_APP_OPENSSL_KEY_V1=
_APP_CONSOLE_WHITELIST_ROOT=enabled
_APP_CONSOLE_WHITELIST_EMAILS=
_APP_CONSOLE_WHITELIST_IPS=
_APP_CONSOLE_HOSTNAMES=localhost,appwrite.io,*.appwrite.io
_APP_SYSTEM_EMAIL_NAME=Appwrite
_APP_SYSTEM_EMAIL_ADDRESS=team@appwrite.io
_APP_SYSTEM_RESPONSE_FORMAT=
_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=certs@appwrite.io
_APP_USAGE_STATS=enabled
_APP_LOGGING_PROVIDER=
_APP_LOGGING_CONFIG=
_APP_USAGE_AGGREGATION_INTERVAL=30
_APP_USAGE_TIMESERIES_INTERVAL=30
_APP_USAGE_DATABASE_INTERVAL=900
_APP_WORKER_PER_CORE=6
_APP_REDIS_HOST=appwrite-redis
_APP_REDIS_PORT=6379
_APP_REDIS_USER=
_APP_REDIS_PASS=
_APP_DB_HOST=appwrite-mariadb
_APP_DB_PORT=3306
_APP_DB_SCHEMA=appwrite
_APP_SMTP_HOST=
_APP_SMTP_PORT=
_APP_SMTP_SECURE=
_APP_SMTP_USERNAME=
_APP_SMTP_PASSWORD=
_APP_SMS_PROVIDER=
_APP_SMS_FROM=
_APP_STORAGE_LIMIT=30000000
_APP_STORAGE_PREVIEW_LIMIT=20000000
_APP_STORAGE_ANTIVIRUS=disabled
_APP_STORAGE_ANTIVIRUS_HOST=appwrite-clamav
_APP_STORAGE_ANTIVIRUS_PORT=3310
_APP_STORAGE_DEVICE=local
_APP_STORAGE_S3_ACCESS_KEY=
_APP_STORAGE_S3_SECRET=
_APP_STORAGE_S3_REGION=us-east-1
_APP_STORAGE_S3_BUCKET=
_APP_STORAGE_DO_SPACES_ACCESS_KEY=
_APP_STORAGE_DO_SPACES_SECRET=
_APP_STORAGE_DO_SPACES_REGION=us-east-1
_APP_STORAGE_DO_SPACES_BUCKET=
_APP_STORAGE_BACKBLAZE_ACCESS_KEY=
_APP_STORAGE_BACKBLAZE_SECRET=
_APP_STORAGE_BACKBLAZE_REGION=us-west-004
_APP_STORAGE_BACKBLAZE_BUCKET=
_APP_STORAGE_LINODE_ACCESS_KEY=
_APP_STORAGE_LINODE_SECRET=
_APP_STORAGE_LINODE_REGION=eu-central-1
_APP_STORAGE_LINODE_BUCKET=
_APP_STORAGE_WASABI_ACCESS_KEY=
_APP_STORAGE_WASABI_SECRET=
_APP_STORAGE_WASABI_REGION=eu-central-1
_APP_STORAGE_WASABI_BUCKET=
_APP_FUNCTIONS_SIZE_LIMIT=30000000
_APP_FUNCTIONS_TIMEOUT=900
_APP_FUNCTIONS_BUILD_TIMEOUT=900
_APP_FUNCTIONS_CONTAINERS=10
_APP_FUNCTIONS_CPUS=0
_APP_FUNCTIONS_MEMORY=0
_APP_FUNCTIONS_MEMORY_SWAP=0
_APP_FUNCTIONS_RUNTIMES=node-20.0,php-8.2,python-3.11,ruby-3.2
_APP_EXECUTOR_HOST=http://appwrite-executor/v1
_APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes
_APP_FUNCTIONS_INACTIVE_THRESHOLD=60
DOCKERHUB_PULL_USERNAME=
DOCKERHUB_PULL_PASSWORD=
DOCKERHUB_PULL_EMAIL=
OPEN_RUNTIMES_NETWORK=appwrite_runtimes
_APP_FUNCTIONS_RUNTIMES_NETWORK=runtimes
_APP_DOCKER_HUB_USERNAME=
_APP_DOCKER_HUB_PASSWORD=
_APP_FUNCTIONS_MAINTENANCE_INTERVAL=3600
_APP_VCS_GITHUB_APP_NAME=
_APP_VCS_GITHUB_PRIVATE_KEY=
_APP_VCS_GITHUB_APP_ID=
_APP_VCS_GITHUB_CLIENT_ID=
_APP_VCS_GITHUB_CLIENT_SECRET=
_APP_VCS_GITHUB_WEBHOOK_SECRET=
_APP_MAINTENANCE_DELAY=
_APP_MAINTENANCE_INTERVAL=86400
_APP_MAINTENANCE_RETENTION_CACHE=2592000
_APP_MAINTENANCE_RETENTION_EXECUTION=1209600
_APP_MAINTENANCE_RETENTION_AUDIT=1209600
_APP_MAINTENANCE_RETENTION_ABUSE=86400
_APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000
_APP_MAINTENANCE_RETENTION_SCHEDULES=86400
_APP_GRAPHQL_MAX_BATCH_SIZE=10
_APP_GRAPHQL_MAX_COMPLEXITY=250
_APP_GRAPHQL_MAX_DEPTH=3
_APP_MIGRATIONS_FIREBASE_CLIENT_ID=
_APP_MIGRATIONS_FIREBASE_CLIENT_SECRET=
_APP_ASSISTANT_OPENAI_API_KEY=

View File

@@ -1,6 +1,5 @@
# documentation: https://appwrite.io
# slogan: A backend-as-a-service platform that simplifies the web & mobile app development.
# env_file: appwrite.env
# tags: backend-as-a-service, platform
# logo: svgs/appwrite.svg
@@ -28,97 +27,97 @@ services:
- appwrite-redis
environment:
- SERVICE_FQDN_APPWRITE=/
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_LOCALE
- _APP_CONSOLE_WHITELIST_ROOT
- _APP_CONSOLE_WHITELIST_EMAILS
- _APP_CONSOLE_WHITELIST_IPS
- _APP_CONSOLE_HOSTNAMES
- _APP_SYSTEM_EMAIL_NAME
- _APP_SYSTEM_EMAIL_ADDRESS
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_SYSTEM_RESPONSE_FORMAT
- _APP_OPTIONS_ABUSE
- _APP_OPTIONS_FORCE_HTTPS
- _APP_OPENSSL_KEY_V1
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_LOCALE=${_APP_LOCALE:-en}
- _APP_CONSOLE_WHITELIST_ROOT=${_APP_CONSOLE_WHITELIST_ROOT:-enabled}
- _APP_CONSOLE_WHITELIST_EMAILS=${_APP_CONSOLE_WHITELIST_EMAILS}
- _APP_CONSOLE_WHITELIST_IPS=${_APP_CONSOLE_WHITELIST_IPS}
- _APP_CONSOLE_HOSTNAMES=${_APP_CONSOLE_HOSTNAMES:-localhost,appwrite.io,*.appwrite.io}
- _APP_SYSTEM_EMAIL_NAME=${_APP_SYSTEM_EMAIL_NAME:-Appwrite}
- _APP_SYSTEM_EMAIL_ADDRESS=${_APP_SYSTEM_EMAIL_ADDRESS:-team@appwrite.io}
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS=${_APP_SYSTEM_SECURITY_EMAIL_ADDRESS:-certs@appwrite.io}
- _APP_SYSTEM_RESPONSE_FORMAT=${_APP_SYSTEM_RESPONSE_FORMAT}
- _APP_OPTIONS_ABUSE=${_APP_OPTIONS_ABUSE:-enabled}
- _APP_OPTIONS_FORCE_HTTPS=${_APP_OPTIONS_FORCE_HTTPS:-disabled}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_DOMAIN=$SERVICE_FQDN_APPWRITE
- _APP_DOMAIN_TARGET=$SERVICE_FQDN_APPWRITE
- _APP_DOMAIN_FUNCTIONS=$SERVICE_FQDN_APPWRITE
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_DB_ROOT_PASS=$SERVICE_PASSWORD_MARIADBROOT
- _APP_SMTP_HOST
- _APP_SMTP_PORT
- _APP_SMTP_SECURE
- _APP_SMTP_USERNAME
- _APP_SMTP_PASSWORD
- _APP_USAGE_STATS
- _APP_STORAGE_LIMIT
- _APP_STORAGE_PREVIEW_LIMIT
- _APP_STORAGE_ANTIVIRUS
- _APP_STORAGE_ANTIVIRUS_HOST
- _APP_STORAGE_ANTIVIRUS_PORT
- _APP_STORAGE_DEVICE
- _APP_STORAGE_S3_ACCESS_KEY
- _APP_STORAGE_S3_SECRET
- _APP_STORAGE_S3_REGION
- _APP_STORAGE_S3_BUCKET
- _APP_STORAGE_DO_SPACES_ACCESS_KEY
- _APP_STORAGE_DO_SPACES_SECRET
- _APP_STORAGE_DO_SPACES_REGION
- _APP_STORAGE_DO_SPACES_BUCKET
- _APP_STORAGE_BACKBLAZE_ACCESS_KEY
- _APP_STORAGE_BACKBLAZE_SECRET
- _APP_STORAGE_BACKBLAZE_REGION
- _APP_STORAGE_BACKBLAZE_BUCKET
- _APP_STORAGE_LINODE_ACCESS_KEY
- _APP_STORAGE_LINODE_SECRET
- _APP_STORAGE_LINODE_REGION
- _APP_STORAGE_LINODE_BUCKET
- _APP_STORAGE_WASABI_ACCESS_KEY
- _APP_STORAGE_WASABI_SECRET
- _APP_STORAGE_WASABI_REGION
- _APP_STORAGE_WASABI_BUCKET
- _APP_FUNCTIONS_SIZE_LIMIT
- _APP_FUNCTIONS_TIMEOUT
- _APP_FUNCTIONS_BUILD_TIMEOUT
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_FUNCTIONS_RUNTIMES
- _APP_SMTP_HOST=${_APP_SMTP_HOST}
- _APP_SMTP_PORT=${_APP_SMTP_PORT}
- _APP_SMTP_SECURE=${_APP_SMTP_SECURE}
- _APP_SMTP_USERNAME=${_APP_SMTP_USERNAME}
- _APP_SMTP_PASSWORD=${_APP_SMTP_PASSWORD}
- _APP_USAGE_STATS=${_APP_USAGE_STATS:-enabled}
- _APP_STORAGE_LIMIT=${_APP_STORAGE_LIMIT:-30000000}
- _APP_STORAGE_PREVIEW_LIMIT=${_APP_STORAGE_PREVIEW_LIMIT:-20000000}
- _APP_STORAGE_ANTIVIRUS=${_APP_STORAGE_ANTIVIRUS:-disabled}
- _APP_STORAGE_ANTIVIRUS_HOST=${_APP_STORAGE_ANTIVIRUS_HOST:-appwrite-clamav}
- _APP_STORAGE_ANTIVIRUS_PORT=${_APP_STORAGE_ANTIVIRUS_PORT:-3310}
- _APP_STORAGE_DEVICE=${_APP_STORAGE_DEVICE:-local}
- _APP_STORAGE_S3_ACCESS_KEY=${_APP_STORAGE_S3_ACCESS_KEY}
- _APP_STORAGE_S3_SECRET=${_APP_STORAGE_S3_SECRET}
- _APP_STORAGE_S3_REGION=${_APP_STORAGE_S3_REGION:-us-east-1}
- _APP_STORAGE_S3_BUCKET=${_APP_STORAGE_S3_BUCKET}
- _APP_STORAGE_DO_SPACES_ACCESS_KEY=${_APP_STORAGE_DO_SPACES_ACCESS_KEY}
- _APP_STORAGE_DO_SPACES_SECRET=${_APP_STORAGE_DO_SPACES_SECRET}
- _APP_STORAGE_DO_SPACES_REGION=${_APP_STORAGE_DO_SPACES_REGION:-us-east-1}
- _APP_STORAGE_DO_SPACES_BUCKET=${_APP_STORAGE_DO_SPACES_BUCKET}
- _APP_STORAGE_BACKBLAZE_ACCESS_KEY=${_APP_STORAGE_BACKBLAZE_ACCESS_KEY}
- _APP_STORAGE_BACKBLAZE_SECRET=${_APP_STORAGE_BACKBLAZE_SECRET}
- _APP_STORAGE_BACKBLAZE_REGION=${_APP_STORAGE_BACKBLAZE_REGION:-us-west-004}
- _APP_STORAGE_BACKBLAZE_BUCKET=${_APP_STORAGE_BACKBLAZE_BUCKET}
- _APP_STORAGE_LINODE_ACCESS_KEY=${_APP_STORAGE_LINODE_ACCESS_KEY}
- _APP_STORAGE_LINODE_SECRET=${_APP_STORAGE_LINODE_SECRET}
- _APP_STORAGE_LINODE_REGION=${_APP_STORAGE_LINODE_REGION:-eu-central-1}
- _APP_STORAGE_LINODE_BUCKET=${_APP_STORAGE_LINODE_BUCKET}
- _APP_STORAGE_WASABI_ACCESS_KEY=${_APP_STORAGE_WASABI_ACCESS_KEY}
- _APP_STORAGE_WASABI_SECRET=${_APP_STORAGE_WASABI_SECRET}
- _APP_STORAGE_WASABI_REGION=${_APP_STORAGE_WASABI_REGION:-eu-central-1}
- _APP_STORAGE_WASABI_BUCKET=${_APP_STORAGE_WASABI_BUCKET}
- _APP_FUNCTIONS_SIZE_LIMIT=${_APP_FUNCTIONS_SIZE_LIMIT:-30000000}
- _APP_FUNCTIONS_TIMEOUT=${_APP_FUNCTIONS_TIMEOUT:-900}
- _APP_FUNCTIONS_BUILD_TIMEOUT=${_APP_FUNCTIONS_BUILD_TIMEOUT:-900}
- _APP_FUNCTIONS_CPUS=${_APP_FUNCTIONS_CPUS:-0}
- _APP_FUNCTIONS_MEMORY=${_APP_FUNCTIONS_MEMORY:-0}
- _APP_FUNCTIONS_RUNTIMES=${_APP_FUNCTIONS_RUNTIMES:-node-20.0,php-8.2,python-3.11,ruby-3.2}
- _APP_EXECUTOR_SECRET=$SERVICE_PASSWORD_64_APPWRITE
- _APP_EXECUTOR_HOST
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_MAINTENANCE_INTERVAL
- _APP_MAINTENANCE_DELAY
- _APP_MAINTENANCE_RETENTION_EXECUTION
- _APP_MAINTENANCE_RETENTION_CACHE
- _APP_MAINTENANCE_RETENTION_ABUSE
- _APP_MAINTENANCE_RETENTION_AUDIT
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
- _APP_MAINTENANCE_RETENTION_SCHEDULES
- _APP_SMS_PROVIDER
- _APP_SMS_FROM
- _APP_GRAPHQL_MAX_BATCH_SIZE
- _APP_GRAPHQL_MAX_COMPLEXITY
- _APP_GRAPHQL_MAX_DEPTH
- _APP_VCS_GITHUB_APP_NAME
- _APP_VCS_GITHUB_PRIVATE_KEY
- _APP_VCS_GITHUB_APP_ID
- _APP_VCS_GITHUB_WEBHOOK_SECRET
- _APP_VCS_GITHUB_CLIENT_SECRET
- _APP_VCS_GITHUB_CLIENT_ID
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
- _APP_ASSISTANT_OPENAI_API_KEY
- _APP_EXECUTOR_HOST=${_APP_EXECUTOR_HOST:-http://appwrite-executor/v1}
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
- _APP_MAINTENANCE_INTERVAL=${_APP_MAINTENANCE_INTERVAL:-86400}
- _APP_MAINTENANCE_DELAY=${_APP_MAINTENANCE_DELAY}
- _APP_MAINTENANCE_RETENTION_EXECUTION=${_APP_MAINTENANCE_RETENTION_EXECUTION:-1209600}
- _APP_MAINTENANCE_RETENTION_CACHE=${_APP_MAINTENANCE_RETENTION_CACHE:-2592000}
- _APP_MAINTENANCE_RETENTION_ABUSE=${_APP_MAINTENANCE_RETENTION_ABUSE:-86400}
- _APP_MAINTENANCE_RETENTION_AUDIT=${_APP_MAINTENANCE_RETENTION_AUDIT:-1209600}
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY=${_APP_MAINTENANCE_RETENTION_USAGE_HOURLY:-8640000}
- _APP_MAINTENANCE_RETENTION_SCHEDULES=${_APP_MAINTENANCE_RETENTION_SCHEDULES:-86400}
- _APP_SMS_PROVIDER=${_APP_SMS_PROVIDER}
- _APP_SMS_FROM=${_APP_SMS_FROM}
- _APP_GRAPHQL_MAX_BATCH_SIZE=${_APP_GRAPHQL_MAX_BATCH_SIZE:-10}
- _APP_GRAPHQL_MAX_COMPLEXITY=${_APP_GRAPHQL_MAX_COMPLEXITY:-250}
- _APP_GRAPHQL_MAX_DEPTH=${_APP_GRAPHQL_MAX_DEPTH:-3}
- _APP_VCS_GITHUB_APP_NAME=${_APP_VCS_GITHUB_APP_NAME}
- _APP_VCS_GITHUB_PRIVATE_KEY=${_APP_VCS_GITHUB_PRIVATE_KEY}
- _APP_VCS_GITHUB_APP_ID=${_APP_VCS_GITHUB_APP_ID}
- _APP_VCS_GITHUB_WEBHOOK_SECRET=${_APP_VCS_GITHUB_WEBHOOK_SECRET}
- _APP_VCS_GITHUB_CLIENT_SECRET=${_APP_VCS_GITHUB_CLIENT_SECRET}
- _APP_VCS_GITHUB_CLIENT_ID=${_APP_VCS_GITHUB_CLIENT_ID}
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID=${_APP_MIGRATIONS_FIREBASE_CLIENT_ID}
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET=${_APP_MIGRATIONS_FIREBASE_CLIENT_SECRET}
- _APP_ASSISTANT_OPENAI_API_KEY=${_APP_ASSISTANT_OPENAI_API_KEY}
appwrite-realtime:
image: appwrite/appwrite:1.5
@@ -129,22 +128,22 @@ services:
- appwrite-redis
environment:
- SERVICE_FQDN_APPWRITE=/v1/realtime
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPTIONS_ABUSE
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_USAGE_STATS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPTIONS_ABUSE=${_APP_OPTIONS_ABUSE:-enabled}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_USAGE_STATS=${_APP_USAGE_STATS:-enabled}
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
appwrite-worker-audits:
image: appwrite/appwrite:1.5
@@ -155,20 +154,20 @@ services:
- appwrite-redis
- appwrite-mariadb
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
appwrite-worker-webhooks:
image: appwrite/appwrite:1.5
@@ -179,16 +178,16 @@ services:
- appwrite-redis
- appwrite-mariadb
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS=${_APP_SYSTEM_SECURITY_EMAIL_ADDRESS:-certs@appwrite.io}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
appwrite-worker-deletes:
image: appwrite/appwrite:1.5
@@ -205,43 +204,43 @@ services:
- appwrite-builds:/storage/builds:rw
- appwrite-certificates:/storage/certificates:rw
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_STORAGE_DEVICE
- _APP_STORAGE_S3_ACCESS_KEY
- _APP_STORAGE_S3_SECRET
- _APP_STORAGE_S3_REGION
- _APP_STORAGE_S3_BUCKET
- _APP_STORAGE_DO_SPACES_ACCESS_KEY
- _APP_STORAGE_DO_SPACES_SECRET
- _APP_STORAGE_DO_SPACES_REGION
- _APP_STORAGE_DO_SPACES_BUCKET
- _APP_STORAGE_BACKBLAZE_ACCESS_KEY
- _APP_STORAGE_BACKBLAZE_SECRET
- _APP_STORAGE_BACKBLAZE_REGION
- _APP_STORAGE_BACKBLAZE_BUCKET
- _APP_STORAGE_LINODE_ACCESS_KEY
- _APP_STORAGE_LINODE_SECRET
- _APP_STORAGE_LINODE_REGION
- _APP_STORAGE_LINODE_BUCKET
- _APP_STORAGE_WASABI_ACCESS_KEY
- _APP_STORAGE_WASABI_SECRET
- _APP_STORAGE_WASABI_REGION
- _APP_STORAGE_WASABI_BUCKET
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_STORAGE_DEVICE=${_APP_STORAGE_DEVICE:-local}
- _APP_STORAGE_S3_ACCESS_KEY=${_APP_STORAGE_S3_ACCESS_KEY:-local}
- _APP_STORAGE_S3_SECRET=${_APP_STORAGE_S3_SECRET}
- _APP_STORAGE_S3_REGION=${_APP_STORAGE_S3_REGION:-us-east-1}
- _APP_STORAGE_S3_BUCKET=${_APP_STORAGE_S3_BUCKET}
- _APP_STORAGE_DO_SPACES_ACCESS_KEY=${_APP_STORAGE_DO_SPACES_ACCESS_KEY}
- _APP_STORAGE_DO_SPACES_SECRET=${_APP_STORAGE_DO_SPACES_SECRET}
- _APP_STORAGE_DO_SPACES_REGION=${_APP_STORAGE_DO_SPACES_REGION:-us-east-1}
- _APP_STORAGE_DO_SPACES_BUCKET=${_APP_STORAGE_DO_SPACES_BUCKET}
- _APP_STORAGE_BACKBLAZE_ACCESS_KEY=${_APP_STORAGE_BACKBLAZE_ACCESS_KEY}
- _APP_STORAGE_BACKBLAZE_SECRET=${_APP_STORAGE_BACKBLAZE_SECRET}
- _APP_STORAGE_BACKBLAZE_REGION=${_APP_STORAGE_BACKBLAZE_REGION:-us-west-004}
- _APP_STORAGE_BACKBLAZE_BUCKET=${_APP_STORAGE_BACKBLAZE_BUCKET}
- _APP_STORAGE_LINODE_ACCESS_KEY=${_APP_STORAGE_LINODE_ACCESS_KEY}
- _APP_STORAGE_LINODE_SECRET=${_APP_STORAGE_LINODE_SECRET}
- _APP_STORAGE_LINODE_REGION=${_APP_STORAGE_LINODE_REGION:-eu-central-1}
- _APP_STORAGE_LINODE_BUCKET=${_APP_STORAGE_LINODE_BUCKET}
- _APP_STORAGE_WASABI_ACCESS_KEY=${_APP_STORAGE_WASABI_ACCESS_KEY}
- _APP_STORAGE_WASABI_SECRET=${_APP_STORAGE_WASABI_SECRET}
- _APP_STORAGE_WASABI_REGION=${_APP_STORAGE_WASABI_REGION:-eu-central-1}
- _APP_STORAGE_WASABI_BUCKET=${_APP_STORAGE_WASABI_BUCKET}
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
- _APP_EXECUTOR_SECRET=$SERVICE_PASSWORD_64_APPWRITE
- _APP_EXECUTOR_HOST=${_APP_EXECUTOR_HOST:-http://appwrite-executor/v1}
appwrite-worker-databases:
image: appwrite/appwrite:1.5
@@ -252,20 +251,20 @@ services:
- appwrite-redis
- appwrite-mariadb
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
appwrite-worker-builds:
image: appwrite/appwrite:1.5
@@ -279,52 +278,52 @@ services:
- appwrite-functions:/storage/functions:rw
- appwrite-builds:/storage/builds:rw
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_VCS_GITHUB_APP_NAME
- _APP_VCS_GITHUB_PRIVATE_KEY
- _APP_VCS_GITHUB_APP_ID
- _APP_FUNCTIONS_TIMEOUT
- _APP_FUNCTIONS_BUILD_TIMEOUT
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_OPTIONS_FORCE_HTTPS
- _APP_DOMAIN
- _APP_STORAGE_DEVICE
- _APP_STORAGE_S3_ACCESS_KEY
- _APP_STORAGE_S3_SECRET
- _APP_STORAGE_S3_REGION
- _APP_STORAGE_S3_BUCKET
- _APP_STORAGE_DO_SPACES_ACCESS_KEY
- _APP_STORAGE_DO_SPACES_SECRET
- _APP_STORAGE_DO_SPACES_REGION
- _APP_STORAGE_DO_SPACES_BUCKET
- _APP_STORAGE_BACKBLAZE_ACCESS_KEY
- _APP_STORAGE_BACKBLAZE_SECRET
- _APP_STORAGE_BACKBLAZE_REGION
- _APP_STORAGE_BACKBLAZE_BUCKET
- _APP_STORAGE_LINODE_ACCESS_KEY
- _APP_STORAGE_LINODE_SECRET
- _APP_STORAGE_LINODE_REGION
- _APP_STORAGE_LINODE_BUCKET
- _APP_STORAGE_WASABI_ACCESS_KEY
- _APP_STORAGE_WASABI_SECRET
- _APP_STORAGE_WASABI_REGION
- _APP_STORAGE_WASABI_BUCKET
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_EXECUTOR_SECRET=$SERVICE_PASSWORD_64_APPWRITE
- _APP_EXECUTOR_HOST=${_APP_EXECUTOR_HOST:-http://appwrite-executor/v1}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
- _APP_VCS_GITHUB_APP_NAME=${_APP_VCS_GITHUB_APP_NAME}
- _APP_VCS_GITHUB_PRIVATE_KEY=${_APP_VCS_GITHUB_PRIVATE_KEY}
- _APP_VCS_GITHUB_APP_ID=${_APP_VCS_GITHUB_APP_ID}
- _APP_FUNCTIONS_TIMEOUT=${_APP_FUNCTIONS_TIMEOUT:-900}
- _APP_FUNCTIONS_BUILD_TIMEOUT=${_APP_FUNCTIONS_BUILD_TIMEOUT:-900}
- _APP_FUNCTIONS_CPUS=${_APP_FUNCTIONS_CPUS:-0}
- _APP_FUNCTIONS_MEMORY=${_APP_FUNCTIONS_MEMORY:-0}
- _APP_OPTIONS_FORCE_HTTPS=${_APP_OPTIONS_FORCE_HTTPS:-disabled}
- _APP_DOMAIN=$SERVICE_FQDN_APPWRITE
- _APP_STORAGE_DEVICE=${_APP_STORAGE_DEVICE:-local}
- _APP_STORAGE_S3_ACCESS_KEY=${_APP_STORAGE_S3_ACCESS_KEY:-local}
- _APP_STORAGE_S3_SECRET=${_APP_STORAGE_S3_SECRET}
- _APP_STORAGE_S3_REGION=${_APP_STORAGE_S3_REGION:-us-east-1}
- _APP_STORAGE_S3_BUCKET=${_APP_STORAGE_S3_BUCKET}
- _APP_STORAGE_DO_SPACES_ACCESS_KEY=${_APP_STORAGE_DO_SPACES_ACCESS_KEY}
- _APP_STORAGE_DO_SPACES_SECRET=${_APP_STORAGE_DO_SPACES_SECRET}
- _APP_STORAGE_DO_SPACES_REGION=${_APP_STORAGE_DO_SPACES_REGION:-us-east-1}
- _APP_STORAGE_DO_SPACES_BUCKET=${_APP_STORAGE_DO_SPACES_BUCKET}
- _APP_STORAGE_BACKBLAZE_ACCESS_KEY=${_APP_STORAGE_BACKBLAZE_ACCESS_KEY}
- _APP_STORAGE_BACKBLAZE_SECRET=${_APP_STORAGE_BACKBLAZE_SECRET}
- _APP_STORAGE_BACKBLAZE_REGION=${_APP_STORAGE_BACKBLAZE_REGION:-us-west-004}
- _APP_STORAGE_BACKBLAZE_BUCKET=${_APP_STORAGE_BACKBLAZE_BUCKET}
- _APP_STORAGE_LINODE_ACCESS_KEY=${_APP_STORAGE_LINODE_ACCESS_KEY}
- _APP_STORAGE_LINODE_SECRET=${_APP_STORAGE_LINODE_SECRET}
- _APP_STORAGE_LINODE_REGION=${_APP_STORAGE_LINODE_REGION:-eu-central-1}
- _APP_STORAGE_LINODE_BUCKET=${_APP_STORAGE_LINODE_BUCKET}
- _APP_STORAGE_WASABI_ACCESS_KEY=${_APP_STORAGE_WASABI_ACCESS_KEY}
- _APP_STORAGE_WASABI_SECRET=${_APP_STORAGE_WASABI_SECRET}
- _APP_STORAGE_WASABI_REGION=${_APP_STORAGE_WASABI_REGION:-eu-central-1}
- _APP_STORAGE_WASABI_BUCKET=${_APP_STORAGE_WASABI_BUCKET}
appwrite-worker-certificates:
image: appwrite/appwrite:1.5
@@ -338,24 +337,24 @@ services:
- appwrite-config:/storage/config:rw
- appwrite-certificates:/storage/certificates:rw
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET
- _APP_DOMAIN_FUNCTIONS
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_DOMAIN=$SERVICE_FQDN_APPWRITE
- _APP_DOMAIN_TARGET=$SERVICE_FQDN_APPWRITE
- _APP_DOMAIN_FUNCTIONS=$SERVICE_FQDN_APPWRITE
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS=${_APP_SYSTEM_SECURITY_EMAIL_ADDRESS:-certs@appwrite.io}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
appwrite-worker-functions:
image: appwrite/appwrite:1.5
@@ -367,29 +366,30 @@ services:
- appwrite-mariadb
- openruntimes-executor
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_FUNCTIONS_TIMEOUT
- _APP_FUNCTIONS_BUILD_TIMEOUT
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
- _APP_USAGE_STATS
- _APP_DOCKER_HUB_USERNAME
- _APP_DOCKER_HUB_PASSWORD
- _APP_LOGGING_CONFIG
- _APP_LOGGING_PROVIDER
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_FUNCTIONS_TIMEOUT=${_APP_FUNCTIONS_TIMEOUT:-900}
- _APP_FUNCTIONS_BUILD_TIMEOUT=${_APP_FUNCTIONS_BUILD_TIMEOUT:-900}
- _APP_FUNCTIONS_CPUS=${_APP_FUNCTIONS_CPUS:-0}
- _APP_FUNCTIONS_MEMORY=${_APP_FUNCTIONS_MEMORY:-0}
- _APP_EXECUTOR_SECRET=$SERVICE_PASSWORD_64_APPWRITE
- _APP_EXECUTOR_HOST=${_APP_EXECUTOR_HOST:-http://appwrite-executor/v1}
- _APP_USAGE_STATS=${_APP_USAGE_STATS:-enabled}
- _APP_DOCKER_HUB_USERNAME=${_APP_DOCKER_HUB_USERNAME}
- _APP_DOCKER_HUB_PASSWORD=${_APP_DOCKER_HUB_PASSWORD}
- _APP_DOCKER_HUB_EMAIL=${_APP_DOCKER_HUB_EMAIL}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
appwrite-worker-mails:
image: appwrite/appwrite:1.5
@@ -399,22 +399,22 @@ services:
depends_on:
- appwrite-redis
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_SYSTEM_EMAIL_NAME
- _APP_SYSTEM_EMAIL_ADDRESS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_SMTP_HOST
- _APP_SMTP_PORT
- _APP_SMTP_SECURE
- _APP_SMTP_USERNAME
- _APP_SMTP_PASSWORD
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_SYSTEM_EMAIL_NAME=${_APP_SYSTEM_EMAIL_NAME:-Appwrite}
- _APP_SYSTEM_EMAIL_ADDRESS=${_APP_SYSTEM_EMAIL_ADDRESS:-team@appwrite.io}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_SMTP_HOST=${_APP_SMTP_HOST}
- _APP_SMTP_PORT=${_APP_SMTP_PORT}
- _APP_SMTP_SECURE=${_APP_SMTP_SECURE}
- _APP_SMTP_USERNAME=${_APP_SMTP_USERNAME}
- _APP_SMTP_PASSWORD=${_APP_SMTP_PASSWORD}
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
appwrite-worker-messaging:
image: appwrite/appwrite:1.5
@@ -424,22 +424,22 @@ services:
depends_on:
- appwrite-redis
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_SMS_FROM
- _APP_SMS_PROVIDER
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
- _APP_SMS_FROM=${_APP_SMS_FROM}
- _APP_SMS_PROVIDER=${_APP_SMS_PROVIDER}
appwrite-worker-migrations:
image: appwrite/appwrite:1.5
@@ -449,25 +449,25 @@ services:
depends_on:
- appwrite-mariadb
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_DOMAIN=$SERVICE_FQDN_APPWRITE
- _APP_DOMAIN_TARGET=$SERVICE_FQDN_APPWRITE
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS=${_APP_SYSTEM_SECURITY_EMAIL_ADDRESS:-certs@appwrite.io}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID=${_APP_MIGRATIONS_FIREBASE_CLIENT_ID}
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET=${_APP_MIGRATIONS_FIREBASE_CLIENT_SECRET}
appwrite-maintenance:
image: appwrite/appwrite:1.5
@@ -477,28 +477,28 @@ services:
depends_on:
- appwrite-redis
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_DOMAIN
- _APP_DOMAIN_TARGET
- _APP_DOMAIN_FUNCTIONS
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_MAINTENANCE_INTERVAL
- _APP_MAINTENANCE_RETENTION_EXECUTION
- _APP_MAINTENANCE_RETENTION_CACHE
- _APP_MAINTENANCE_RETENTION_ABUSE
- _APP_MAINTENANCE_RETENTION_AUDIT
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
- _APP_MAINTENANCE_RETENTION_SCHEDULES
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_DOMAIN=$SERVICE_FQDN_APPWRITE
- _APP_DOMAIN_TARGET=$SERVICE_FQDN_APPWRITE
- _APP_DOMAIN_FUNCTIONS=$SERVICE_FQDN_APPWRITE
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_MAINTENANCE_INTERVAL=${_APP_MAINTENANCE_INTERVAL}
- _APP_MAINTENANCE_RETENTION_EXECUTION=${_APP_MAINTENANCE_RETENTION_EXECUTION}
- _APP_MAINTENANCE_RETENTION_CACHE=${_APP_MAINTENANCE_RETENTION_CACHE:-2592000}
- _APP_MAINTENANCE_RETENTION_ABUSE=${_APP_MAINTENANCE_RETENTION_ABUSE:-86400}
- _APP_MAINTENANCE_RETENTION_AUDIT=${_APP_MAINTENANCE_RETENTION_AUDIT:-1209600}
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY=${_APP_MAINTENANCE_RETENTION_USAGE_HOURLY:-8640000}
- _APP_MAINTENANCE_RETENTION_SCHEDULES=${_APP_MAINTENANCE_RETENTION_SCHEDULES:-86400}
appwrite-worker-usage:
image: appwrite/appwrite:1.5
@@ -510,22 +510,22 @@ services:
- appwrite-redis
- appwrite-mariadb
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_USAGE_STATS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_USAGE_AGGREGATION_INTERVAL
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_USAGE_STATS=${_APP_USAGE_STATS:-enabled}
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
- _APP_USAGE_AGGREGATION_INTERVAL=${_APP_USAGE_AGGREGATION_INTERVAL:-30}
appwrite-worker-usage-dump:
image: appwrite/appwrite:1.5
@@ -536,22 +536,22 @@ services:
- appwrite-redis
- appwrite-mariadb
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_USAGE_STATS
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_USAGE_AGGREGATION_INTERVAL
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_USAGE_STATS=${_APP_USAGE_STATS:-enabled}
- _APP_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- _APP_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
- _APP_USAGE_AGGREGATION_INTERVAL=${_APP_USAGE_AGGREGATION_INTERVAL:-30}
appwrite-scheduler-functions:
image: appwrite/appwrite:1.5
@@ -563,18 +563,18 @@ services:
- appwrite-mariadb
- appwrite-redis
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
appwrite-scheduler-messages:
image: appwrite/appwrite:1.5
@@ -586,18 +586,18 @@ services:
- appwrite-mariadb
- appwrite-redis
environment:
- _APP_ENV
- _APP_WORKER_PER_CORE
- _APP_OPENSSL_KEY_V1
- _APP_REDIS_HOST
- _APP_REDIS_PORT
- _APP_REDIS_USER
- _APP_REDIS_PASS
- _APP_DB_HOST
- _APP_DB_PORT
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_ENV=${_APP_ENV:-production}
- _APP_WORKER_PER_CORE=${_APP_WORKER_PER_CORE:-6}
- _APP_OPENSSL_KEY_V1=${_APP_OPENSSL_KEY_V1}
- _APP_REDIS_HOST=${_APP_REDIS_HOST:-appwrite-redis}
- _APP_REDIS_PORT=${_APP_REDIS_PORT:-6379}
- _APP_REDIS_USER=${_APP_REDIS_USER}
- _APP_REDIS_PASS=${_APP_REDIS_PASS}
- _APP_DB_HOST=${_APP_DB_HOST:-appwrite-mariadb}
- _APP_DB_PORT=${_APP_DB_PORT:-3306}
- _APP_DB_SCHEMA=${_APP_DB_SCHEMA:-appwrite}
- _APP_DB_USER=$SERVICE_USER_MARIADB
- _APP_DB_PASS=$SERVICE_PASSWORD_MARIADB
appwrite-assistant:
image: appwrite/assistant:0.4.0
@@ -616,37 +616,37 @@ services:
- appwrite-functions:/storage/functions:rw
- /tmp:/tmp:rw
environment:
- OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_FUNCTIONS_INACTIVE_THRESHOLD
- OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_FUNCTIONS_MAINTENANCE_INTERVAL
- OPR_EXECUTOR_NETWORK=$_APP_FUNCTIONS_RUNTIMES_NETWORK
- OPR_EXECUTOR_DOCKER_HUB_USERNAME=$_APP_DOCKER_HUB_USERNAME
- OPR_EXECUTOR_DOCKER_HUB_PASSWORD=$_APP_DOCKER_HUB_PASSWORD
- OPR_EXECUTOR_ENV=$_APP_ENV
- OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES
- OPR_EXECUTOR_SECRET=$_APP_EXECUTOR_SECRET
- OPR_EXECUTOR_LOGGING_PROVIDER=$_APP_LOGGING_PROVIDER
- OPR_EXECUTOR_LOGGING_CONFIG=$_APP_LOGGING_CONFIG
- OPR_EXECUTOR_STORAGE_DEVICE=$_APP_STORAGE_DEVICE
- OPR_EXECUTOR_STORAGE_S3_ACCESS_KEY=$_APP_STORAGE_S3_ACCESS_KEY
- OPR_EXECUTOR_STORAGE_S3_SECRET=$_APP_STORAGE_S3_SECRET
- OPR_EXECUTOR_STORAGE_S3_REGION=$_APP_STORAGE_S3_REGION
- OPR_EXECUTOR_STORAGE_S3_BUCKET=$_APP_STORAGE_S3_BUCKET
- OPR_EXECUTOR_STORAGE_DO_SPACES_ACCESS_KEY=$_APP_STORAGE_DO_SPACES_ACCESS_KEY
- OPR_EXECUTOR_STORAGE_DO_SPACES_SECRET=$_APP_STORAGE_DO_SPACES_SECRET
- OPR_EXECUTOR_STORAGE_DO_SPACES_REGION=$_APP_STORAGE_DO_SPACES_REGION
- OPR_EXECUTOR_STORAGE_DO_SPACES_BUCKET=$_APP_STORAGE_DO_SPACES_BUCKET
- OPR_EXECUTOR_STORAGE_BACKBLAZE_ACCESS_KEY=$_APP_STORAGE_BACKBLAZE_ACCESS_KEY
- OPR_EXECUTOR_STORAGE_BACKBLAZE_SECRET=$_APP_STORAGE_BACKBLAZE_SECRET
- OPR_EXECUTOR_STORAGE_BACKBLAZE_REGION=$_APP_STORAGE_BACKBLAZE_REGION
- OPR_EXECUTOR_STORAGE_BACKBLAZE_BUCKET=$_APP_STORAGE_BACKBLAZE_BUCKET
- OPR_EXECUTOR_STORAGE_LINODE_ACCESS_KEY=$_APP_STORAGE_LINODE_ACCESS_KEY
- OPR_EXECUTOR_STORAGE_LINODE_SECRET=$_APP_STORAGE_LINODE_SECRET
- OPR_EXECUTOR_STORAGE_LINODE_REGION=$_APP_STORAGE_LINODE_REGION
- OPR_EXECUTOR_STORAGE_LINODE_BUCKET=$_APP_STORAGE_LINODE_BUCKET
- OPR_EXECUTOR_STORAGE_WASABI_ACCESS_KEY=$_APP_STORAGE_WASABI_ACCESS_KEY
- OPR_EXECUTOR_STORAGE_WASABI_SECRET=$_APP_STORAGE_WASABI_SECRET
- OPR_EXECUTOR_STORAGE_WASABI_REGION=$_APP_STORAGE_WASABI_REGION
- OPR_EXECUTOR_STORAGE_WASABI_BUCKET=$_APP_STORAGE_WASABI_BUCKET
- OPR_EXECUTOR_INACTIVE_TRESHOLD=${_APP_FUNCTIONS_INACTIVE_THRESHOLD}
- OPR_EXECUTOR_MAINTENANCE_INTERVAL=${_APP_FUNCTIONS_MAINTENANCE_INTERVAL}
- OPR_EXECUTOR_NETWORK=${_APP_FUNCTIONS_RUNTIMES_NETWORK}
- OPR_EXECUTOR_DOCKER_HUB_USERNAME=${_APP_DOCKER_HUB_USERNAME}
- OPR_EXECUTOR_DOCKER_HUB_PASSWORD=${_APP_DOCKER_HUB_PASSWORD}
- OPR_EXECUTOR_ENV=${_APP_ENV:-production}
- OPR_EXECUTOR_RUNTIMES=${_APP_FUNCTIONS_RUNTIMES}
- OPR_EXECUTOR_SECRET=$SERVICE_PASSWORD_64_APPWRITE
- OPR_EXECUTOR_LOGGING_PROVIDER=${_APP_LOGGING_PROVIDER}
- OPR_EXECUTOR_LOGGING_CONFIG=${_APP_LOGGING_CONFIG}
- OPR_EXECUTOR_STORAGE_DEVICE=${_APP_STORAGE_DEVICE:-local}
- OPR_EXECUTOR_STORAGE_S3_ACCESS_KEY=${_APP_STORAGE_S3_ACCESS_KEY:-local}
- OPR_EXECUTOR_STORAGE_S3_SECRET=${_APP_STORAGE_S3_SECRET}
- OPR_EXECUTOR_STORAGE_S3_REGION=${_APP_STORAGE_S3_REGION}
- OPR_EXECUTOR_STORAGE_S3_BUCKET=${_APP_STORAGE_S3_BUCKET}
- OPR_EXECUTOR_STORAGE_DO_SPACES_ACCESS_KEY=${_APP_STORAGE_DO_SPACES_ACCESS_KEY}
- OPR_EXECUTOR_STORAGE_DO_SPACES_SECRET=${_APP_STORAGE_DO_SPACES_SECRET}
- OPR_EXECUTOR_STORAGE_DO_SPACES_REGION=${_APP_STORAGE_DO_SPACES_REGION}
- OPR_EXECUTOR_STORAGE_DO_SPACES_BUCKET=${_APP_STORAGE_DO_SPACES_BUCKET}
- OPR_EXECUTOR_STORAGE_BACKBLAZE_ACCESS_KEY=${_APP_STORAGE_BACKBLAZE_ACCESS_KEY}
- OPR_EXECUTOR_STORAGE_BACKBLAZE_SECRET=${_APP_STORAGE_BACKBLAZE_SECRET}
- OPR_EXECUTOR_STORAGE_BACKBLAZE_REGION=${_APP_STORAGE_BACKBLAZE_REGION}
- OPR_EXECUTOR_STORAGE_BACKBLAZE_BUCKET=${_APP_STORAGE_BACKBLAZE_BUCKET}
- OPR_EXECUTOR_STORAGE_LINODE_ACCESS_KEY=${_APP_STORAGE_LINODE_ACCESS_KEY}
- OPR_EXECUTOR_STORAGE_LINODE_SECRET=${_APP_STORAGE_LINODE_SECRET}
- OPR_EXECUTOR_STORAGE_LINODE_REGION=${_APP_STORAGE_LINODE_REGION}
- OPR_EXECUTOR_STORAGE_LINODE_BUCKET=${_APP_STORAGE_LINODE_BUCKET}
- OPR_EXECUTOR_STORAGE_WASABI_ACCESS_KEY=${_APP_STORAGE_WASABI_ACCESS_KEY}
- OPR_EXECUTOR_STORAGE_WASABI_SECRET=${_APP_STORAGE_WASABI_SECRET}
- OPR_EXECUTOR_STORAGE_WASABI_REGION=${_APP_STORAGE_WASABI_REGION}
- OPR_EXECUTOR_STORAGE_WASABI_BUCKET=${_APP_STORAGE_WASABI_BUCKET}
appwrite-mariadb:
image: mariadb:10.11
@@ -655,10 +655,10 @@ services:
volumes:
- appwrite-mariadb:/var/lib/mysql:rw
environment:
- MYSQL_ROOT_PASSWORD=${_APP_DB_ROOT_PASS}
- MYSQL_DATABASE=${_APP_DB_SCHEMA}
- MYSQL_USER=${_APP_DB_USER}
- MYSQL_PASSWORD=${_APP_DB_PASS}
- MYSQL_ROOT_PASSWORD=$SERVICE_PASSWORD_MARIADBROOT
- MYSQL_DATABASE=${_APP_DB_SCHEMA:-appwrite}
- MYSQL_USER=$SERVICE_USER_MARIADB
- MYSQL_PASSWORD=$SERVICE_PASSWORD_MARIADB
command: 'mysqld --innodb-flush-method=fsync'
appwrite-redis:
image: redis:7.2.4-alpine

View File

@@ -5,41 +5,17 @@
# port: 9000
services:
postgresql:
image: docker.io/library/postgres:12-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
interval: 2s
timeout: 10s
retries: 15
volumes:
- authentik-db:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
- POSTGRES_USER=${SERVICE_USER_POSTGRESQL}
- POSTGRES_DB=authentik
redis:
image: docker.io/library/redis:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 2s
timeout: 10s
retries: 15
volumes:
- redis:/data
authentik-server:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2024.2.2}
restart: unless-stopped
command: server
environment:
- SERVICE_FQDN_AUTHENTIKSERVER_9000
- AUTHENTIK_REDIS__HOST=redis
- AUTHENTIK_POSTGRESQL__HOST=postgresql
- AUTHENTIK_REDIS__HOST=${REDIS_HOST:-redis}
- AUTHENTIK_POSTGRESQL__HOST=${POSTGRES_HOST:-postgresql}
- AUTHENTIK_POSTGRESQL__USER=${SERVICE_USER_POSTGRESQL}
- AUTHENTIK_POSTGRESQL__NAME=authentik
- AUTHENTIK_POSTGRESQL__NAME=${POSTGRES_DB:-authentik}
- AUTHENTIK_POSTGRESQL__PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
- AUTHENTIK_SECRET_KEY=${SERVICE_PASSWORD_64_AUTHENTIKSERVER}
- AUTHENTIK_ERROR_REPORTING__ENABLED=${AUTHENTIK_ERROR_REPORTING__ENABLED:-true}
@@ -64,10 +40,10 @@ services:
restart: unless-stopped
command: worker
environment:
- AUTHENTIK_REDIS__HOST=redis
- AUTHENTIK_POSTGRESQL__HOST=postgresql
- AUTHENTIK_REDIS__HOST=${REDIS_HOST:-redis}
- AUTHENTIK_POSTGRESQL__HOST=${POSTGRES_HOST:-postgresql}
- AUTHENTIK_POSTGRESQL__USER=${SERVICE_USER_POSTGRESQL}
- AUTHENTIK_POSTGRESQL__NAME=authentik
- AUTHENTIK_POSTGRESQL__NAME=${POSTGRES_DB:-authentik}
- AUTHENTIK_POSTGRESQL__PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
- AUTHENTIK_SECRET_KEY=${SERVICE_PASSWORD_64_AUTHENTIKSERVER}
- AUTHENTIK_ERROR_REPORTING__ENABLED=${AUTHENTIK_ERROR_REPORTING__ENABLED}
@@ -96,3 +72,28 @@ services:
condition: service_healthy
redis:
condition: service_healthy
postgresql:
image: docker.io/library/postgres:12-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
interval: 2s
timeout: 10s
retries: 15
volumes:
- authentik-db:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
- POSTGRES_USER=${SERVICE_USER_POSTGRESQL}
- POSTGRES_DB=${POSTGRES_DB:-authentik}
redis:
image: docker.io/library/redis:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 2s
timeout: 10s
retries: 15
volumes:
- redis:/data

View File

@@ -8,8 +8,8 @@ services:
browserless:
image: ghcr.io/browserless/chromium
environment:
- TOKEN=$SERVICE_BASE64_BROWSERLESS_TOKEN
- SERVICE_FQDN_BROWSERLESS_3000
- TOKEN=$SERVICE_BASE64_BROWSERLESS_TOKEN
expose:
- 3000
healthcheck:

View File

@@ -16,7 +16,7 @@ services:
environment:
- SERVICE_FQDN_PLUNK_3000
- REDIS_URL=redis://redis:6379
- DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql/docmost?schema=public
- DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql/plunk?schema=public
- JWT_SECRET=${SERVICE_PASSWORD_JWT_SECRET}
- AWS_REGION=${AWS_REGION}
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}

File diff suppressed because one or more lines are too long

View File

@@ -88,114 +88,64 @@ networks:
]);
$this->serviceYaml = '
services:
chatwoot:
image: chatwoot/chatwoot:latest
depends_on:
- postgres
- redis
activepieces:
image: "ghcr.io/activepieces/activepieces:latest"
environment:
- SERVICE_FQDN_CHATWOOT_3000
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
- FORCE_SSL=false
- ENABLE_ACCOUNT_SIGNUP=false
- REDIS_URL=redis://default@redis:6379
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
- REDIS_OPENSSL_VERIFY_MODE=none
- POSTGRES_DATABASE=chatwoot
- POSTGRES_HOST=postgres
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
- RAILS_MAX_THREADS=5
- NODE_ENV=production
- RAILS_ENV=production
- INSTALLATION_ENV=docker
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
- SMTP_DOMAIN=${CHATWOOT_SMTP_DOMAIN}
- SMTP_ENABLE_STARTTLS_AUTO=${CHATWOOT_SMTP_ENABLE_STARTTLS_AUTO}
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
- ACTIVE_STORAGE_SERVICE=local
entrypoint: docker/entrypoints/rails.sh
command: sh -c "bundle exec rails db:chatwoot_prepare && bundle exec rails s -p 3000 -b 0.0.0.0"
volumes:
- rails-data:/app/storage
- SERVICE_FQDN_ACTIVEPIECES
- AP_API_KEY=$SERVICE_PASSWORD_64_APIKEY
- AP_ENCRYPTION_KEY=$SERVICE_PASSWORD_ENCRYPTIONKEY
- AP_ENGINE_EXECUTABLE_PATH=dist/packages/engine/main.js
- AP_ENVIRONMENT=prod
- AP_EXECUTION_MODE=${AP_EXECUTION_MODE}
- AP_FRONTEND_URL=$SERVICE_FQDN_ACTIVEPIECES
- AP_JWT_SECRET=$SERVICE_PASSWORD_64_JWT
- AP_POSTGRES_DATABASE=activepieces
- AP_POSTGRES_HOST=postgres
- AP_POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
- AP_POSTGRES_PORT=5432
- AP_POSTGRES_USERNAME=$SERVICE_USER_POSTGRES
- AP_REDIS_HOST=redis
- AP_REDIS_PORT=6379
- AP_SANDBOX_RUN_TIME_SECONDS=600
- AP_TELEMETRY_ENABLED=true
- "AP_TEMPLATES_SOURCE_URL=https://cloud.activepieces.com/api/v1/flow-templates"
- AP_TRIGGER_DEFAULT_POLL_INTERVAL=5
- AP_WEBHOOK_TIMEOUT_SECONDS=30
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:3000"]
test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 5s
timeout: 20s
retries: 10
sidekiq:
image: chatwoot/chatwoot:latest
depends_on:
- postgres
- redis
environment:
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
- FORCE_SSL=false
- ENABLE_ACCOUNT_SIGNUP=false
- REDIS_URL=redis://default@redis:6379
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
- REDIS_OPENSSL_VERIFY_MODE=none
- POSTGRES_DATABASE=chatwoot
- POSTGRES_HOST=postgres
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
- RAILS_MAX_THREADS=5
- NODE_ENV=production
- RAILS_ENV=production
- INSTALLATION_ENV=docker
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
- SMTP_DOMAIN=${CHATWOOT_SMTP_DOMAIN}
- SMTP_ENABLE_STARTTLS_AUTO=${CHATWOOT_SMTP_ENABLE_STARTTLS_AUTO}
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
- ACTIVE_STORAGE_SERVICE=local
command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"]
volumes:
- sidekiq-data:/app/storage
healthcheck:
test: ["CMD-SHELL", "bundle exec rails runner \'puts Sidekiq.redis(&:info)\' > /dev/null 2>&1"]
interval: 30s
timeout: 10s
retries: 3
postgres:
image: postgres:12
restart: always
volumes:
- postgres-data:/var/lib/postgresql/data
image: "nginx"
environment:
- POSTGRES_DB=chatwoot
- POSTGRES_USER=$SERVICE_USER_POSTGRES_USER
- SERVICE_FQDN_ACTIVEPIECES=/api
- POSTGRES_DB=activepieces
- PASSW=$AP_POSTGRES_PASSWORD
- AP_FRONTEND_URL=$SERVICE_FQDN_ACTIVEPIECES
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $SERVICE_USER_POSTGRES_USER -d chatwoot -h 127.0.0.1"]
interval: 30s
timeout: 10s
retries: 5
redis:
image: redis:alpine
restart: always
command: ["sh", "-c", "redis-server --requirepass \"$SERVICE_PASSWORD_REDIS\""]
- POSTGRES_USER=$SERVICE_USER_POSTGRES
volumes:
- redis-data:/data
- "pg-data:/var/lib/postgresql/data"
healthcheck:
test: ["CMD", "redis-cli", "-a", "$SERVICE_PASSWORD_REDIS", "PING"]
interval: 30s
timeout: 10s
retries: 5
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
timeout: 20s
retries: 10
redis:
image: "redis:latest"
volumes:
- "redis_data:/data"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 20s
retries: 10
';
@@ -221,6 +171,7 @@ afterEach(function () {
test('ServiceComposeParseNew', function () {
$output = newParser($this->service);
$this->service->saveComposeConfigs();
// ray('New parser');
// ray($output->toArray());
ray($this->service->environment_variables->pluck('value', 'key')->toArray());

View File

@@ -1,13 +1,13 @@
{
"coolify": {
"v4": {
"version": "4.0.0-beta.331"
"version": "4.0.0-beta.333"
},
"nightly": {
"version": "4.0.0-beta.332"
"version": "4.0.0-beta.334"
},
"helper": {
"version": "1.0.0"
"version": "1.0.1"
}
}
}