From 36e3d9c6034273eeb889de7542f5eb2ba106ee14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 27 Nov 2024 16:27:40 +0100 Subject: [PATCH] WIP: Server-side rendering for sites --- .env | 2 +- app/config/frameworks.php | 11 ++++++-- app/config/site-templates.php | 12 ++++---- app/controllers/general.php | 28 +++++++++++++++++-- docker-compose.yml | 1 + .../Modules/Functions/Workers/Builds.php | 21 +++++++------- 6 files changed, 53 insertions(+), 22 deletions(-) diff --git a/.env b/.env index 4b82bda47a..dc66155208 100644 --- a/.env +++ b/.env @@ -77,7 +77,7 @@ _APP_COMPUTE_INACTIVE_THRESHOLD=600 _APP_COMPUTE_MAINTENANCE_INTERVAL=600 _APP_COMPUTE_RUNTIMES_NETWORK=runtimes _APP_EXECUTOR_SECRET=your-secret-key -_APP_EXECUTOR_HOST=http://proxy/v1 +_APP_EXECUTOR_HOST=http://exc1/v1 _APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1 _APP_SITES_RUNTIMES=static-1,node-22,flutter-3.24 _APP_SITES_FRAMEWORKS=sveltekit,nextjs,nuxt,astro,angular,remix,static diff --git a/app/config/frameworks.php b/app/config/frameworks.php index 13c6b69825..742b00aae0 100644 --- a/app/config/frameworks.php +++ b/app/config/frameworks.php @@ -28,6 +28,8 @@ return [ 'defaultBuildCommand' => 'npm run build', 'defaultInstallCommand' => 'npm install', 'defaultOutputDirectory' => './build', + 'startCommand' => 'cd src/function && node index.js', + 'bundleCommand' => 'cp package*.json build/ && cp -R node_modules/ build/node_modules/', ], 'nextjs' => [ 'key' => 'nextjs', @@ -73,15 +75,20 @@ return [ 'astro' => [ 'key' => 'astro', 'name' => 'Astro', - 'defaultServeRuntime' => 'static-1', + 'defaultServeRuntime' => 'node-22', 'serveRuntimes' => [ - 'static-1' + ...getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'static-1', ], 'defaultBuildRuntime' => 'node-22', 'buildRuntimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), 'defaultBuildCommand' => 'npm run build', 'defaultInstallCommand' => 'npm install', 'defaultOutputDirectory' => './dist', + // 'startCommand' => 'sh helpers/server-astro.sh', + // 'bundleCommand' => 'sh helpers/bundle-astro.sh', + 'startCommand' => 'cd src/function && HOST=0.0.0.0 PORT=3000 node server/entry.mjs', + 'bundleCommand' => 'cp package*.json dist/server/ && cp -R node_modules/ dist/server/node_modules/', ], 'remix' => [ 'key' => 'remix', diff --git a/app/config/site-templates.php b/app/config/site-templates.php index 8a71fa556a..7e943437ab 100644 --- a/app/config/site-templates.php +++ b/app/config/site-templates.php @@ -8,7 +8,7 @@ const TEMPLATE_FRAMEWORKS = [ 'buildCommand' => 'npm run build', 'outputDirectory' => './build', 'buildRuntime' => 'node-22', - 'serveRuntime' => 'static-1', + 'serveRuntime' => 'node-22', 'fallbackFile' => null, ], 'NEXTJS' => [ @@ -48,7 +48,7 @@ const TEMPLATE_FRAMEWORKS = [ 'buildCommand' => 'npm run build', 'outputDirectory' => './dist', 'buildRuntime' => 'node-22', - 'serveRuntime' => 'static-1', + 'serveRuntime' => 'node-22', 'fallbackFile' => null, ], /* @@ -130,7 +130,7 @@ return [ 'vcsProvider' => 'github', 'providerRepositoryId' => 'templates-for-sites', 'providerOwner' => 'appwrite', - 'providerVersion' => '0.1.*', + 'providerVersion' => '0.2.*', 'variables' => [], ], [ @@ -141,12 +141,12 @@ return [ 'demoImage' => 'https://qa17.appwrite.org/console/images/sites/templates/astro-starter.png', 'frameworks' => [ getFramework('ASTRO', [ - 'providerRootDirectory' => './astro/starter', + 'providerRootDirectory' => './', ]), ], 'vcsProvider' => 'github', - 'providerRepositoryId' => 'templates-for-sites', - 'providerOwner' => 'appwrite', + 'providerRepositoryId' => 'astro-ssr-test-template', + 'providerOwner' => 'Meldiron', 'providerVersion' => '0.1.*', 'variables' => [], ], diff --git a/app/controllers/general.php b/app/controllers/general.php index 0d42357b95..71782414e7 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -336,9 +336,28 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo 'site' => '', 'deployment' => '' }; - $runtimeEntrypoint = match ($version) { - 'v2' => '', - default => 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $runtime['startCommand'] . '"' + + if($type === 'function') { + $runtimeEntrypoint = match ($version) { + 'v2' => '', + default => 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $runtime['startCommand'] . '"' + }; + } else if($type === 'site' || $type === 'deployment') { + $frameworks = Config::getParam('frameworks', []); + $framework = $frameworks[$resource->getAttribute('framework', '')] ?? null; + + $startCommand = $runtime['startCommand']; + if(!is_null($framework) && !empty($framework['startCommand'])) { + $startCommand = $framework['startCommand']; + } + + $runtimeEntrypoint = 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $startCommand . '"'; + } + + $entrypoint = match($type) { + 'function' => $deployment->getAttribute('entrypoint', ''), + 'site' => '', + 'deployment' => '' }; $executionResponse = $executor->createExecution( @@ -446,6 +465,9 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo $response->setHeader($header['name'], $header['value']); } + // TODO: Figoure out situation with transfer-encoding + // TODO: Dont double-compress + $response ->setContentType($contentType) ->setStatusCode($execution['responseStatusCode'] ?? 200) diff --git a/docker-compose.yml b/docker-compose.yml index 227c07fb2a..9c8c133ee6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -84,6 +84,7 @@ services: - ./public:/usr/src/code/public - ./src:/usr/src/code/src - ./dev:/usr/src/code/dev + - ./vendor/utopia-php/framework:/usr/src/code/vendor/utopia-php/framework depends_on: - mariadb - redis diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php index 2fcbf4bb36..3d2937f80b 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -870,20 +870,21 @@ class Builds extends Action if ($resource->getCollection() === 'functions') { return $deployment->getAttribute('commands', ''); } elseif ($resource->getCollection() === 'sites') { - $command = ''; + $commands = []; + + $commands[] = $deployment->getAttribute('installCommand', ''); + $commands[] = $deployment->getAttribute('buildCommand', ''); - $installCommand = $deployment->getAttribute('installCommand', ''); - $buildCommand = $deployment->getAttribute('buildCommand', ''); - - $command .= $installCommand; - - if (!empty($installCommand) && !empty($buildCommand)) { - $command .= ' && '; + $frameworks = Config::getParam('frameworks', []); + $framework = $frameworks[$resource->getAttribute('framework', '')] ?? null; + + if(!is_null($framework) && !empty($framework['bundleCommand'])) { + $commands[] = $framework['bundleCommand']; } - $command .= $buildCommand; + $commands = array_filter($commands, fn($command) => !empty($command)); - return $command; + return implode(' && ', $commands); } return '';