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