mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bf7af3387 |
@@ -11,6 +11,8 @@ $httpsPort = $this->getParam('httpsPort', '');
|
||||
$version = $this->getParam('version', '');
|
||||
$organization = $this->getParam('organization', '');
|
||||
$image = $this->getParam('image', '');
|
||||
$appwriteImage = $this->getParam('appwriteImage', '');
|
||||
$useHostSourceMount = $this->getParam('useHostSourceMount', false);
|
||||
$enableAssistant = $this->getParam('enableAssistant', false);
|
||||
$dbService = $this->getParam('database', 'mongodb');
|
||||
$allowedDbServices = ['mariadb', 'mongodb', 'postgresql'];
|
||||
@@ -18,6 +20,9 @@ if (!\in_array($dbService, $allowedDbServices, true)) {
|
||||
$dbService = 'mongodb';
|
||||
}
|
||||
$hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
if ($appwriteImage === '') {
|
||||
$appwriteImage = $organization . '/' . $image . ':' . $version;
|
||||
}
|
||||
?>services:
|
||||
traefik:
|
||||
image: traefik:3.6
|
||||
@@ -46,7 +51,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- appwrite
|
||||
|
||||
appwrite:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
container_name: appwrite
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
@@ -67,7 +72,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- traefik.http.routers.appwrite_api_https.service=appwrite_api
|
||||
- traefik.http.routers.appwrite_api_https.tls=true
|
||||
volumes:
|
||||
<?php if ($version === 'local' && !empty($hostPath)): ?>
|
||||
<?php if ($useHostSourceMount && !empty($hostPath)): ?>
|
||||
- "<?php echo $hostPath; ?>:/usr/src/code:rw"
|
||||
<?php endif; ?>
|
||||
- appwrite-uploads:/storage/uploads:rw
|
||||
@@ -214,7 +219,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- traefik.http.routers.appwrite_console_https.tls=true
|
||||
|
||||
appwrite-realtime:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: realtime
|
||||
container_name: appwrite-realtime
|
||||
<<: *x-logging
|
||||
@@ -261,7 +266,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-audits:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-audits
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-audits
|
||||
@@ -291,7 +296,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-webhooks:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-webhooks
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-webhooks
|
||||
@@ -323,7 +328,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-deletes:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-deletes
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-deletes
|
||||
@@ -390,7 +395,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
|
||||
appwrite-worker-databases:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-databases
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-databases
|
||||
@@ -420,7 +425,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-builds:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-builds
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-builds
|
||||
@@ -492,7 +497,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_DOMAIN_SITES
|
||||
|
||||
appwrite-worker-certificates:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-certificates
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-certificates
|
||||
@@ -533,7 +538,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-functions:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-functions
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-functions
|
||||
@@ -577,7 +582,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-mails:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-mails
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-mails
|
||||
@@ -616,7 +621,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_OPTIONS_FORCE_HTTPS
|
||||
|
||||
appwrite-worker-messaging:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-messaging
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-messaging
|
||||
@@ -672,7 +677,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_STORAGE_WASABI_BUCKET
|
||||
|
||||
appwrite-worker-migrations:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-migrations
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-migrations
|
||||
@@ -711,7 +716,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
|
||||
|
||||
appwrite-task-maintenance:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: maintenance
|
||||
<<: *x-logging
|
||||
container_name: appwrite-task-maintenance
|
||||
@@ -755,7 +760,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_MAINTENANCE_RETENTION_SCHEDULES
|
||||
|
||||
appwrite-task-stats-resources:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
container_name: appwrite-task-stats-resources
|
||||
entrypoint: stats-resources
|
||||
<<: *x-logging
|
||||
@@ -788,7 +793,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_STATS_RESOURCES_INTERVAL
|
||||
|
||||
appwrite-worker-stats-resources:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-stats-resources
|
||||
container_name: appwrite-worker-stats-resources
|
||||
<<: *x-logging
|
||||
@@ -820,7 +825,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_STATS_RESOURCES_INTERVAL
|
||||
|
||||
appwrite-worker-stats-usage:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: worker-stats-usage
|
||||
container_name: appwrite-worker-stats-usage
|
||||
<<: *x-logging
|
||||
@@ -852,7 +857,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_USAGE_AGGREGATION_INTERVAL
|
||||
|
||||
appwrite-task-scheduler-functions:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: schedule-functions
|
||||
container_name: appwrite-task-scheduler-functions
|
||||
<<: *x-logging
|
||||
@@ -881,7 +886,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_DB_ADAPTER
|
||||
|
||||
appwrite-task-scheduler-executions:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: schedule-executions
|
||||
container_name: appwrite-task-scheduler-executions
|
||||
<<: *x-logging
|
||||
@@ -910,7 +915,7 @@ $hostPath = rtrim($this->getParam('hostPath', ''), '/');
|
||||
- _APP_DB_ADAPTER
|
||||
|
||||
appwrite-task-scheduler-messages:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
image: <?php echo $appwriteImage."\n"; ?>
|
||||
entrypoint: schedule-messages
|
||||
container_name: appwrite-task-scheduler-messages
|
||||
<<: *x-logging
|
||||
|
||||
@@ -106,7 +106,7 @@ class Install extends Action
|
||||
file_put_contents($this->path . '/' . $composeFileName . '.' . $time . '.backup', $data);
|
||||
$compose = new Compose($data);
|
||||
$appwrite = $compose->getService('appwrite');
|
||||
$oldVersion = $appwrite?->getImageVersion();
|
||||
$oldImage = $appwrite?->getImage() ?? null;
|
||||
try {
|
||||
$ports = $compose->getService('traefik')->getPorts();
|
||||
} catch (\Throwable $th) {
|
||||
@@ -117,7 +117,7 @@ class Install extends Action
|
||||
Console::warning('Traefik not found. Falling back to default ports.');
|
||||
}
|
||||
|
||||
if ($oldVersion) {
|
||||
if (!empty($oldImage)) {
|
||||
foreach ($compose->getServices() as $service) {
|
||||
if (!$service) {
|
||||
continue;
|
||||
@@ -509,12 +509,14 @@ class Install extends Action
|
||||
$this->applyLocalPaths($isLocalInstall, false);
|
||||
|
||||
$isCLI = php_sapi_name() === 'cli';
|
||||
if ($isLocalInstall || $isUpgrade) {
|
||||
$useExistingConfig = false;
|
||||
} else {
|
||||
$useExistingConfig = file_exists($this->path . '/' . $this->getComposeFileName())
|
||||
&& file_exists($this->path . '/' . $this->getEnvFileName());
|
||||
}
|
||||
$existingComposePath = $this->path . '/' . $this->getComposeFileName();
|
||||
$existingEnvPath = $this->path . '/' . $this->getEnvFileName();
|
||||
$useExistingConfig = $this->shouldReuseExistingConfig(
|
||||
$isLocalInstall,
|
||||
$isUpgrade,
|
||||
file_exists($existingComposePath) && file_exists($existingEnvPath),
|
||||
$this->readExistingComposeImage()
|
||||
);
|
||||
|
||||
if ($isLocalInstall) {
|
||||
$image = 'appwrite';
|
||||
@@ -531,6 +533,8 @@ class Install extends Action
|
||||
$version = 'local';
|
||||
}
|
||||
|
||||
$appwriteImage = $this->resolveComposeAppwriteImage($isLocalInstall, $organization, $image, $version);
|
||||
|
||||
$assistantKey = (string) ($input['_APP_ASSISTANT_OPENAI_API_KEY'] ?? '');
|
||||
$enableAssistant = trim($assistantKey) !== '';
|
||||
|
||||
@@ -540,8 +544,10 @@ class Install extends Action
|
||||
->setParam('version', $version)
|
||||
->setParam('organization', $organization)
|
||||
->setParam('image', $image)
|
||||
->setParam('appwriteImage', $appwriteImage)
|
||||
->setParam('database', $database)
|
||||
->setParam('hostPath', $this->hostPath)
|
||||
->setParam('useHostSourceMount', $isLocalInstall)
|
||||
->setParam('enableAssistant', $enableAssistant);
|
||||
|
||||
$templateForEnv->setParam('vars', $input);
|
||||
@@ -1096,6 +1102,63 @@ class Install extends Action
|
||||
return !empty($data) ? $data : '';
|
||||
}
|
||||
|
||||
protected function readExistingComposeImage(): ?string
|
||||
{
|
||||
$data = $this->readExistingCompose();
|
||||
|
||||
if ($data === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$compose = new Compose($data);
|
||||
return $compose->getService('appwrite')?->getImage();
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected function shouldUseLocalAppwriteImage(): bool
|
||||
{
|
||||
return \trim((string) \getenv('_APP_VERSION')) === 'dev' && $this->dockerImageExists('appwrite-dev');
|
||||
}
|
||||
|
||||
protected function resolveComposeAppwriteImage(bool $isLocalInstall, string $organization, string $image, string $version): string
|
||||
{
|
||||
if ($isLocalInstall || $this->shouldUseLocalAppwriteImage()) {
|
||||
return 'appwrite-dev';
|
||||
}
|
||||
|
||||
return $organization . '/' . $image . ':' . $version;
|
||||
}
|
||||
|
||||
protected function shouldReuseExistingConfig(bool $isLocalInstall, bool $isUpgrade, bool $configFilesExist, ?string $existingImage = null): bool
|
||||
{
|
||||
if ($isLocalInstall || $isUpgrade || !$configFilesExist) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Avoid sticky mutable or legacy dev tags from previous failed installer runs.
|
||||
if ($existingImage !== null && $this->isStaleMutableAppwriteImageReference($existingImage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isStaleMutableAppwriteImageReference(string $image): bool
|
||||
{
|
||||
return \in_array(\strtolower(\trim($image)), ['appwrite/appwrite:dev', 'appwrite/appwrite:unknown'], true);
|
||||
}
|
||||
|
||||
protected function dockerImageExists(string $image): bool
|
||||
{
|
||||
$result = 1;
|
||||
$output = [];
|
||||
\exec('docker image inspect ' . \escapeshellarg($image) . ' >/dev/null 2>&1', $output, $result);
|
||||
return $result === 0;
|
||||
}
|
||||
|
||||
protected function generatePasswordValue(string $varName, Password $password): string
|
||||
{
|
||||
$value = $password->generate();
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Platform\Tasks;
|
||||
|
||||
use Appwrite\Platform\Tasks\Install;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class InstallTest extends TestCase
|
||||
{
|
||||
public function testResolveComposeAppwriteImageUsesLocalImageForDevBuilds(): void
|
||||
{
|
||||
$this->assertSame('appwrite-dev', $this->resolveComposeAppwriteImageForTest(false, 'appwrite', 'appwrite', 'dev', true));
|
||||
}
|
||||
|
||||
public function testShouldNotReuseExistingConfigForDevTaggedCompose(): void
|
||||
{
|
||||
$this->assertFalse($this->shouldReuseExistingConfigForTest(false, false, true, 'appwrite/appwrite:dev'));
|
||||
}
|
||||
|
||||
public function testShouldReuseExistingConfigForLocalAppwriteImageReference(): void
|
||||
{
|
||||
$this->assertTrue($this->shouldReuseExistingConfigForTest(false, false, true, 'appwrite-dev'));
|
||||
}
|
||||
|
||||
private function resolveComposeAppwriteImageForTest(bool $isLocalInstall, string $organization, string $image, string $version, bool $useLocalAppwriteImage): string
|
||||
{
|
||||
$install = new class ($useLocalAppwriteImage) extends Install {
|
||||
public function __construct(private bool $useLocalAppwriteImage)
|
||||
{
|
||||
}
|
||||
|
||||
public function resolveComposeAppwriteImageForTest(bool $isLocalInstall, string $organization, string $image, string $version): string
|
||||
{
|
||||
return $this->resolveComposeAppwriteImage($isLocalInstall, $organization, $image, $version);
|
||||
}
|
||||
|
||||
protected function shouldUseLocalAppwriteImage(): bool
|
||||
{
|
||||
return $this->useLocalAppwriteImage;
|
||||
}
|
||||
};
|
||||
|
||||
return $install->resolveComposeAppwriteImageForTest($isLocalInstall, $organization, $image, $version);
|
||||
}
|
||||
|
||||
private function shouldReuseExistingConfigForTest(bool $isLocalInstall, bool $isUpgrade, bool $configFilesExist, ?string $existingImage = null): bool
|
||||
{
|
||||
$install = new class () extends Install {
|
||||
public function shouldReuseExistingConfigForTest(bool $isLocalInstall, bool $isUpgrade, bool $configFilesExist, ?string $existingImage = null): bool
|
||||
{
|
||||
return $this->shouldReuseExistingConfig($isLocalInstall, $isUpgrade, $configFilesExist, $existingImage);
|
||||
}
|
||||
};
|
||||
|
||||
return $install->shouldReuseExistingConfigForTest($isLocalInstall, $isUpgrade, $configFilesExist, $existingImage);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user