From dc1655b7f547857ddc9b6adb55c5d156a6cf63e0 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Tue, 28 Jul 2020 22:48:51 +0300 Subject: [PATCH 01/12] Work in progress --- Dockerfile | 2 + app/cli.php | 25 ++++ app/tasks/{init.php => doctor.php} | 27 +--- app/tasks/install.php | 201 +++++++++++++++++++++++++++++ app/tasks/migrate.php | 13 +- app/tasks/sdks.php | 10 +- app/tasks/ssl.php | 23 ++++ bin/doctor | 2 +- bin/install | 3 + bin/migrate | 2 +- bin/ssl | 3 + bin/test | 2 +- 12 files changed, 267 insertions(+), 46 deletions(-) create mode 100644 app/cli.php rename app/tasks/{init.php => doctor.php} (92%) create mode 100644 app/tasks/install.php create mode 100644 app/tasks/ssl.php create mode 100755 bin/install create mode 100755 bin/ssl diff --git a/Dockerfile b/Dockerfile index 26fbaea5a..2eeb7f84f 100755 --- a/Dockerfile +++ b/Dockerfile @@ -143,8 +143,10 @@ RUN mkdir -p /storage/uploads && \ # Executables RUN chmod +x /usr/local/bin/doctor && \ + chmod +x /usr/local/bin/install && \ chmod +x /usr/local/bin/migrate && \ chmod +x /usr/local/bin/schedule && \ + chmod +x /usr/local/bin/ssl && \ chmod +x /usr/local/bin/test && \ chmod +x /usr/local/bin/worker-audits && \ chmod +x /usr/local/bin/worker-certificates && \ diff --git a/app/cli.php b/app/cli.php new file mode 100644 index 000000000..9eede27a3 --- /dev/null +++ b/app/cli.php @@ -0,0 +1,25 @@ +#!/bin/env php +task('version') + ->desc('Get the server version') + ->action(function () { + Console::log(App::getEnv('_APP_VERSION', 'UNKNOWN')); + }); + +$cli->run(); \ No newline at end of file diff --git a/app/tasks/init.php b/app/tasks/doctor.php similarity index 92% rename from app/tasks/init.php rename to app/tasks/doctor.php index 63f754b5a..0836628bd 100644 --- a/app/tasks/init.php +++ b/app/tasks/doctor.php @@ -1,35 +1,14 @@ -#!/bin/env php task('ssl') - ->desc('Validate server certificates') - ->action(function () { - $domain = App::getEnv('_APP_DOMAIN', ''); - - Console::log('Issue a TLS certificate for master domain ('.$domain.') in 30 seconds. - Make sure your domain points to your server or restart to try again.'); - - ResqueScheduler::enqueueAt(\time() + 30, 'v1-certificates', 'CertificatesV1', [ - 'document' => [], - 'domain' => $domain, - 'validateTarget' => false, - 'validateCNAME' => false, - ]); - }); - $cli ->task('doctor') ->desc('Validate server health') @@ -254,6 +233,4 @@ $cli } catch (\Throwable $th) { Console::error('Failed to check for a newer version'."\n"); } - }); - -$cli->run(); + }); \ No newline at end of file diff --git a/app/tasks/install.php b/app/tasks/install.php new file mode 100644 index 000000000..fcad91f90 --- /dev/null +++ b/app/tasks/install.php @@ -0,0 +1,201 @@ +task('install') + ->desc('Install Appwrite') + ->action(function () { + /** + * 1. Start - DONE + * 2. Check for older setup and get older version + * 2.1 If older version is equal or bigger(?) than current version, **stop setup** + * 2.2. Get ENV vars + * 2.2.1 Fetch from older docker-compose.yml file + * 2.2.2 Fetch from older .env file (manually parse) + * 2.3 Use old ENV vars as default values + * 2.4 Ask for all required vars not given as CLI args and if in interactive mode + * Otherwise, just use default vars. - DONE + * 3. Ask user to backup important volumes, env vars, and SQL tables + * In th future we can try and automate this for smaller/medium size setups + * 4. Drop new docker-compose.yml setup (located inside the container, no network dependencies with appwrite.io) + * 5. Run docker-compose up -d + * 6. Run data migration + */ + + $vars = [ + '_APP_ENV' => [ + 'default' => 'production', + 'required' => false, + 'question' => '', + ], + '_APP_OPTIONS_ABUSE' => [ + 'default' => 'enabled', + 'required' => false, + 'question' => '', + ], + '_APP_OPTIONS_FORCE_HTTPS' => [ + 'default' => 'enabled', + 'required' => false, + 'question' => '', + ], + '_APP_OPENSSL_KEY_V1' => [ + 'default' => 'your-secret-key', + 'required' => true, + 'question' => 'Choose a secret API key, make sure to make a backup of your key in a secure location', + ], + '_APP_DOMAIN' => [ + 'default' => 'localhost', + 'required' => true, + 'question' => 'Enter your Appwrite hostname', + ], + '_APP_DOMAIN_TARGET' => [ + 'default' => 'localhost', + 'required' => true, + 'question' => "Enter a DNS A record hostname to server as a CNAME for your custom domains.\nYou can use the same value as used for the Appwrite hostname.", + ], + '_APP_REDIS_HOST' => [ + 'default' => 'redis', + 'required' => false, + 'question' => '', + ], + '_APP_REDIS_PORT' => [ + 'default' => '6379', + 'required' => false, + 'question' => '', + ], + '_APP_DB_HOST' => [ + 'default' => 'mariadb', + 'required' => false, + 'question' => '', + ], + '_APP_DB_PORT' => [ + 'default' => '3306', + 'required' => false, + 'question' => '', + ], + '_APP_DB_SCHEMA' => [ + 'default' => 'appwrite', + 'required' => false, + 'question' => '', + ], + '_APP_DB_USER' => [ + 'default' => 'user', + 'required' => false, + 'question' => '', + ], + '_APP_DB_PASS' => [ + 'default' => 'password', + 'required' => false, + 'question' => '', + ], + '_APP_INFLUXDB_HOST' => [ + 'default' => 'influxdb', + 'required' => false, + 'question' => '', + ], + '_APP_INFLUXDB_PORT' => [ + 'default' => '8086', + 'required' => false, + 'question' => '', + ], + '_APP_STATSD_HOST' => [ + 'default' => 'telegraf', + 'required' => false, + 'question' => '', + ], + '_APP_STATSD_PORT' => [ + 'default' => '8125', + 'required' => false, + 'question' => '', + ], + '_APP_SMTP_HOST' => [ + 'default' => 'smtp', + 'required' => false, + 'question' => '', + ], + '_APP_SMTP_PORT' => [ + 'default' => '25', + 'required' => false, + 'question' => '', + ], + '_APP_STORAGE_LIMIT' => [ + 'default' => '100000000', + 'required' => false, + 'question' => '', + ], + '_APP_FUNCTIONS_TIMEOUT' => [ + 'default' => '900', + 'required' => false, + 'question' => '', + ], + '_APP_FUNCTIONS_CONTAINERS' => [ + 'default' => '10', + 'required' => false, + 'question' => '', + ], + ]; + + // var_dump(realpath(__DIR__.'/docker-compose.yml')); + // var_dump(yaml_parse_file(__DIR__.'/docker-compose.yml')); + + Console::success('Starting Appwrite installation...'); + + if(!empty($httpPort)) { + $httpPort = Console::confirm('Choose your server HTTP port: (default: 80)'); + $httpPort = ($httpPort) ? $httpPort : 80; + } + + if(!empty($httpsPort)) { + $httpsPort = Console::confirm('Choose your server HTTPS port: (default: 443)'); + $httpsPort = ($httpsPort) ? $httpsPort : 443; + } + + $input = []; + + foreach($vars as $key => $var) { + if(!$var['required']) { + $input[$key] = $var['default']; + continue; + } + + $input[$key] = Console::confirm($var['question'].' (default: \''.$var['default'].'\')'); + + if(empty($input[$key])) { + $input[$key] = $var['default']; + } + } + + var_dump($input); + + // $composeUrl = $source.'/docker-compose.yml?'.http_build_query([ + // 'version' => $version, + // 'domain' => $domain, + // 'httpPort' => $httpPort, + // 'httpsPort' => $httpsPort, + // 'target' => $target, + // ]); + + // $composeFile = @file_get_contents($composeUrl); + + // if(!$composeFile) { + // throw new Exception('Failed to fetch Docker Compose file'); + // } + + // if(!file_put_contents('/install/appwrite/docker-compose.yml', $composeFile)) { + // throw new Exception('Failed to save Docker Compose file'); + // } + + + $stdout = null; + $stderr = null; + + Console::execute('docker-compose -f /install/appwrite/docker-compose.yml up -d', null, $stdout, $stderr); + if ($stdout != NULL) { + Console::error("Failed to install Appwrite dockers"); + } else { + Console::success("Appwrite installed successfully"); + } + }); \ No newline at end of file diff --git a/app/tasks/migrate.php b/app/tasks/migrate.php index 3e3eec30c..36773b35b 100644 --- a/app/tasks/migrate.php +++ b/app/tasks/migrate.php @@ -1,18 +1,13 @@ -#!/bin/env php get('db'); $callbacks = [ @@ -172,7 +167,7 @@ function fixDocument(Document $document) { } $cli - ->task('run') + ->task('migrate') ->action(function () use ($console, $projectDB, $consoleDB, $callbacks) { Console::success('Starting Data Migration'); @@ -214,6 +209,4 @@ $cli } Console::success('Data Migration Completed'); - }); - -$cli->run(); + }); \ No newline at end of file diff --git a/app/tasks/sdks.php b/app/tasks/sdks.php index bab19d108..b70dbc7be 100644 --- a/app/tasks/sdks.php +++ b/app/tasks/sdks.php @@ -1,10 +1,8 @@ -#!/bin/env php run(); + }); \ No newline at end of file diff --git a/app/tasks/ssl.php b/app/tasks/ssl.php new file mode 100644 index 000000000..2c32324fa --- /dev/null +++ b/app/tasks/ssl.php @@ -0,0 +1,23 @@ +task('ssl') + ->desc('Validate server certificates') + ->action(function () { + $domain = App::getEnv('_APP_DOMAIN', ''); + + Console::log('Issue a TLS certificate for master domain ('.$domain.') in 30 seconds. + Make sure your domain points to your server or restart to try again.'); + + ResqueScheduler::enqueueAt(\time() + 30, 'v1-certificates', 'CertificatesV1', [ + 'document' => [], + 'domain' => $domain, + 'validateTarget' => false, + 'validateCNAME' => false, + ]); + }); \ No newline at end of file diff --git a/bin/doctor b/bin/doctor index 022a4d8a5..b2a454715 100755 --- a/bin/doctor +++ b/bin/doctor @@ -1,3 +1,3 @@ #!/bin/sh -php /usr/src/code/app/tasks/init.php doctor \ No newline at end of file +php /usr/src/code/app/cli.php doctor $@ \ No newline at end of file diff --git a/bin/install b/bin/install new file mode 100755 index 000000000..e669e91e6 --- /dev/null +++ b/bin/install @@ -0,0 +1,3 @@ +#!/bin/sh + +php /usr/src/code/app/cli.php install $@ \ No newline at end of file diff --git a/bin/migrate b/bin/migrate index 509512fae..28ebbd19e 100755 --- a/bin/migrate +++ b/bin/migrate @@ -1,3 +1,3 @@ #!/bin/sh -php /usr/src/code/app/tasks/migrate.php run \ No newline at end of file +php /usr/src/code/app/cli.php migrate $@ \ No newline at end of file diff --git a/bin/ssl b/bin/ssl new file mode 100755 index 000000000..83dcf6a02 --- /dev/null +++ b/bin/ssl @@ -0,0 +1,3 @@ +#!/bin/sh + +php /usr/src/code/app/cli.php ssl $@ \ No newline at end of file diff --git a/bin/test b/bin/test index 61f606b15..a2153fc53 100755 --- a/bin/test +++ b/bin/test @@ -1,3 +1,3 @@ #!/bin/sh -/usr/src/code/vendor/bin/phpunit --configuration /usr/src/code/phpunit.xml \ No newline at end of file +/usr/src/code/vendor/bin/phpunit --configuration /usr/src/code/phpunit.xml $@ \ No newline at end of file From 13b4ee6624a4a28ed8f2e63959576a839304e7e8 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Wed, 29 Jul 2020 07:03:28 +0300 Subject: [PATCH 02/12] Added config set for env vars --- app/config/variables.php | 136 +++++++++++++++++++++++++++++++++++++++ app/init.php | 1 + app/tasks/install.php | 125 ++--------------------------------- 3 files changed, 144 insertions(+), 118 deletions(-) create mode 100644 app/config/variables.php diff --git a/app/config/variables.php b/app/config/variables.php new file mode 100644 index 000000000..06e701c3f --- /dev/null +++ b/app/config/variables.php @@ -0,0 +1,136 @@ + '_APP_ENV', + 'default' => 'production', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_OPTIONS_ABUSE', + 'default' => 'enabled', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_OPTIONS_FORCE_HTTPS', + 'default' => 'enabled', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_OPENSSL_KEY_V1', + 'default' => 'your-secret-key', + 'required' => true, + 'question' => 'Choose a secret API key, make sure to make a backup of your key in a secure location', + ], + [ + 'name' => '_APP_DOMAIN', + 'default' => 'localhost', + 'required' => true, + 'question' => 'Enter your Appwrite hostname', + ], + [ + 'name' => '_APP_DOMAIN_TARGET', + 'default' => 'localhost', + 'required' => true, + 'question' => "Enter a DNS A record hostname to server as a CNAME for your custom domains.\nYou can use the same value as used for the Appwrite hostname.", + ], + [ + 'name' => '_APP_REDIS_HOST', + 'default' => 'redis', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_REDIS_PORT', + 'default' => '6379', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_DB_HOST', + 'default' => 'mariadb', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_DB_PORT', + 'default' => '3306', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_DB_SCHEMA', + 'default' => 'appwrite', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_DB_USER', + 'default' => 'user', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_DB_PASS', + 'default' => 'password', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_INFLUXDB_HOST', + 'default' => 'influxdb', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_INFLUXDB_PORT', + 'default' => '8086', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STATSD_HOST', + 'default' => 'telegraf', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STATSD_PORT', + 'default' => '8125', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_SMTP_HOST', + 'default' => 'smtp', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_SMTP_PORT', + 'default' => '25', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_STORAGE_LIMIT', + 'default' => '100000000', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_FUNCTIONS_TIMEOUT', + 'default' => '900', + 'required' => false, + 'question' => '', + ], + [ + 'name' => '_APP_FUNCTIONS_CONTAINERS', + 'default' => '10', + 'required' => false, + 'question' => '', + ], +]; \ No newline at end of file diff --git a/app/init.php b/app/init.php index f29608f5d..b3d33b350 100644 --- a/app/init.php +++ b/app/init.php @@ -67,6 +67,7 @@ Config::load('environments', __DIR__.'/config/environments.php'); Config::load('roles', __DIR__.'/config/roles.php'); // User roles and scopes Config::load('scopes', __DIR__.'/config/scopes.php'); // User roles and scopes Config::load('services', __DIR__.'/config/services.php'); // List of services +Config::load('variables', __DIR__.'/config/variables.php'); // List of env variables Config::load('avatar-browsers', __DIR__.'/config/avatars/browsers.php'); Config::load('avatar-credit-cards', __DIR__.'/config/avatars/credit-cards.php'); Config::load('avatar-flags', __DIR__.'/config/avatars/flags.php'); diff --git a/app/tasks/install.php b/app/tasks/install.php index fcad91f90..4db2dedca 100644 --- a/app/tasks/install.php +++ b/app/tasks/install.php @@ -3,6 +3,7 @@ global $cli; use Utopia\CLI\Console; +use Utopia\Config\Config; $cli ->task('install') @@ -25,118 +26,7 @@ $cli * 6. Run data migration */ - $vars = [ - '_APP_ENV' => [ - 'default' => 'production', - 'required' => false, - 'question' => '', - ], - '_APP_OPTIONS_ABUSE' => [ - 'default' => 'enabled', - 'required' => false, - 'question' => '', - ], - '_APP_OPTIONS_FORCE_HTTPS' => [ - 'default' => 'enabled', - 'required' => false, - 'question' => '', - ], - '_APP_OPENSSL_KEY_V1' => [ - 'default' => 'your-secret-key', - 'required' => true, - 'question' => 'Choose a secret API key, make sure to make a backup of your key in a secure location', - ], - '_APP_DOMAIN' => [ - 'default' => 'localhost', - 'required' => true, - 'question' => 'Enter your Appwrite hostname', - ], - '_APP_DOMAIN_TARGET' => [ - 'default' => 'localhost', - 'required' => true, - 'question' => "Enter a DNS A record hostname to server as a CNAME for your custom domains.\nYou can use the same value as used for the Appwrite hostname.", - ], - '_APP_REDIS_HOST' => [ - 'default' => 'redis', - 'required' => false, - 'question' => '', - ], - '_APP_REDIS_PORT' => [ - 'default' => '6379', - 'required' => false, - 'question' => '', - ], - '_APP_DB_HOST' => [ - 'default' => 'mariadb', - 'required' => false, - 'question' => '', - ], - '_APP_DB_PORT' => [ - 'default' => '3306', - 'required' => false, - 'question' => '', - ], - '_APP_DB_SCHEMA' => [ - 'default' => 'appwrite', - 'required' => false, - 'question' => '', - ], - '_APP_DB_USER' => [ - 'default' => 'user', - 'required' => false, - 'question' => '', - ], - '_APP_DB_PASS' => [ - 'default' => 'password', - 'required' => false, - 'question' => '', - ], - '_APP_INFLUXDB_HOST' => [ - 'default' => 'influxdb', - 'required' => false, - 'question' => '', - ], - '_APP_INFLUXDB_PORT' => [ - 'default' => '8086', - 'required' => false, - 'question' => '', - ], - '_APP_STATSD_HOST' => [ - 'default' => 'telegraf', - 'required' => false, - 'question' => '', - ], - '_APP_STATSD_PORT' => [ - 'default' => '8125', - 'required' => false, - 'question' => '', - ], - '_APP_SMTP_HOST' => [ - 'default' => 'smtp', - 'required' => false, - 'question' => '', - ], - '_APP_SMTP_PORT' => [ - 'default' => '25', - 'required' => false, - 'question' => '', - ], - '_APP_STORAGE_LIMIT' => [ - 'default' => '100000000', - 'required' => false, - 'question' => '', - ], - '_APP_FUNCTIONS_TIMEOUT' => [ - 'default' => '900', - 'required' => false, - 'question' => '', - ], - '_APP_FUNCTIONS_CONTAINERS' => [ - 'default' => '10', - 'required' => false, - 'question' => '', - ], - ]; + $vars = Config::getParam('variables'); // var_dump(realpath(__DIR__.'/docker-compose.yml')); // var_dump(yaml_parse_file(__DIR__.'/docker-compose.yml')); @@ -157,14 +47,14 @@ $cli foreach($vars as $key => $var) { if(!$var['required']) { - $input[$key] = $var['default']; + $input[$var['name']] = $var['default']; continue; } - $input[$key] = Console::confirm($var['question'].' (default: \''.$var['default'].'\')'); + $input[$var['name']] = Console::confirm($var['question'].' (default: \''.$var['default'].'\')'); if(empty($input[$key])) { - $input[$key] = $var['default']; + $input[$var['name']] = $var['default']; } } @@ -188,9 +78,8 @@ $cli // throw new Exception('Failed to save Docker Compose file'); // } - - $stdout = null; - $stderr = null; + $stdout = ''; + $stderr = ''; Console::execute('docker-compose -f /install/appwrite/docker-compose.yml up -d', null, $stdout, $stderr); if ($stdout != NULL) { From 6ef383faada2bf891525cff3309ab76583dadc88 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Wed, 29 Jul 2020 09:56:39 +0300 Subject: [PATCH 03/12] Added new templates --- app/tasks/install.php | 50 ++--- app/views/install/compose.phtml | 327 ++++++++++++++++++++++++++++++++ app/views/install/env.phtml | 8 + 3 files changed, 362 insertions(+), 23 deletions(-) create mode 100644 app/views/install/compose.phtml create mode 100644 app/views/install/env.phtml diff --git a/app/tasks/install.php b/app/tasks/install.php index 4db2dedca..e00f761dc 100644 --- a/app/tasks/install.php +++ b/app/tasks/install.php @@ -4,6 +4,7 @@ global $cli; use Utopia\CLI\Console; use Utopia\Config\Config; +use Utopia\View; $cli ->task('install') @@ -22,14 +23,11 @@ $cli * 3. Ask user to backup important volumes, env vars, and SQL tables * In th future we can try and automate this for smaller/medium size setups * 4. Drop new docker-compose.yml setup (located inside the container, no network dependencies with appwrite.io) - * 5. Run docker-compose up -d + * 5. Run docker-compose up -d - DONE * 6. Run data migration */ $vars = Config::getParam('variables'); - - // var_dump(realpath(__DIR__.'/docker-compose.yml')); - // var_dump(yaml_parse_file(__DIR__.'/docker-compose.yml')); Console::success('Starting Appwrite installation...'); @@ -58,31 +56,37 @@ $cli } } - var_dump($input); + $templateForCompose = new View('../views/install/compose.phtml'); + $templateForEnv = new View('../views/install/env.phtml'); - // $composeUrl = $source.'/docker-compose.yml?'.http_build_query([ - // 'version' => $version, - // 'domain' => $domain, - // 'httpPort' => $httpPort, - // 'httpsPort' => $httpsPort, - // 'target' => $target, - // ]); - - // $composeFile = @file_get_contents($composeUrl); - - // if(!$composeFile) { - // throw new Exception('Failed to fetch Docker Compose file'); - // } + $templateForCompose + ->setParam('httpPort', $httpPort) + ->setParam('httpsPort', $httpsPort) + ->setParam('version', APP_VERSION_STABLE) + ; - // if(!file_put_contents('/install/appwrite/docker-compose.yml', $composeFile)) { - // throw new Exception('Failed to save Docker Compose file'); - // } + $templateForEnv + ->setParam('vars', $input) + ; + + $path = '/usr/src/code'; + + if(!file_put_contents($path.'/docker-compose.yml', $templateForCompose->render())) { + Console::error('Failed to save Docker Compose file'); + exit(1); + } + + if(!file_put_contents($path.'/.env', $templateForEnv->render())) { + Console::error('Failed to save environment variables file'); + exit(1); + } $stdout = ''; $stderr = ''; - Console::execute('docker-compose -f /install/appwrite/docker-compose.yml up -d', null, $stdout, $stderr); - if ($stdout != NULL) { + Console::execute("docker-compose -f {$path}.'/docker-compose.yml up -d --remove-orphans", null, $stdout, $stderr); + + if ($stderr !== '') { Console::error("Failed to install Appwrite dockers"); } else { Console::success("Appwrite installed successfully"); diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml new file mode 100644 index 000000000..c9e4932ae --- /dev/null +++ b/app/views/install/compose.phtml @@ -0,0 +1,327 @@ +getParam('httpPort', ''); +$httpsPort = $this->getParam('httpsPort', ''); +$version = $this->getParam('version', ''); +?>version: '3' + +services: + traefik: + image: traefik:2.2 + container_name: appwrite-traefik + command: + - --providers.file.directory=/storage/config + - --providers.file.watch=true + - --providers.docker=true + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + restart: unless-stopped + ports: + - :80 + - :443 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - appwrite-config:/storage/config:ro + - appwrite-certificates:/storage/certificates:ro + depends_on: + - appwrite + networks: + - gateway + - appwrite + + appwrite: + image: appwrite/appwrite: + container_name: appwrite + restart: unless-stopped + networks: + - appwrite + labels: + - traefik.http.routers.appwrite.rule=PathPrefix(`/`) + - traefik.http.routers.appwrite-secure.rule=PathPrefix(`/`) + - traefik.http.routers.appwrite-secure.tls=true + volumes: + - appwrite-uploads:/storage/uploads:rw + - appwrite-cache:/storage/cache:rw + - appwrite-config:/storage/config:rw + - appwrite-certificates:/storage/certificates:rw + - appwrite-functions:/storage/functions:rw + depends_on: + - mariadb + - redis + - clamav + - influxdb + environment: + - _APP_ENV + - _APP_OPTIONS_ABUSE + - _APP_OPTIONS_FORCE_HTTPS + - _APP_OPENSSL_KEY_V1 + - _APP_DOMAIN + - _APP_DOMAIN_TARGET + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_INFLUXDB_HOST + - _APP_INFLUXDB_PORT + - _APP_STORAGE_LIMIT + - _APP_FUNCTIONS_TIMEOUT + - _APP_FUNCTIONS_CONTAINERS + + appwrite-worker-usage: + image: appwrite/appwrite: + entrypoint: worker-usage + container_name: appwrite-worker-usage + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - telegraf + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_STATSD_HOST + - _APP_STATSD_PORT + + appwrite-worker-audits: + image: appwrite/appwrite: + entrypoint: worker-audits + container_name: appwrite-worker-audits + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-worker-webhooks: + image: appwrite/appwrite: + entrypoint: worker-webhooks + container_name: appwrite-worker-webhooks + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-worker-tasks: + image: appwrite/appwrite: + entrypoint: worker-tasks + container_name: appwrite-worker-tasks + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-worker-deletes: + image: appwrite/appwrite: + entrypoint: worker-deletes + container_name: appwrite-worker-deletes + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - appwrite-uploads:/storage/uploads:rw + - appwrite-cache:/storage/cache:rw + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-worker-certificates: + image: appwrite/appwrite: + entrypoint: worker-certificates + container_name: appwrite-worker-certificates + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - appwrite-config:/storage/config:rw + - appwrite-certificates:/storage/certificates:rw + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-worker-functions: + image: appwrite/appwrite: + entrypoint: worker-functions + container_name: appwrite-worker-functions + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /tmp:/tmp:rw + - appwrite-functions:/storage/functions:rw + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_FUNCTIONS_TIMEOUT + - _APP_FUNCTIONS_CONTAINERS + + appwrite-worker-mails: + image: appwrite/appwrite: + entrypoint: worker-mails + container_name: appwrite-worker-mails + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - smtp + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_SMTP_HOST + - _APP_SMTP_PORT + + appwrite-schedule: + image: appwrite/appwrite: + entrypoint: schedule + container_name: appwrite-schedule + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + + mariadb: + image: appwrite/mariadb:1.0.3 # fix issues when upgrading using: mysql_upgrade -u root -p + container_name: appwrite-mariadb + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-mariadb:/var/lib/mysql:rw + ports: + - "3306:3306" + environment: + - MYSQL_ROOT_PASSWORD=rootsecretpassword + - MYSQL_DATABASE=appwrite + - MYSQL_USER=user + - MYSQL_PASSWORD=password + command: 'mysqld --innodb-flush-method=fsync' + + smtp: + image: appwrite/smtp:1.0.1 + container_name: appwrite-smtp + restart: unless-stopped + networks: + - appwrite + environment: + - MAILNAME=appwrite + - RELAY_NETWORKS=:192.168.0.0/24:10.0.0.0/16 + + redis: + image: redis:5.0 + container_name: appwrite-redis + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-redis:/data:rw + + clamav: + image: appwrite/clamav:1.0.12 + container_name: appwrite-clamav + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-uploads:/storage/uploads + + influxdb: + image: influxdb:1.6 + container_name: appwrite-influxdb + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-influxdb:/var/lib/influxdb:rw + + telegraf: + image: appwrite/telegraf:1.0.0 + container_name: appwrite-telegraf + restart: unless-stopped + networks: + - appwrite + +networks: + gateway: + appwrite: + +volumes: + appwrite-mariadb: + appwrite-redis: + appwrite-cache: + appwrite-uploads: + appwrite-certificates: + appwrite-functions: + appwrite-influxdb: + appwrite-chronograf: + appwrite-config: diff --git a/app/views/install/env.phtml b/app/views/install/env.phtml new file mode 100644 index 000000000..c3ebb6f91 --- /dev/null +++ b/app/views/install/env.phtml @@ -0,0 +1,8 @@ +getParam('vars'); + +foreach ($vars as $key => $value) { + echo $key.'='.$value."\n"; +} +?> \ No newline at end of file From 9f386df16af06459bc5779dcd9a5f73c4cbcb91e Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Wed, 29 Jul 2020 10:29:34 +0300 Subject: [PATCH 04/12] Updated controllers naming --- app/config/services.php | 28 ++++++++++---------- app/{app.php => controllers/general.php} | 6 ++--- app/http.php | 2 +- app/preload.php | 4 +-- app/tasks/install.php | 33 ++++++++++++------------ public/index.php | 2 +- 6 files changed, 38 insertions(+), 37 deletions(-) rename app/{app.php => controllers/general.php} (99%) diff --git a/app/config/services.php b/app/config/services.php index cf5ee4392..e500f9a24 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -3,96 +3,96 @@ return [ '/' => [ 'name' => 'Homepage', - 'controller' => 'controllers/web/home.php', + 'controller' => 'web/home.php', 'sdk' => false, 'tests' => false, ], 'console/' => [ 'name' => 'Console', - 'controller' => 'controllers/web/console.php', + 'controller' => 'web/console.php', 'sdk' => false, 'tests' => false, ], 'v1/account' => [ 'name' => 'Account', 'description' => '/docs/services/account.md', - 'controller' => 'controllers/api/account.php', + 'controller' => 'api/account.php', 'sdk' => true, 'tests' => false, ], 'v1/avatars' => [ 'name' => 'Avatars', 'description' => '/docs/services/avatars.md', - 'controller' => 'controllers/api/avatars.php', + 'controller' => 'api/avatars.php', 'sdk' => true, 'tests' => false, ], 'v1/database' => [ 'name' => 'Database', 'description' => '/docs/services/database.md', - 'controller' => 'controllers/api/database.php', + 'controller' => 'api/database.php', 'sdk' => true, 'tests' => false, ], 'v1/locale' => [ 'name' => 'Locale', 'description' => '/docs/services/locale.md', - 'controller' => 'controllers/api/locale.php', + 'controller' => 'api/locale.php', 'sdk' => true, 'tests' => false, ], 'v1/health' => [ 'name' => 'Health', 'description' => '/docs/services/health.md', - 'controller' => 'controllers/api/health.php', + 'controller' => 'api/health.php', 'sdk' => true, 'tests' => false, ], 'v1/projects' => [ 'name' => 'Projects', - 'controller' => 'controllers/api/projects.php', + 'controller' => 'api/projects.php', 'sdk' => true, 'tests' => false, ], 'v1/storage' => [ 'name' => 'Storage', 'description' => '/docs/services/storage.md', - 'controller' => 'controllers/api/storage.php', + 'controller' => 'api/storage.php', 'sdk' => true, 'tests' => false, ], 'v1/teams' => [ 'name' => 'Teams', 'description' => '/docs/services/teams.md', - 'controller' => 'controllers/api/teams.php', + 'controller' => 'api/teams.php', 'sdk' => true, 'tests' => false, ], 'v1/users' => [ 'name' => 'Users', 'description' => '/docs/services/users.md', - 'controller' => 'controllers/api/users.php', + 'controller' => 'api/users.php', 'sdk' => true, 'tests' => false, ], 'v1/functions' => [ 'name' => 'Users', 'description' => '/docs/services/functions.md', - 'controller' => 'controllers/api/functions.php', + 'controller' => 'api/functions.php', 'sdk' => true, 'tests' => false, ], 'v1/mock' => [ 'name' => 'Mock', 'description' => '', - 'controller' => 'controllers/mock.php', + 'controller' => 'mock.php', 'sdk' => false, 'tests' => true, ], 'v1/graphql' => [ 'name' => 'GraphQL', 'description' => 'GraphQL Endpoint', - 'controller' => 'controllers/api/graphql.php', + 'controller' => 'api/graphql.php', 'sdk' => false, 'tests' => false, ], diff --git a/app/app.php b/app/controllers/general.php similarity index 99% rename from app/app.php rename to app/controllers/general.php index 90a2580e8..751e6cdb0 100644 --- a/app/app.php +++ b/app/controllers/general.php @@ -1,6 +1,6 @@ text($content); }, ['request', 'response']); -include_once __DIR__ . '/controllers/shared/api.php'; -include_once __DIR__ . '/controllers/shared/web.php'; +include_once __DIR__ . '/shared/api.php'; +include_once __DIR__ . '/shared/web.php'; foreach(Config::getParam('services', []) as $service) { include_once $service['controller']; diff --git a/app/http.php b/app/http.php index fd4f260a4..954037543 100644 --- a/app/http.php +++ b/app/http.php @@ -63,7 +63,7 @@ $http->on('start', function (Server $http) use ($payloadSize) { Files::load(__DIR__ . '/../public'); -include __DIR__ . '/app.php'; +include __DIR__ . '/controllers/general.php'; $domain = App::getEnv('_APP_DOMAIN', ''); diff --git a/app/preload.php b/app/preload.php index 7e5fe6654..e01a39aba 100644 --- a/app/preload.php +++ b/app/preload.php @@ -18,8 +18,8 @@ if (file_exists(__DIR__.'/../vendor/autoload.php')) { use Appwrite\Preloader\Preloader; -include 'init.php'; -include 'app.php'; +include './init.php'; +include './controllers/general.php'; (new Preloader()) ->paths(realpath(__DIR__ . '/../app/config')) diff --git a/app/tasks/install.php b/app/tasks/install.php index e00f761dc..815cd5796 100644 --- a/app/tasks/install.php +++ b/app/tasks/install.php @@ -17,7 +17,7 @@ $cli * 2.2. Get ENV vars * 2.2.1 Fetch from older docker-compose.yml file * 2.2.2 Fetch from older .env file (manually parse) - * 2.3 Use old ENV vars as default values + * 2.3 Use old ENV vars as default values * 2.4 Ask for all required vars not given as CLI args and if in interactive mode * Otherwise, just use default vars. - DONE * 3. Ask user to backup important volumes, env vars, and SQL tables @@ -26,21 +26,16 @@ $cli * 5. Run docker-compose up -d - DONE * 6. Run data migration */ - $vars = Config::getParam('variables'); Console::success('Starting Appwrite installation...'); - if(!empty($httpPort)) { - $httpPort = Console::confirm('Choose your server HTTP port: (default: 80)'); - $httpPort = ($httpPort) ? $httpPort : 80; - } - - if(!empty($httpsPort)) { - $httpsPort = Console::confirm('Choose your server HTTPS port: (default: 443)'); - $httpsPort = ($httpsPort) ? $httpsPort : 443; - } - + $httpPort = Console::confirm('Choose your server HTTP port: (default: 80)'); + $httpPort = ($httpPort) ? $httpPort : 80; + + $httpsPort = Console::confirm('Choose your server HTTPS port: (default: 443)'); + $httpsPort = ($httpsPort) ? $httpsPort : 443; + $input = []; foreach($vars as $key => $var) { @@ -56,8 +51,8 @@ $cli } } - $templateForCompose = new View('../views/install/compose.phtml'); - $templateForEnv = new View('../views/install/env.phtml'); + $templateForCompose = new View(__DIR__.'/../views/install/compose.phtml'); + $templateForEnv = new View(__DIR__.'/../views/install/env.phtml'); $templateForCompose ->setParam('httpPort', $httpPort) @@ -71,12 +66,12 @@ $cli $path = '/usr/src/code'; - if(!file_put_contents($path.'/docker-compose.yml', $templateForCompose->render())) { + if(!file_put_contents($path.'/docker-compose.yml', $templateForCompose->render(false))) { Console::error('Failed to save Docker Compose file'); exit(1); } - if(!file_put_contents($path.'/.env', $templateForEnv->render())) { + if(!file_put_contents($path.'/.env', $templateForEnv->render(false))) { Console::error('Failed to save environment variables file'); exit(1); } @@ -91,4 +86,10 @@ $cli } else { Console::success("Appwrite installed successfully"); } + + $files1 = scandir($path); + + var_dump($files1); + var_dump(file_get_contents($path.'/.env')); + var_dump(file_get_contents($path.'/docker-compose.yml')); }); \ No newline at end of file diff --git a/public/index.php b/public/index.php index 3aa0984c7..01f9dbb11 100644 --- a/public/index.php +++ b/public/index.php @@ -20,7 +20,7 @@ ini_set('display_startup_errors', 1); error_reporting(E_ALL); //trigger_error('hide errors in prod', E_USER_NOTICE); -include __DIR__ . '/../app/app.php'; +include __DIR__ . '/../app/controllers/general.php'; $app = new App('Asia/Tel_Aviv'); From 15c24f8d9aab1750094e951be56d181308e58549 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Wed, 29 Jul 2020 18:26:01 +0300 Subject: [PATCH 05/12] Added docker compose parsers --- app/preload.php | 3 +- src/Appwrite/Docker/Compose.php | 73 ++++ src/Appwrite/Docker/Compose/Service.php | 38 ++ src/Appwrite/Docker/Env.php | 69 ++++ tests/resources/docker/.env | 3 + tests/resources/docker/docker-compose.yml | 409 ++++++++++++++++++++++ tests/unit/Docker/ComposeTest.php | 56 +++ tests/unit/Docker/EnvTest.php | 49 +++ 8 files changed, 698 insertions(+), 2 deletions(-) create mode 100644 src/Appwrite/Docker/Compose.php create mode 100644 src/Appwrite/Docker/Compose/Service.php create mode 100644 src/Appwrite/Docker/Env.php create mode 100644 tests/resources/docker/.env create mode 100644 tests/resources/docker/docker-compose.yml create mode 100644 tests/unit/Docker/ComposeTest.php create mode 100644 tests/unit/Docker/EnvTest.php diff --git a/app/preload.php b/app/preload.php index e01a39aba..63d08c3e1 100644 --- a/app/preload.php +++ b/app/preload.php @@ -18,8 +18,7 @@ if (file_exists(__DIR__.'/../vendor/autoload.php')) { use Appwrite\Preloader\Preloader; -include './init.php'; -include './controllers/general.php'; +include __DIR__.'/controllers/general.php'; (new Preloader()) ->paths(realpath(__DIR__ . '/../app/config')) diff --git a/src/Appwrite/Docker/Compose.php b/src/Appwrite/Docker/Compose.php new file mode 100644 index 000000000..d186f9479 --- /dev/null +++ b/src/Appwrite/Docker/Compose.php @@ -0,0 +1,73 @@ +compose = yaml_parse($data); + + $this->compose['services'] = (isset($this->compose['services']) && is_array($this->compose['services'])) + ? $this->compose['services'] : []; + + foreach ($this->compose['services'] as $key => &$service) { + $service = new Service($service); + } + } + + /** + * @return array + */ + public function getVersion(): string + { + return (isset($this->compose['version'])) ? $this->compose['version'] : ''; + } + + /** + * @return Service[] + */ + public function getServices(): array + { + return $this->compose['services']; + } + + /** + * @return Service + */ + public function getService(string $name): Service + { + if(!isset($this->compose['services'][$name])) { + throw new Exception('Service not found'); + } + + return $this->compose['services'][$name]; + } + + /** + * @return array + */ + public function getNetworks(): array + { + return (isset($this->compose['networks'])) ? array_keys($this->compose['networks']) : []; + } + + /** + * @return array + */ + public function getVolumes(): array + { + return (isset($this->compose['volumes'])) ? array_keys($this->compose['volumes']) : []; + } +} diff --git a/src/Appwrite/Docker/Compose/Service.php b/src/Appwrite/Docker/Compose/Service.php new file mode 100644 index 000000000..19a3cd695 --- /dev/null +++ b/src/Appwrite/Docker/Compose/Service.php @@ -0,0 +1,38 @@ +service = $service; + $this->service['environment'] = isset($this->service['environment']) ? new Env(implode("\n", $this->service['environment'])) : null; + } + + /** + * @return array + */ + public function getContainerName(): string + { + return (isset($this->service['container_name'])) ? $this->service['container_name'] : ''; + } + + /** + * @return array + */ + public function getImage(): string + { + return (isset($this->service['image'])) ? $this->service['image'] : ''; + } +} diff --git a/src/Appwrite/Docker/Env.php b/src/Appwrite/Docker/Env.php new file mode 100644 index 000000000..47ef46e01 --- /dev/null +++ b/src/Appwrite/Docker/Env.php @@ -0,0 +1,69 @@ +vars[$key] = $value; + } + } + } + + /** + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function setVar(string $key, $value): self + { + $this->vars[$key] = $value; + + return $this; + } + + /** + * @param string $key + * + * @return mixed|null + */ + public function getVar(string $key): string + { + return (isset($this->vars[$key])) ? $this->vars[$key] : ''; + } + + /** + * @return string + */ + public function export(): string + { + $output = ''; + + foreach ($this->vars as $key => $value) { + $output .= $key.'='.$value."\n"; + } + + return $output; + } +} diff --git a/tests/resources/docker/.env b/tests/resources/docker/.env new file mode 100644 index 000000000..1c1359f0f --- /dev/null +++ b/tests/resources/docker/.env @@ -0,0 +1,3 @@ +_APP_X=value1 +_APP_Y=value2 +_APP_Z = value3 \ No newline at end of file diff --git a/tests/resources/docker/docker-compose.yml b/tests/resources/docker/docker-compose.yml new file mode 100644 index 000000000..484f73b42 --- /dev/null +++ b/tests/resources/docker/docker-compose.yml @@ -0,0 +1,409 @@ +version: '3' + +services: + traefik: + image: traefik:2.2 + container_name: appwrite-traefik + command: + - --log.level=DEBUG + - --api.insecure=true + - --providers.file.directory=/storage/config + - --providers.file.watch=true + - --providers.docker=true + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + - --accesslog=true + restart: unless-stopped + ports: + - 80:80 + - 443:443 + - 8080:8080 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - appwrite-config:/storage/config:ro + - appwrite-certificates:/storage/certificates:ro + depends_on: + - appwrite + networks: + - gateway + - appwrite + + appwrite: + container_name: appwrite + build: + context: . + args: + - TESTING=true + - VERSION=dev + restart: unless-stopped + ports: + - 9501:80 + networks: + - appwrite + labels: + - traefik.http.routers.appwrite.rule=PathPrefix(`/`) + - traefik.http.routers.appwrite-secure.rule=PathPrefix(`/`) + - traefik.http.routers.appwrite-secure.tls=true + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - appwrite-uploads:/storage/uploads:rw + - appwrite-cache:/storage/cache:rw + - appwrite-config:/storage/config:rw + - appwrite-certificates:/storage/certificates:rw + - appwrite-functions:/storage/functions:rw + - ./phpunit.xml:/usr/src/code/phpunit.xml + - ./tests:/usr/src/code/tests + - ./app:/usr/src/code/app + # - ./vendor:/usr/src/code/vendor + - ./docs:/usr/src/code/docs + - ./public:/usr/src/code/public + - ./src:/usr/src/code/src + - ./debug:/tmp + depends_on: + - mariadb + - redis + - clamav + - influxdb + environment: + - _APP_ENV + - _APP_OPTIONS_ABUSE + - _APP_OPTIONS_FORCE_HTTPS + - _APP_OPENSSL_KEY_V1 + - _APP_DOMAIN + - _APP_DOMAIN_TARGET + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_INFLUXDB_HOST + - _APP_INFLUXDB_PORT + - _APP_STORAGE_LIMIT + - _APP_FUNCTIONS_TIMEOUT + - _APP_FUNCTIONS_CONTAINERS + + appwrite-worker-usage: + entrypoint: worker-usage + container_name: appwrite-worker-usage + build: + context: . + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - telegraf + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_STATSD_HOST + - _APP_STATSD_PORT + + appwrite-worker-audits: + entrypoint: worker-audits + container_name: appwrite-worker-audits + build: + context: . + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-worker-webhooks: + entrypoint: worker-webhooks + container_name: appwrite-worker-webhooks + build: + context: . + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-worker-tasks: + entrypoint: worker-tasks + container_name: appwrite-worker-tasks + build: + context: . + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-worker-deletes: + entrypoint: worker-deletes + container_name: appwrite-worker-deletes + build: + context: . + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - appwrite-uploads:/storage/uploads:rw + - appwrite-cache:/storage/cache:rw + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-worker-certificates: + entrypoint: worker-certificates + container_name: appwrite-worker-certificates + build: + context: . + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - appwrite-config:/storage/config:rw + - appwrite-certificates:/storage/certificates:rw + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + + appwrite-worker-functions: + entrypoint: worker-functions + container_name: appwrite-worker-functions + build: + context: . + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /tmp:/tmp:rw + - appwrite-functions:/storage/functions:rw + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_FUNCTIONS_TIMEOUT + - _APP_FUNCTIONS_CONTAINERS + + appwrite-worker-mails: + entrypoint: worker-mails + container_name: appwrite-worker-mails + build: + context: . + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - maildev + # - smtp + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_SMTP_HOST + - _APP_SMTP_PORT + + appwrite-schedule: + entrypoint: schedule + container_name: appwrite-schedule + build: + context: . + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + + mariadb: + image: appwrite/mariadb:1.0.3 # fix issues when upgrading using: mysql_upgrade -u root -p + container_name: appwrite-mariadb + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-mariadb:/var/lib/mysql:rw + ports: + - "3306:3306" + environment: + - MYSQL_ROOT_PASSWORD=rootsecretpassword + - MYSQL_DATABASE=appwrite + - MYSQL_USER=user + - MYSQL_PASSWORD=password + command: 'mysqld --innodb-flush-method=fsync' + + maildev: + image: djfarrelly/maildev + container_name: appwrite-maildev + restart: unless-stopped + ports: + - '1080:80' + networks: + - appwrite + + # smtp: + # image: appwrite/smtp:1.0.1 + # container_name: appwrite-smtp + # restart: unless-stopped + # networks: + # - appwrite + # environment: + # - MAILNAME=appwrite + # - RELAY_NETWORKS=:192.168.0.0/24:10.0.0.0/16 + + redis: + image: redis:5.0 + container_name: appwrite-redis + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-redis:/data:rw + + clamav: + image: appwrite/clamav:1.0.12 + container_name: appwrite-clamav + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-uploads:/storage/uploads + + influxdb: + image: influxdb:1.6 + container_name: appwrite-influxdb + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-influxdb:/var/lib/influxdb:rw + + telegraf: + image: appwrite/telegraf:1.0.0 + container_name: appwrite-telegraf + restart: unless-stopped + networks: + - appwrite + + # redis-commander: + # image: rediscommander/redis-commander:latest + # restart: unless-stopped + # networks: + # - appwrite + # environment: + # - REDIS_HOSTS=redis + # ports: + # - "8081:8081" + + # resque: + # image: registry.gitlab.com/appwrite/appwrite/resque-web:v1.0.2 + # restart: unless-stopped + # networks: + # - appwrite + # ports: + # - "5678:5678" + # environment: + # - RESQUE_WEB_HOST=redis + # - RESQUE_WEB_PORT=6379 + # - RESQUE_WEB_HTTP_BASIC_AUTH_USER=user + # - RESQUE_WEB_HTTP_BASIC_AUTH_PASSWORD=password + + # chronograf: + # image: chronograf:1.5 + # container_name: appwrite-chronograf + # restart: unless-stopped + # networks: + # - appwrite + # volumes: + # - appwrite-chronograf:/var/lib/chronograf + # ports: + # - "8888:8888" + # environment: + # - INFLUXDB_URL=http://influxdb:8086 + # - KAPACITOR_URL=http://kapacitor:9092 + # - AUTH_DURATION=48h + # - TOKEN_SECRET=duperduper5674829!jwt + # - GH_CLIENT_ID=d86f7145a41eacfc52cc + # - GH_CLIENT_SECRET=9e0081062367a2134e7f2ea95ba1a32d08b6c8ab + # - GH_ORGS=appwrite + + # webgrind: + # image: 'jokkedk/webgrind:latest' + # volumes: + # - './debug:/tmp' + # ports: + # - '3001:80' + +networks: + gateway: + appwrite: + +volumes: + appwrite-mariadb: + appwrite-redis: + appwrite-cache: + appwrite-uploads: + appwrite-certificates: + appwrite-functions: + appwrite-influxdb: + appwrite-chronograf: + appwrite-config: diff --git a/tests/unit/Docker/ComposeTest.php b/tests/unit/Docker/ComposeTest.php new file mode 100644 index 000000000..59cf3cffb --- /dev/null +++ b/tests/unit/Docker/ComposeTest.php @@ -0,0 +1,56 @@ +object = new Compose($data); + } + + public function tearDown() + { + } + + public function testVersion() + { + $this->assertEquals('3', $this->object->getVersion()); + } + + public function testServices() + { + $this->assertCount(17, $this->object->getServices()); + $this->assertEquals('appwrite-telegraf', $this->object->getService('telegraf')->getContainerName()); + $this->assertEquals('appwrite', $this->object->getService('appwrite')->getContainerName()); + } + + public function testNetworks() + { + $this->assertCount(2, $this->object->getNetworks()); + } + + public function testVolumes() + { + $this->assertCount(9, $this->object->getVolumes()); + $this->assertEquals('appwrite-mariadb', $this->object->getVolumes()[0]); + $this->assertEquals('appwrite-redis', $this->object->getVolumes()[1]); + $this->assertEquals('appwrite-cache', $this->object->getVolumes()[2]); + } +} \ No newline at end of file diff --git a/tests/unit/Docker/EnvTest.php b/tests/unit/Docker/EnvTest.php new file mode 100644 index 000000000..ce4d4b391 --- /dev/null +++ b/tests/unit/Docker/EnvTest.php @@ -0,0 +1,49 @@ +object = new Env($data); + } + + public function tearDown() + { + } + + public function testVars() + { + $this->object->setVar('_APP_TEST', 'value4'); + + $this->assertEquals('value1', $this->object->getVar('_APP_X')); + $this->assertEquals('value2', $this->object->getVar('_APP_Y')); + $this->assertEquals('value3', $this->object->getVar('_APP_Z')); + $this->assertEquals('value4', $this->object->getVar('_APP_TEST')); + } + + public function testExport() + { + $this->assertEquals("_APP_X=value1 +_APP_Y=value2 +_APP_Z=value3 +", $this->object->export()); + } +} \ No newline at end of file From df9957357ce2a81eb408212369005f682a555239 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Thu, 30 Jul 2020 10:23:25 +0300 Subject: [PATCH 06/12] Fixed typo --- app/config/variables.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/config/variables.php b/app/config/variables.php index 06e701c3f..c1b998276 100644 --- a/app/config/variables.php +++ b/app/config/variables.php @@ -35,7 +35,7 @@ return [ 'name' => '_APP_DOMAIN_TARGET', 'default' => 'localhost', 'required' => true, - 'question' => "Enter a DNS A record hostname to server as a CNAME for your custom domains.\nYou can use the same value as used for the Appwrite hostname.", + 'question' => "Enter a DNS A record hostname to serve as a CNAME for your custom domains.\nYou can use the same value as used for the Appwrite hostname.", ], [ 'name' => '_APP_REDIS_HOST', From 54c0e8bf824ad9e4326573170a63e9e1d8b2c89f Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Thu, 30 Jul 2020 21:26:40 +0300 Subject: [PATCH 07/12] Removed leftovers --- app/tasks/migrate.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/tasks/migrate.php b/app/tasks/migrate.php index 36773b35b..efa06e1fe 100644 --- a/app/tasks/migrate.php +++ b/app/tasks/migrate.php @@ -147,9 +147,7 @@ function fixDocument(Document $document) { ->removeAttribute('$uid') ; - //Console::log('Switched from $uid to $id: '.$document->getCollection().'/'.$document->getId()); - - foreach($document as &$attr) { + foreach($document as &$attr) { // Handle child documents if($attr instanceof Document) { $attr = fixDocument($attr); } From a447f2129759dcf4c9a55a899171a72f1ef0a840 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 31 Jul 2020 09:31:29 +0300 Subject: [PATCH 08/12] Fetch old version and env vars --- app/tasks/install.php | 41 ++++++++++++++++++++++--- src/Appwrite/Docker/Compose/Service.php | 23 ++++++++++++-- src/Appwrite/Docker/Env.php | 10 ++++++ tests/unit/Docker/ComposeTest.php | 2 ++ 4 files changed, 68 insertions(+), 8 deletions(-) diff --git a/app/tasks/install.php b/app/tasks/install.php index 815cd5796..59af8ba28 100644 --- a/app/tasks/install.php +++ b/app/tasks/install.php @@ -2,6 +2,7 @@ global $cli; +use Appwrite\Docker\Compose; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\View; @@ -12,9 +13,9 @@ $cli ->action(function () { /** * 1. Start - DONE - * 2. Check for older setup and get older version + * 2. Check for older setup and get older version - DONE * 2.1 If older version is equal or bigger(?) than current version, **stop setup** - * 2.2. Get ENV vars + * 2.2. Get ENV vars - DONE * 2.2.1 Fetch from older docker-compose.yml file * 2.2.2 Fetch from older .env file (manually parse) * 2.3 Use old ENV vars as default values @@ -22,14 +23,46 @@ $cli * Otherwise, just use default vars. - DONE * 3. Ask user to backup important volumes, env vars, and SQL tables * In th future we can try and automate this for smaller/medium size setups - * 4. Drop new docker-compose.yml setup (located inside the container, no network dependencies with appwrite.io) + * 4. Drop new docker-compose.yml setup (located inside the container, no network dependencies with appwrite.io) - DONE * 5. Run docker-compose up -d - DONE * 6. Run data migration */ $vars = Config::getParam('variables'); + $path = '/usr/src/code/appwrite'; + $version = null; Console::success('Starting Appwrite installation...'); + // Create directory with write permissions + if (null !== $path && !\file_exists(\dirname($path))) { + if (!@\mkdir(\dirname($path), 0755, true)) { + Console::error('Can\'t create directory '.\dirname($path)); + exit(1); + } + } + + $data = @file_get_contents($path.'/docker-compose.yml'); + + if($data !== false) { + $compose = new Compose($data); + $service = $compose->getService('appwrite'); + $version = ($service) ? $service->getImageVersion() : $version; + + if($version) { + foreach($compose->getServices() as $service) { // Fetch all env vars from previous compose file + if(!$service) { + continue; + } + + $env = $service->getEnvironment()->list(); + + var_dump($env); + } + + // Fetch all env vars from previous .env file + } + } + $httpPort = Console::confirm('Choose your server HTTP port: (default: 80)'); $httpPort = ($httpPort) ? $httpPort : 80; @@ -64,8 +97,6 @@ $cli ->setParam('vars', $input) ; - $path = '/usr/src/code'; - if(!file_put_contents($path.'/docker-compose.yml', $templateForCompose->render(false))) { Console::error('Failed to save Docker Compose file'); exit(1); diff --git a/src/Appwrite/Docker/Compose/Service.php b/src/Appwrite/Docker/Compose/Service.php index 19a3cd695..633405947 100644 --- a/src/Appwrite/Docker/Compose/Service.php +++ b/src/Appwrite/Docker/Compose/Service.php @@ -17,11 +17,11 @@ class Service public function __construct(array $service) { $this->service = $service; - $this->service['environment'] = isset($this->service['environment']) ? new Env(implode("\n", $this->service['environment'])) : null; + $this->service['environment'] = isset($this->service['environment']) ? new Env(implode("\n", $this->service['environment'])) : new Env(''); } /** - * @return array + * @return string */ public function getContainerName(): string { @@ -29,10 +29,27 @@ class Service } /** - * @return array + * @return string */ public function getImage(): string { return (isset($this->service['image'])) ? $this->service['image'] : ''; } + + /** + * @return string + */ + public function getImageVersion(): string + { + $image = $this->getImage(); + return substr($image, strpos($image, ':')+1); + } + + /** + * @return string + */ + public function getEnvironment(): Env + { + return $this->service['environment']; + } } diff --git a/src/Appwrite/Docker/Env.php b/src/Appwrite/Docker/Env.php index 47ef46e01..c1f25d5e4 100644 --- a/src/Appwrite/Docker/Env.php +++ b/src/Appwrite/Docker/Env.php @@ -53,6 +53,16 @@ class Env return (isset($this->vars[$key])) ? $this->vars[$key] : ''; } + /** + * Get All Vars + * + * @return array + */ + public function list(): array + { + return $this->vars; + } + /** * @return string */ diff --git a/tests/unit/Docker/ComposeTest.php b/tests/unit/Docker/ComposeTest.php index 59cf3cffb..a682269a0 100644 --- a/tests/unit/Docker/ComposeTest.php +++ b/tests/unit/Docker/ComposeTest.php @@ -39,6 +39,8 @@ class ComposeTest extends TestCase $this->assertCount(17, $this->object->getServices()); $this->assertEquals('appwrite-telegraf', $this->object->getService('telegraf')->getContainerName()); $this->assertEquals('appwrite', $this->object->getService('appwrite')->getContainerName()); + $this->assertEquals('', $this->object->getService('appwrite')->getImageVersion()); + $this->assertEquals('2.2', $this->object->getService('traefik')->getImageVersion()); } public function testNetworks() From 280f2e4296dab9e4b6e4abef7f8cda4576d10280 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 31 Jul 2020 15:49:15 +0300 Subject: [PATCH 09/12] Updated README setup instructions --- README.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2a498451f..a34d4362b 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,8 @@ The easiest way to start running your Appwrite server is by running our docker-c ```bash docker run -it --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ - --volume "$(pwd)"/appwrite:/install/appwrite:rw \ - -e version=0.7.0 \ - appwrite/install + --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \ + appwrite/appwrite:0.7.0 ``` ### Windows @@ -62,9 +61,8 @@ docker run -it --rm \ ```cmd docker run -it --rm ^ --volume //var/run/docker.sock:/var/run/docker.sock ^ - --volume "%cd%"/appwrite:/install/appwrite:rw ^ - -e version=0.7.0 ^ - appwrite/install + --volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^ + appwrite/appwrite:0.7.0 ``` #### PowerShell @@ -72,9 +70,8 @@ docker run -it --rm ^ ```powershell docker run -it --rm , --volume /var/run/docker.sock:/var/run/docker.sock , - --volume ${pwd}/appwrite:/install/appwrite:rw , - -e version=0.7.0 , - appwrite/install + --volume ${pwd}/appwrite:/usr/src/code/appwrite:rw , + appwrite/appwrite:0.7.0 ``` Once the Docker installation completes, go to http://localhost to access the Appwrite console from your browser. Please note that on non-linux native hosts, the server might take a few minutes to start after installation completes. From 674c003da9e02cd097ca5367a2063ba674e85a86 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 31 Jul 2020 15:49:44 +0300 Subject: [PATCH 10/12] Fetch default ports --- app/tasks/install.php | 60 +++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/app/tasks/install.php b/app/tasks/install.php index 59af8ba28..6b24fde75 100644 --- a/app/tasks/install.php +++ b/app/tasks/install.php @@ -3,6 +3,7 @@ global $cli; use Appwrite\Docker\Compose; +use Appwrite\Docker\Env; use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\View; @@ -30,6 +31,8 @@ $cli $vars = Config::getParam('variables'); $path = '/usr/src/code/appwrite'; $version = null; + $defaultHTTPPort = '80'; + $defaultHTTPSPort = '443'; Console::success('Starting Appwrite installation...'); @@ -45,8 +48,9 @@ $cli if($data !== false) { $compose = new Compose($data); - $service = $compose->getService('appwrite'); - $version = ($service) ? $service->getImageVersion() : $version; + $appwrite = $compose->getService('appwrite'); + $version = ($appwrite) ? $appwrite->getImageVersion() : $version; + $ports = $compose->getService('traefik')->getPorts(); if($version) { foreach($compose->getServices() as $service) { // Fetch all env vars from previous compose file @@ -56,18 +60,46 @@ $cli $env = $service->getEnvironment()->list(); - var_dump($env); + foreach ($env as $key => $value) { + foreach($vars as &$var) { + if($var['name'] === $key) { + $var['default'] = $value; + } + } + } } - // Fetch all env vars from previous .env file + $data = @file_get_contents($path.'/.env'); + + if($data !== false) { // Fetch all env vars from previous .env file + $env = new Env($data); + + foreach ($env->list() as $key => $value) { + foreach($vars as &$var) { + if($var['name'] === $key) { + $var['default'] = $value; + } + } + } + } + + foreach ($ports as $key => $value) { + if($value === $defaultHTTPPort) { + $defaultHTTPPort = $key; + } + + if($value === $defaultHTTPSPort) { + $defaultHTTPSPort = $key; + } + } } } - $httpPort = Console::confirm('Choose your server HTTP port: (default: 80)'); - $httpPort = ($httpPort) ? $httpPort : 80; + $httpPort = Console::confirm('Choose your server HTTP port: (default: '.$defaultHTTPPort.')'); + $httpPort = ($httpPort) ? $httpPort : $defaultHTTPPort; - $httpsPort = Console::confirm('Choose your server HTTPS port: (default: 443)'); - $httpsPort = ($httpsPort) ? $httpsPort : 443; + $httpsPort = Console::confirm('Choose your server HTTPS port: (default: '.$defaultHTTPSPort.')'); + $httpsPort = ($httpsPort) ? $httpsPort : $defaultHTTPPort; $input = []; @@ -97,12 +129,12 @@ $cli ->setParam('vars', $input) ; - if(!file_put_contents($path.'/docker-compose.yml', $templateForCompose->render(false))) { + if(!file_put_contents($path.'/docker-compose.yml.xx', $templateForCompose->render(false))) { Console::error('Failed to save Docker Compose file'); exit(1); } - if(!file_put_contents($path.'/.env', $templateForEnv->render(false))) { + if(!file_put_contents($path.'/.env.xx', $templateForEnv->render(false))) { Console::error('Failed to save environment variables file'); exit(1); } @@ -110,17 +142,11 @@ $cli $stdout = ''; $stderr = ''; - Console::execute("docker-compose -f {$path}.'/docker-compose.yml up -d --remove-orphans", null, $stdout, $stderr); + //Console::execute("docker-compose -f {$path}.'/docker-compose.yml up -d --remove-orphans", null, $stdout, $stderr); if ($stderr !== '') { Console::error("Failed to install Appwrite dockers"); } else { Console::success("Appwrite installed successfully"); } - - $files1 = scandir($path); - - var_dump($files1); - var_dump(file_get_contents($path.'/.env')); - var_dump(file_get_contents($path.'/docker-compose.yml')); }); \ No newline at end of file From e5d26d74eb9463d13838b52b3aa1b202d3f2f404 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 31 Jul 2020 15:49:52 +0300 Subject: [PATCH 11/12] Fixed template --- app/views/install/compose.phtml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index c9e4932ae..7df932c9e 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -30,7 +30,7 @@ services: - appwrite appwrite: - image: appwrite/appwrite: + image: appwrite/appwrite: container_name: appwrite restart: unless-stopped networks: @@ -71,7 +71,7 @@ services: - _APP_FUNCTIONS_CONTAINERS appwrite-worker-usage: - image: appwrite/appwrite: + image: appwrite/appwrite: entrypoint: worker-usage container_name: appwrite-worker-usage restart: unless-stopped @@ -88,7 +88,7 @@ services: - _APP_STATSD_PORT appwrite-worker-audits: - image: appwrite/appwrite: + image: appwrite/appwrite: entrypoint: worker-audits container_name: appwrite-worker-audits restart: unless-stopped @@ -108,7 +108,7 @@ services: - _APP_DB_PASS appwrite-worker-webhooks: - image: appwrite/appwrite: + image: appwrite/appwrite: entrypoint: worker-webhooks container_name: appwrite-worker-webhooks restart: unless-stopped @@ -128,7 +128,7 @@ services: - _APP_DB_PASS appwrite-worker-tasks: - image: appwrite/appwrite: + image: appwrite/appwrite: entrypoint: worker-tasks container_name: appwrite-worker-tasks restart: unless-stopped @@ -148,7 +148,7 @@ services: - _APP_DB_PASS appwrite-worker-deletes: - image: appwrite/appwrite: + image: appwrite/appwrite: entrypoint: worker-deletes container_name: appwrite-worker-deletes restart: unless-stopped @@ -171,7 +171,7 @@ services: - _APP_DB_PASS appwrite-worker-certificates: - image: appwrite/appwrite: + image: appwrite/appwrite: entrypoint: worker-certificates container_name: appwrite-worker-certificates restart: unless-stopped @@ -194,7 +194,7 @@ services: - _APP_DB_PASS appwrite-worker-functions: - image: appwrite/appwrite: + image: appwrite/appwrite: entrypoint: worker-functions container_name: appwrite-worker-functions restart: unless-stopped @@ -220,7 +220,7 @@ services: - _APP_FUNCTIONS_CONTAINERS appwrite-worker-mails: - image: appwrite/appwrite: + image: appwrite/appwrite: entrypoint: worker-mails container_name: appwrite-worker-mails restart: unless-stopped @@ -237,7 +237,7 @@ services: - _APP_SMTP_PORT appwrite-schedule: - image: appwrite/appwrite: + image: appwrite/appwrite: entrypoint: schedule container_name: appwrite-schedule restart: unless-stopped From 40b7a1de7f9182f2b1936a3237eb6c0481dcfc2f Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Fri, 31 Jul 2020 15:50:39 +0300 Subject: [PATCH 12/12] Added default ports --- app/tasks/install.php | 4 ++-- src/Appwrite/Docker/Compose/Service.php | 24 +++++++++++++++++++++-- tests/resources/docker/docker-compose.yml | 4 ++-- tests/unit/Docker/ComposeTest.php | 1 + 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/app/tasks/install.php b/app/tasks/install.php index 6b24fde75..3b3aa4ea6 100644 --- a/app/tasks/install.php +++ b/app/tasks/install.php @@ -129,12 +129,12 @@ $cli ->setParam('vars', $input) ; - if(!file_put_contents($path.'/docker-compose.yml.xx', $templateForCompose->render(false))) { + if(!file_put_contents($path.'/docker-compose.yml', $templateForCompose->render(false))) { Console::error('Failed to save Docker Compose file'); exit(1); } - if(!file_put_contents($path.'/.env.xx', $templateForEnv->render(false))) { + if(!file_put_contents($path.'/.env', $templateForEnv->render(false))) { Console::error('Failed to save environment variables file'); exit(1); } diff --git a/src/Appwrite/Docker/Compose/Service.php b/src/Appwrite/Docker/Compose/Service.php index 633405947..dcb4ce737 100644 --- a/src/Appwrite/Docker/Compose/Service.php +++ b/src/Appwrite/Docker/Compose/Service.php @@ -17,7 +17,19 @@ class Service public function __construct(array $service) { $this->service = $service; - $this->service['environment'] = isset($this->service['environment']) ? new Env(implode("\n", $this->service['environment'])) : new Env(''); + + $ports = (isset($this->service['ports']) && is_array($this->service['ports'])) ? $this->service['ports'] : []; + $this->service['ports'] = []; + + array_walk($ports, function(&$value, &$key) { + $split = explode(':', $value); + $this->service['ports'][ + (isset($split[0])) ? $split[0] : '' + ] = (isset($split[1])) ? $split[1] : ''; + }); + + $this->service['environment'] = (isset($this->service['environment']) && is_array($this->service['environment'])) ? $this->service['environment'] : []; + $this->service['environment'] = new Env(implode("\n", $this->service['environment'])); } /** @@ -46,10 +58,18 @@ class Service } /** - * @return string + * @return Env */ public function getEnvironment(): Env { return $this->service['environment']; } + + /** + * @return array + */ + public function getPorts(): array + { + return $this->service['ports']; + } } diff --git a/tests/resources/docker/docker-compose.yml b/tests/resources/docker/docker-compose.yml index 484f73b42..4a3192947 100644 --- a/tests/resources/docker/docker-compose.yml +++ b/tests/resources/docker/docker-compose.yml @@ -15,8 +15,8 @@ services: - --accesslog=true restart: unless-stopped ports: - - 80:80 - - 443:443 + - 2080:80 + - 2443:443 - 8080:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock diff --git a/tests/unit/Docker/ComposeTest.php b/tests/unit/Docker/ComposeTest.php index a682269a0..b7d7c40fa 100644 --- a/tests/unit/Docker/ComposeTest.php +++ b/tests/unit/Docker/ComposeTest.php @@ -41,6 +41,7 @@ class ComposeTest extends TestCase $this->assertEquals('appwrite', $this->object->getService('appwrite')->getContainerName()); $this->assertEquals('', $this->object->getService('appwrite')->getImageVersion()); $this->assertEquals('2.2', $this->object->getService('traefik')->getImageVersion()); + $this->assertEquals(['2080' => '80', '2443' => '443', '8080' => '8080'], $this->object->getService('traefik')->getPorts()); } public function testNetworks()