From 8048a82a5df0f192f90606722a58d260ced6c61c Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Fri, 16 May 2025 14:11:45 +0530 Subject: [PATCH] add postges installtion command --- .env | 1 + app/init/registers.php | 28 ++++++++++++++++++---- app/views/install/compose.phtml | 24 +++++++++++++++++-- src/Appwrite/Platform/Tasks/Install.php | 31 +++++++++++++++++++++---- src/Appwrite/Platform/Tasks/Upgrade.php | 7 +++--- 5 files changed, 77 insertions(+), 14 deletions(-) diff --git a/.env b/.env index b7dd9e24f3..fa22be4586 100644 --- a/.env +++ b/.env @@ -32,6 +32,7 @@ _APP_REDIS_HOST=redis _APP_REDIS_PORT=6379 _APP_REDIS_PASS= _APP_REDIS_USER= +_APP_DB_SCHEME=postgresql _APP_DB_HOST=mariadb _APP_DB_PORT=3306 _APP_DB_SCHEMA=appwrite diff --git a/app/init/registers.php b/app/init/registers.php index 415730f936..b2f1a54dbe 100644 --- a/app/init/registers.php +++ b/app/init/registers.php @@ -14,6 +14,7 @@ use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Adapter\MariaDB; use Utopia\Database\Adapter\MySQL; +use Utopia\Database\Adapter\Postgres; use Utopia\Database\Adapter\SQL; use Utopia\Database\PDO; use Utopia\Domains\Validator\PublicDomain; @@ -120,19 +121,19 @@ $register->set('pools', function () { 'type' => 'database', 'dsns' => $fallbackForDB, 'multiple' => false, - 'schemes' => ['mariadb', 'mysql'], + 'schemes' => ['mariadb', 'mysql','postgresql'], ], 'database' => [ 'type' => 'database', 'dsns' => $fallbackForDB, 'multiple' => true, - 'schemes' => ['mariadb', 'mysql'], + 'schemes' => ['mariadb', 'mysql','postgresql'], ], 'logs' => [ 'type' => 'database', 'dsns' => System::getEnv('_APP_CONNECTIONS_DB_LOGS', $fallbackForDB), 'multiple' => false, - 'schemes' => ['mariadb', 'mysql'], + 'schemes' => ['mariadb', 'mysql','postgresql'], ], 'publisher' => [ 'type' => 'publisher', @@ -225,6 +226,17 @@ $register->set('pools', function () { ]); }); }, + 'postgresql' => function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) { + return new PDOProxy(function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) { + return new PDO("pgsql:host={$dsnHost};port={$dsnPort};dbname={$dsnDatabase}", $dsnUser, $dsnPass, array( + \PDO::ATTR_TIMEOUT => 3, // Seconds + \PDO::ATTR_PERSISTENT => false, + \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, + \PDO::ATTR_EMULATE_PREPARES => true, + \PDO::ATTR_STRINGIFY_FETCHES => true + )); + }); + }, 'redis' => function () use ($dsnHost, $dsnPort, $dsnPass) { $redis = new \Redis(); @$redis->pconnect($dsnHost, (int)$dsnPort); @@ -245,6 +257,7 @@ $register->set('pools', function () { $adapter = match ($dsn->getScheme()) { 'mariadb' => new MariaDB($resource()), 'mysql' => new MySQL($resource()), + 'postgresql' => new Postgres($resource), default => null }; @@ -286,10 +299,15 @@ $register->set('db', function () { $dbPort = System::getEnv('_APP_DB_PORT', ''); $dbUser = System::getEnv('_APP_DB_USER', ''); $dbPass = System::getEnv('_APP_DB_PASS', ''); - $dbScheme = System::getEnv('_APP_DB_SCHEMA', ''); + $dbSchema = System::getEnv('_APP_DB_SCHEMA', ''); + $dbScheme = System::getEnv('_APP_DB_SCHEME', 'mariadb'); + $dsn = ($dbScheme === 'postgresql') + ? "pgsql:host={$dbHost};port={$dbPort};dbname={$dbSchema}" + : "mysql:host={$dbHost};port={$dbPort};dbname={$dbSchema};charset=utf8mb4"; + return new PDO( - "mysql:host={$dbHost};port={$dbPort};dbname={$dbScheme};charset=utf8mb4", + $dsn, $dbUser, $dbPass, SQL::getPDOAttributes() diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index 2d8f2b35ab..774a72537d 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -69,8 +69,12 @@ $image = $this->getParam('image', ''); - appwrite-sites:/storage/sites:rw - appwrite-builds:/storage/builds:rw depends_on: - - mariadb - redis + getParam('_APP_DB_SCHEME', 'mariadb') === 'mariadb'): ?> + - mariadb + + - postgres + # - clamav environment: - _APP_ENV @@ -105,6 +109,7 @@ $image = $this->getParam('image', ''); - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_DB_SCHEME - _APP_SMTP_HOST - _APP_SMTP_PORT - _APP_SMTP_SECURE @@ -219,8 +224,8 @@ $image = $this->getParam('image', ''); networks: - appwrite depends_on: - - mariadb - redis + - mariadb environment: - _APP_ENV - _APP_WORKER_PER_CORE @@ -927,6 +932,20 @@ $image = $this->getParam('image', ''); - MARIADB_AUTO_UPGRADE=1 command: 'mysqld --innodb-flush-method=fsync' + postgres: + image: postgres:15-alpine + container_name: appwrite-postgres + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-postgres:/var/lib/postgresql/data:rw + environment: + - POSTGRES_DB=${_APP_DB_SCHEMA} + - POSTGRES_USER=${_APP_DB_USER} + - POSTGRES_PASSWORD=${_APP_DB_PASS} + redis: image: redis:7.2.4-alpine container_name: appwrite-redis @@ -970,3 +989,4 @@ volumes: appwrite-sites: appwrite-builds: appwrite-config: + appwrite-postgres: diff --git a/src/Appwrite/Platform/Tasks/Install.php b/src/Appwrite/Platform/Tasks/Install.php index c7b1f72453..c157374893 100644 --- a/src/Appwrite/Platform/Tasks/Install.php +++ b/src/Appwrite/Platform/Tasks/Install.php @@ -31,16 +31,25 @@ class Install extends Action ->param('image', 'appwrite', new Text(0), 'Main appwrite docker image', true) ->param('interactive', 'Y', new Text(1), 'Run an interactive session', true) ->param('no-start', false, new Boolean(true), 'Run an interactive session', true) - ->callback([$this, 'action']); + ->param('database', 'mariadb', new Text(0), 'Database to use (mariadb|postgresql)', true) + ->callback(fn ($httpPort, $httpsPort, $organization, $image, $interactive, $noStart, $database) => $this->action($httpPort, $httpsPort, $organization, $image, $interactive, $noStart, $database)); } - public function action(string $httpPort, string $httpsPort, string $organization, string $image, string $interactive, bool $noStart): void + public function action(string $httpPort, string $httpsPort, string $organization, string $image, string $interactive, bool $noStart, string $database): void { $config = Config::getParam('variables'); $defaultHTTPPort = '80'; $defaultHTTPSPort = '443'; /** @var array> $vars array whre key is variable name and value is variable */ $vars = []; + $vars['_APP_DB_SCHEME'] = [ + 'name' => '_APP_DB_SCHEME', + 'default' => $database, + 'required' => false, + 'filter' => '', + 'overwrite' => true, + 'question' => 'Choose your database (mariadb|postgresql)', + ]; foreach ($config as $category) { foreach ($category['variables'] ?? [] as $var) { @@ -171,6 +180,19 @@ class Install extends Action continue; } + if ($var['name'] === '_APP_DB_SCHEME') { + $input[$var['name']] = Console::confirm('Choose your database (mariadb|postgresql): (default: ' . $var['default'] . ')'); + if (empty($input[$var['name']])) { + $input[$var['name']] = $var['default']; + } + if (!in_array($input[$var['name']], ['mariadb', 'postgresql'])) { + Console::error('Invalid database choice. Please choose either mariadb or postgresql.'); + Console::exit(1); + } + $database = $input[$var['name']]; + continue; + } + $input[$var['name']] = Console::confirm($var['question'] . ' (default: \'' . $var['default'] . '\')'); if (empty($input[$var['name']])) { @@ -196,8 +218,9 @@ class Install extends Action ->setParam('httpsPort', $httpsPort) ->setParam('version', APP_VERSION_STABLE) ->setParam('organization', $organization) - ->setParam('image', $image); - + ->setParam('image', $image) + ->setParam('database',$database); + $input['_APP_DB_SCHEME'] = $database; $templateForEnv->setParam('vars', $input); if (!file_put_contents($this->path . '/docker-compose.yml', $templateForCompose->render(false))) { diff --git a/src/Appwrite/Platform/Tasks/Upgrade.php b/src/Appwrite/Platform/Tasks/Upgrade.php index dfd10d347e..5f4b625462 100644 --- a/src/Appwrite/Platform/Tasks/Upgrade.php +++ b/src/Appwrite/Platform/Tasks/Upgrade.php @@ -23,10 +23,11 @@ class Upgrade extends Install ->param('image', 'appwrite', new Text(0), 'Main appwrite docker image', true) ->param('interactive', 'Y', new Text(1), 'Run an interactive session', true) ->param('no-start', false, new Boolean(true), 'Run an interactive session', true) - ->callback([$this, 'action']); + ->param('database', 'mariadb', new Text(0), 'Database to use (mariadb|postgresql)', true) + ->callback(fn ($httpPort, $httpsPort, $organization, $image, $interactive, $noStart, $database) => $this->action($httpPort, $httpsPort, $organization, $image, $interactive, $noStart, $database)); } - public function action(string $httpPort, string $httpsPort, string $organization, string $image, string $interactive, bool $noStart): void + public function action(string $httpPort, string $httpsPort, string $organization, string $image, string $interactive, bool $noStart, string $database): void { // Check for previous installation $data = @file_get_contents($this->path . '/docker-compose.yml'); @@ -39,6 +40,6 @@ class Upgrade extends Install Console::log(' └── docker-compose.yml'); Console::exit(1); } - parent::action($httpPort, $httpsPort, $organization, $image, $interactive, $noStart); + parent::action($httpPort, $httpsPort, $organization, $image, $interactive, $noStart, $database); } }