From d5436fbd5f84c47dc6a046f8e34313f8730160f6 Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 18:48:49 +0930 Subject: [PATCH 01/30] Update Installer.php --- app/Console/Commands/Installer.php | 442 +++++++++++++++++------------ 1 file changed, 253 insertions(+), 189 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index c71f2e02..f6dcb7c2 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -57,52 +57,69 @@ class Installer extends Command $this->info(' '); $this->info('Pixelfed version: ' . config('pixelfed.version')); $this->line(' '); + $this->installerSteps(); + } + + protected function installerSteps() + { $this->envCheck(); + $this->envCreate(); + $this->installType(); + + if($this->installType === 'Production') { + $this->info('Installer: Production...'); + $this->checkPHPDependencies(); + $this->checkFFmpegDependencies(); + $this->checkDiskPermissions(); + $this->envProd(); + $this->instanceDB(); + $this->instanceRedis(); + $this->instanceURL(); + $this->activityPubSettings(); + $this->laravelSettings(); + $this->instanceSettings(); + $this->mediaSettings(); + $this->dbMigrations(); + $this->resetArtisanCache(); + } else { + $this->info('Installer: Simple...'); + exit; + } } protected function envCheck() { if( file_exists(base_path('.env')) && - filesize(base_path('.env')) !== 0 && - !$this->option('dangerously-overwrite-env') + filesize(base_path('.env')) !== 0 && + !$this->option('dangerously-overwrite-env') ) { $this->line(''); - $this->error('Installation aborted, found existing .env file'); - $this->line('Run the following command to re-run the installer:'); - $this->line(''); - $this->info('php artisan install --dangerously-overwrite-env'); + $this->error('Existing .env File Found - Installation Aborted'); + $this->line('Run the following command to re-run the installer: php artisan install --dangerously-overwrite-env'); $this->line(''); exit; } - $this->installType(); + } + + protected function envCreate() + { + $this->line(''); + if(!file_exists(app()->environmentFilePath())) { + exec('cp .env.installer .env'); + } } protected function installType() { - $type = $this->choice('Select installation type', ['Simple', 'Advanced'], 0); - $this->installType = $type; - $this->preflightCheck(); + $type = $this->choice('Select installation type', ['Simple', 'Production'], 1); + $this->installType = $type; } - protected function preflightCheck() + protected function checkPHPDependencies() { - if($this->installType === 'Advanced') { - $this->info('Scanning system...'); - $this->line(' '); - $this->info('Checking for installed dependencies...'); - $redis = Redis::connection(); - if($redis->ping()) { - $this->info('- Found redis!'); - } else { - $this->error('- Redis not found, aborting installation'); - exit; - } - } - $this->checkPhpDependencies(); - } + $this->line(' '); + $this->info('Checking for required php extensions...'); - protected function checkPhpDependencies() - { $extensions = [ 'bcmath', 'ctype', @@ -111,37 +128,34 @@ class Installer extends Command 'mbstring', 'openssl', ]; - if($this->installType === 'Advanced') { - $ffmpeg = exec('which ffmpeg'); - if(empty($ffmpeg)) { - $this->error('FFmpeg not found, please install it.'); - $this->error('Cancelling installation.'); - exit; - } else { - $this->info('- Found FFmpeg!'); - } - $this->line(''); - $this->info('Checking for required php extensions...'); - } foreach($extensions as $ext) { if(extension_loaded($ext) == false) { $this->error("\"{$ext}\" PHP extension not found, aborting installation"); exit; } } - if($this->installType === 'Advanced') { - $this->info("- Required PHP extensions found!"); - } - - $this->checkPermissions(); + $this->info("- Required PHP extensions found!"); } - protected function checkPermissions() + protected function checkFFmpegDependencies() { - if($this->installType === 'Advanced') { - $this->line(''); - $this->info('Checking for proper filesystem permissions...'); - } + $this->line(' '); + $this->info('Checking for required FFmpeg dependencies...'); + + $ffmpeg = exec('which ffmpeg'); + if(empty($ffmpeg)) { + $this->error("\"{$ext}\" FFmpeg not found, aborting installation"); + exit; + } else { + $this->info('- Found FFmpeg!'); + } + } + + protected function checkDiskPermissions() + { + $this->line(''); + $this->info('Checking for proper filesystem permissions...'); + $this->callSilently('storage:link'); $paths = [ base_path('bootstrap'), @@ -155,154 +169,227 @@ class Installer extends Command $this->error(" $path"); exit; } else { - if($this->installType === 'Advanced') { - $this->info("- Found valid permissions for {$path}"); - } + $this->info("- Found valid permissions for {$path}"); } } - - $this->createEnv(); } - protected function createEnv() + protected function envProd() { $this->line(''); - if(!file_exists(app()->environmentFilePath())) { - exec('cp .env.example .env'); - $this->updateEnvFile('APP_ENV', 'setup'); - $this->call('key:generate'); - } - - $name = $this->ask('Site name [ex: Pixelfed]'); - $this->updateEnvFile('APP_NAME', $name ?? 'pixelfed'); - - $domain = $this->ask('Site Domain [ex: pixelfed.com]'); - if(empty($domain)) { - $this->error('You must set the site domain'); - exit; - } - if(starts_with($domain, 'http')) { - $this->error('The site domain cannot start with https://, you must use the FQDN (eg: example.org)'); - exit; - } - if(strpos($domain, '.') == false) { - $this->error('You must enter a valid site domain'); - exit; - } - $this->updateEnvFile('APP_DOMAIN', $domain ?? 'example.org'); - $this->updateEnvFile('ADMIN_DOMAIN', $domain ?? 'example.org'); - $this->updateEnvFile('SESSION_DOMAIN', $domain ?? 'example.org'); - $this->updateEnvFile('APP_URL', 'https://' . $domain); - + $this->info('Enabling production'); + + $this->updateEnvFile('APP_ENV', 'production'); + $this->updateEnvFile('APP_DEBUG', 'false'); + $this->call('key:generate', ['--force' => true]); + } + + protected function instanceDB() + { + $this->line(''); + $this->info('Database Settings:'); $database = $this->choice('Select database driver', ['mysql', 'pgsql'], 0); - $this->updateEnvFile('DB_CONNECTION', $database ?? 'mysql'); - $database_host = $this->ask('Select database host', '127.0.0.1'); - $this->updateEnvFile('DB_HOST', $database_host ?? 'mysql'); - $database_port_default = $database === 'mysql' ? 3306 : 5432; $database_port = $this->ask('Select database port', $database_port_default); - $this->updateEnvFile('DB_PORT', $database_port ?? $database_port_default); $database_db = $this->ask('Select database', 'pixelfed'); - $this->updateEnvFile('DB_DATABASE', $database_db ?? 'pixelfed'); - $database_username = $this->ask('Select database username', 'pixelfed'); - $this->updateEnvFile('DB_USERNAME', $database_username ?? 'pixelfed'); + $database_password = $this->secret('Select database password'); - $db_pass = str_random(64); - $database_password = $this->secret('Select database password', $db_pass); + $this->updateEnvFile('DB_CONNECTION', $database); + $this->updateEnvFile('DB_HOST', $database_host); + $this->updateEnvFile('DB_PORT', $database_port); + $this->updateEnvFile('DB_DATABASE', $database_db); + $this->updateEnvFile('DB_USERNAME', $database_username); $this->updateEnvFile('DB_PASSWORD', $database_password); + $this->info('Testing Database...'); $dsn = "{$database}:dbname={$database_db};host={$database_host};port={$database_port};"; try { - $dbh = new PDO($dsn, $database_username, $database_password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); + $dbh = new PDO($dsn, $database_username, $database_password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); } catch (\PDOException $e) { - $this->error('Cannot connect to database, check your credentials and try again'); - exit; + $this->error('Cannot connect to database, check your details and try again'); + exit; } + $this->info('- Connected to DB Successfully'); + } - if($this->installType === 'Advanced') { - $cache = $this->choice('Select cache driver', ["redis", "apc", "array", "database", "file", "memcached"], 0); - $this->updateEnvFile('CACHE_DRIVER', $cache ?? 'redis'); + protected function instanceRedis() + { + $this->line(''); + $this->info('Redis Settings:'); + $redis_client = $this->choice('Set redis client (PHP extension)', ['phpredis', 'predis'], 0); + $redis_host = $this->ask('Set redis host', 'localhost'); + $redis_password = $this->ask('Set redis password', 'null'); + $redis_port = $this->ask('Set redis port', 6379); - $session = $this->choice('Select session driver', ["redis", "file", "cookie", "database", "apc", "memcached", "array"], 0); - $this->updateEnvFile('SESSION_DRIVER', $session ?? 'redis'); + $this->updateEnvFile('REDIS_SCHEME', 'tcp'); + $this->updateEnvFile('REDIS_HOST', $redis_host); + $this->updateEnvFile('REDIS_PASSWORD', $redis_password); + $this->updateEnvFile('REDIS_PORT', $redis_port); - $redis_host = $this->ask('Set redis host', 'localhost'); - $this->updateEnvFile('REDIS_HOST', $redis_host); + $this->info('Testing Redis...'); + $redis = Redis::connection(); + if($redis->ping()) { + $this->info('- Connected to Redis Successfully!'); + } else { + $this->error('Cannot connect to Redis, check your details and try again'); + exit; + } + } - $redis_password = $this->ask('Set redis password', 'null'); - $this->updateEnvFile('REDIS_PASSWORD', $redis_password); + protected function instanceURL() + { + $this->line(''); + $this->info('Instance URL Settings:'); + $name = $this->ask('Site name [ex: Pixelfed]', 'Pixelfed'); - $redis_port = $this->ask('Set redis port', 6379); - $this->updateEnvFile('REDIS_PORT', $redis_port); - } + $domain = $this->ask('Site Domain [ex: pixelfed.com]'); + $domain = strtolower($domain); + if(empty($domain)) { + $this->error('You must set the site domain'); + exit; + } + if(starts_with($domain, 'http')) { + $this->error('The site domain cannot start with https://, you must use the FQDN (eg: example.org)'); + exit; + } + if(strpos($domain, '.') == false) { + $this->error('You must enter a valid site domain'); + exit; + } + $this->updateEnvFile('APP_NAME', $name); + $this->updateEnvFile('APP_URL', 'https://' . $domain); + $this->updateEnvFile('APP_DOMAIN', $domain); + $this->updateEnvFile('ADMIN_DOMAIN', $domain); + $this->updateEnvFile('SESSION_DOMAIN', $domain); + } + + protected function laravelSettings() + { + $this->line(''); + $this->info('Laravel Settings (Defaults are recommended):'); + $session = $this->choice('Select session driver', ["database", "file", "cookie", "redis", "memcached", "array"], 0); + $cache = $this->choice('Select cache driver', ["redis", "apc", "array", "database", "file", "memcached"], 0); + $queue = $this->choice('Select queue driver', ["redis", "database", "sync", "beanstalkd", "sqs", "null"], 0); + $broadcast = $this->choice('Select broadcast driver', ["log", "redis", "pusher", "null"], 0); + $log = $this->choice('Select Log Channel', ["stack", "single", "daily", "stderr", "syslog", "null"], 0); + $horizon = $this->ask('Set Horizon Prefix [ex: horizon-]', 'horizon-'); + + $this->updateEnvFile('SESSION_DRIVER', $session); + $this->updateEnvFile('CACHE_DRIVER', $cache); + $this->updateEnvFile('QUEUE_DRIVER', $cache); + $this->updateEnvFile('BROADCAST_DRIVER', $cache); + $this->updateEnvFile('LOG_CHANNEL', $log); + $this->updateEnvFile('HORIZON_PREFIX', $horizon); + } + + protected function instanceSettings() + { + $this->line(''); + $this->info('Instance Settings:'); + $max_registration = $this->ask('Set Maximum users on this instance.', '1000'); $open_registration = $this->choice('Allow new registrations?', ['false', 'true'], 0); - $this->updateEnvFile('OPEN_REGISTRATION', $open_registration); - - $activitypub_federation = $this->choice('Enable ActivityPub federation?', ['false', 'true'], 1); - $this->updateEnvFile('ACTIVITY_PUB', $activitypub_federation); - $this->updateEnvFile('AP_INBOX', $activitypub_federation); - $this->updateEnvFile('AP_SHAREDINBOX', $activitypub_federation); - $this->updateEnvFile('AP_REMOTE_FOLLOW', $activitypub_federation); - - $enforce_email_verification = $this->choice('Enforce email verification?', ['false', 'true'], 1); - $this->updateEnvFile('ENFORCE_EMAIL_VERIFICATION', $enforce_email_verification); - + $enforce_email_verification = $this->choice('Enforce email verification?', ['false', 'true'], 0); $enable_mobile_apis = $this->choice('Enable mobile app/apis support?', ['false', 'true'], 1); + + $this->updateEnvFile('PF_MAX_USERS', $max_registration); + $this->updateEnvFile('OPEN_REGISTRATION', $open_registration); + $this->updateEnvFile('ENFORCE_EMAIL_VERIFICATION', $enforce_email_verification); $this->updateEnvFile('OAUTH_ENABLED', $enable_mobile_apis); $this->updateEnvFile('EXP_EMC', $enable_mobile_apis); + } - $optimize_media = $this->choice('Optimize media uploads? Requires jpegoptim and other dependencies!', ['false', 'true'], 0); - $this->updateEnvFile('PF_OPTIMIZE_IMAGES', $optimize_media); + protected function activityPubSettings() + { + $this->line(''); + $this->info('Federation Settings:'); + $activitypub_federation = $this->choice('Enable ActivityPub federation?', ['false', 'true'], 1); + + $this->updateEnvFile('ACTIVITY_PUB', $activitypub_federation); + $this->updateEnvFile('AP_REMOTE_FOLLOW', $activitypub_federation); + $this->updateEnvFile('AP_INBOX', $activitypub_federation); + $this->updateEnvFile('AP_OUTBOX', $activitypub_federation); + $this->updateEnvFile('AP_SHAREDINBOX', $activitypub_federation); + } - if($this->installType === 'Advanced') { - - if($optimize_media === 'true') { - $image_quality = $this->ask('Set image optimization quality between 1-100. Default is 80%, lower values use less disk space at the expense of image quality.', '80'); - if($image_quality < 1) { - $this->error('Min image quality is 1. You should avoid such a low value, 60 at minimum is recommended.'); - exit; - } - if($image_quality > 100) { - $this->error('Max image quality is 100'); - exit; - } - $this->updateEnvFile('IMAGE_QUALITY', $image_quality); - } - - $max_photo_size = $this->ask('Max photo upload size in kilobytes. Default 15000 which is equal to 15MB', '15000'); + protected function mediaSettings() + { + $this->line(''); + $this->info('Media Settings:'); + $optimize_media = $this->choice('Optimize media uploads? Requires jpegoptim and other dependencies!', ['false', 'true'], 1); + $image_quality = $this->ask('Set image optimization quality between 1-100. Default is 80%, lower values use less disk space at the expense of image quality.', '80'); + if($image_quality < 1) { + $this->error('Min image quality is 1. You should avoid such a low value, 60 at minimum is recommended.'); + exit; + } + if($image_quality > 100) { + $this->error('Max image quality is 100'); + exit; + } + $this->info(' Note: Max photo size cannot exceed php.ini `post_max_size` of ' . ini_get('post_max_size')); + $max_photo_size = $this->ask('Max photo upload size in kilobytes. Default 15000 which is equal to 15MB', '15000'); if($max_photo_size * 1024 > $this->parseSize(ini_get('post_max_size'))) { $this->error('Max photo size (' . (round($max_photo_size / 1000)) . 'M) cannot exceed php.ini `post_max_size` of ' . ini_get('post_max_size')); exit; } - $this->updateEnvFile('MAX_PHOTO_SIZE', $max_photo_size); + + $max_caption_length = $this->ask('Max caption limit. Default to 500, max 5000.', '500'); + if($max_caption_length > 5000) { + $this->error('Max caption length is 5000 characters.'); + exit; + } - $max_caption_length = $this->ask('Max caption limit. Default to 500, max 5000.', '500'); - if($max_caption_length > 5000) { - $this->error('Max caption length is 5000 characters.'); - exit; - } - $this->updateEnvFile('MAX_CAPTION_LENGTH', $max_caption_length); - - $max_album_length = $this->ask('Max photos allowed per album. Choose a value between 1 and 10.', '4'); - if($max_album_length < 1) { - $this->error('Min album length is 1 photos per album.'); - exit; - } - if($max_album_length > 10) { - $this->error('Max album length is 10 photos per album.'); - exit; - } - $this->updateEnvFile('MAX_ALBUM_LENGTH', $max_album_length); - } - - $this->updateEnvFile('APP_ENV', 'production'); - $this->postInstall(); + $max_album_length = $this->ask('Max photos allowed per album. Choose a value between 1 and 10.', '4'); + if($max_album_length < 1) { + $this->error('Min album length is 1 photos per album.'); + exit; + } + if($max_album_length > 10) { + $this->error('Max album length is 10 photos per album.'); + exit; + } + + $this->updateEnvFile('PF_OPTIMIZE_IMAGES', $optimize_media); + $this->updateEnvFile('IMAGE_QUALITY', $image_quality); + $this->updateEnvFile('MAX_PHOTO_SIZE', $max_photo_size); + $this->updateEnvFile('MAX_CAPTION_LENGTH', $max_caption_length); + $this->updateEnvFile('MAX_ALBUM_LENGTH', $max_album_length); } + protected function dbMigrations() + { + $this->line(''); + $this->info('Note: We recommend running database migrations now!'); + $confirm = $this->choice('Do you want to run the database migrations?', ['Yes', 'No'], 0); + + if($confirm === 'Yes') { + sleep(3); + $this->call('migrate', ['--force' => true]); + $this->callSilently('import:cities'); + $this->callSilently('instance:actor'); + $this->callSilently('passport:keys, ['--force' => true]); + + $confirm = $this->choice('Do you want to create an admin account?', ['Yes', 'No'], 0); + if($confirm === 'Yes') { + $this->call('user:create'); + } + } + } + + protected function resetArtisanCache() + { + $this->call('config:cache'); + $this->call('route:cache'); + $this->call('view:cache'); + } + +##### +# Installer Functions +##### + protected function updateEnvFile($key, $value) { $envPath = app()->environmentFilePath(); @@ -333,37 +420,14 @@ class Installer extends Command fclose($file); } - protected function postInstall() - { - $this->line(''); - $this->info('We recommend running database migrations now, or you can do it manually later.'); - $confirm = $this->choice('Do you want to run the database migrations?', ['No', 'Yes'], 0); - if($confirm === 'Yes') { - $this->callSilently('config:clear'); - sleep(3); - $this->call('migrate', ['--force' => true]); - $this->callSilently('instance:actor'); - $this->callSilently('passport:install'); - - $confirm = $this->choice('Do you want to create an admin account?', ['No', 'Yes'], 0); - if($confirm === 'Yes') { - $this->call('user:create'); - } - } else { - $this->callSilently('config:cache'); - } - - $this->info('Pixelfed has been successfully installed!'); - } - protected function parseSize($size) { - $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); - $size = preg_replace('/[^0-9\.]/', '', $size); - if ($unit) { - return round($size * pow(1024, stripos('bkmgtpezy', $unit[0]))); - } - else { - return round($size); - } + $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); + $size = preg_replace('/[^0-9\.]/', '', $size); + if ($unit) { + return round($size * pow(1024, stripos('bkmgtpezy', $unit[0]))); + } + else { + return round($size); + } } } From 8b0f3f3fc4df51a06c6d6df58b53da580b17f6f7 Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 18:49:58 +0930 Subject: [PATCH 02/30] Create .env.installer --- .env.installer | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .env.installer diff --git a/.env.installer b/.env.installer new file mode 100644 index 00000000..c0b8b096 --- /dev/null +++ b/.env.installer @@ -0,0 +1,67 @@ +APP_NAME="Pixelfed" +APP_ENV="prod" +APP_KEY= +APP_DEBUG="false" + +#Instance Configuration +OPEN_REGISTRATION="false" +ENFORCE_EMAIL_VERIFICATION="false" +PF_MAX_USERS="1000" +OAUTH_ENABLED="true" + +#Media Configuration +PF_OPTIMIZE_IMAGES="true" +IMAGE_QUALITY="80" +MAX_PHOTO_SIZE="15000" +MAX_CAPTION_LENGTH="500" +MAX_ALBUM_LENGTH="4" + +# Instance URL Configuration +APP_URL="http://localhost" +APP_DOMAIN="localhost" +ADMIN_DOMAIN="localhost" +SESSION_DOMAIN="localhost" +TRUST_PROXIES="*" + +# Database Configuration +DB_CONNECTION="mysql" +DB_HOST="127.0.0.1" +DB_PORT="3306" +DB_DATABASE="pixelfed" +DB_USERNAME="pixelfed" +DB_PASSWORD="pixelfed" + +# Redis Configuration +REDIS_SCHEME="tcp" +REDIS_HOST="127.0.0.1" +REDIS_PASSWORD="null" +REDIS_PORT="6379" + +# Laravel Configuration +SESSION_DRIVER="database" +CACHE_DRIVER="redis" +QUEUE_DRIVER="redis" +BROADCAST_DRIVER="log" +LOG_CHANNEL="stack" +HORIZON_PREFIX="horizon-" + +# ActivityPub Configuration +ACTIVITY_PUB="false" +AP_REMOTE_FOLLOW="false" +AP_INBOX="false" +AP_OUTBOX="false" +AP_SHAREDINBOX="false" + +# Experimental Configuration +EXP_EMC="true" + +## Mail Configuration (Post-Installer) + +MAIL_DRIVER=log +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS="pixelfed@example.com" +MAIL_FROM_NAME="Pixelfed" From 829e6d14e047f323ab38b9ffbedbc338613dec3c Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 18:50:31 +0930 Subject: [PATCH 03/30] Update .env.installer --- .env.installer | 1 - 1 file changed, 1 deletion(-) diff --git a/.env.installer b/.env.installer index c0b8b096..28d37798 100644 --- a/.env.installer +++ b/.env.installer @@ -56,7 +56,6 @@ AP_SHAREDINBOX="false" EXP_EMC="true" ## Mail Configuration (Post-Installer) - MAIL_DRIVER=log MAIL_HOST=smtp.mailtrap.io MAIL_PORT=2525 From 8d583403cbbda1687e8e873eb9e4c4424240913c Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 18:53:50 +0930 Subject: [PATCH 04/30] Update Installer.php --- app/Console/Commands/Installer.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index f6dcb7c2..a973d1f4 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -66,8 +66,8 @@ class Installer extends Command $this->envCreate(); $this->installType(); - if($this->installType === 'Production') { - $this->info('Installer: Production...'); + if($this->installType === 'Advanced') { + $this->info('Installer: Advanced...'); $this->checkPHPDependencies(); $this->checkFFmpegDependencies(); $this->checkDiskPermissions(); @@ -83,7 +83,15 @@ class Installer extends Command $this->resetArtisanCache(); } else { $this->info('Installer: Simple...'); - exit; + $this->checkDiskPermissions(); + $this->envProd(); + $this->instanceDB(); + $this->instanceRedis(); + $this->instanceURL(); + $this->activityPubSettings(); + $this->instanceSettings(); + $this->dbMigrations(); + $this->resetArtisanCache(); } } @@ -111,7 +119,7 @@ class Installer extends Command protected function installType() { - $type = $this->choice('Select installation type', ['Simple', 'Production'], 1); + $type = $this->choice('Select installation type', ['Simple', 'Advanced'], 1); $this->installType = $type; } From 4ffa4a3609573ba1137e34ca3d466c18b3385ce7 Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 18:59:37 +0930 Subject: [PATCH 05/30] Update Installer.php --- app/Console/Commands/Installer.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index a973d1f4..20d5b9ae 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -337,12 +337,8 @@ class Installer extends Command $this->error('Max image quality is 100'); exit; } - $this->info(' Note: Max photo size cannot exceed php.ini `post_max_size` of ' . ini_get('post_max_size')); + $this->info('Note: Max photo size cannot exceed `post_max_size` in php.ini.'); $max_photo_size = $this->ask('Max photo upload size in kilobytes. Default 15000 which is equal to 15MB', '15000'); - if($max_photo_size * 1024 > $this->parseSize(ini_get('post_max_size'))) { - $this->error('Max photo size (' . (round($max_photo_size / 1000)) . 'M) cannot exceed php.ini `post_max_size` of ' . ini_get('post_max_size')); - exit; - } $max_caption_length = $this->ask('Max caption limit. Default to 500, max 5000.', '500'); if($max_caption_length > 5000) { From 6be0109dff9ae3966218ffeef9752f1a7829ee4d Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 19:08:52 +0930 Subject: [PATCH 06/30] Update .env.example --- .env.example | 79 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/.env.example b/.env.example index c9b47220..28d37798 100644 --- a/.env.example +++ b/.env.example @@ -1,35 +1,61 @@ -APP_NAME="Pixelfed Prod" -APP_ENV=production +APP_NAME="Pixelfed" +APP_ENV="prod" APP_KEY= -APP_DEBUG=false +APP_DEBUG="false" -APP_URL=http://localhost +#Instance Configuration +OPEN_REGISTRATION="false" +ENFORCE_EMAIL_VERIFICATION="false" +PF_MAX_USERS="1000" +OAUTH_ENABLED="true" + +#Media Configuration +PF_OPTIMIZE_IMAGES="true" +IMAGE_QUALITY="80" +MAX_PHOTO_SIZE="15000" +MAX_CAPTION_LENGTH="500" +MAX_ALBUM_LENGTH="4" + +# Instance URL Configuration +APP_URL="http://localhost" APP_DOMAIN="localhost" ADMIN_DOMAIN="localhost" SESSION_DOMAIN="localhost" TRUST_PROXIES="*" -LOG_CHANNEL=stack +# Database Configuration +DB_CONNECTION="mysql" +DB_HOST="127.0.0.1" +DB_PORT="3306" +DB_DATABASE="pixelfed" +DB_USERNAME="pixelfed" +DB_PASSWORD="pixelfed" -DB_CONNECTION=mysql -DB_HOST=127.0.0.1 -DB_PORT=3306 -DB_DATABASE=pixelfed -DB_USERNAME=pixelfed -DB_PASSWORD=pixelfed - -BROADCAST_DRIVER=log -CACHE_DRIVER=redis -SESSION_DRIVER=database -QUEUE_DRIVER=redis +# Redis Configuration +REDIS_SCHEME="tcp" +REDIS_HOST="127.0.0.1" +REDIS_PASSWORD="null" +REDIS_PORT="6379" +# Laravel Configuration +SESSION_DRIVER="database" +CACHE_DRIVER="redis" +QUEUE_DRIVER="redis" +BROADCAST_DRIVER="log" +LOG_CHANNEL="stack" HORIZON_PREFIX="horizon-" -REDIS_SCHEME=tcp -REDIS_HOST=127.0.0.1 -REDIS_PASSWORD=null -REDIS_PORT=6379 +# ActivityPub Configuration +ACTIVITY_PUB="false" +AP_REMOTE_FOLLOW="false" +AP_INBOX="false" +AP_OUTBOX="false" +AP_SHAREDINBOX="false" +# Experimental Configuration +EXP_EMC="true" + +## Mail Configuration (Post-Installer) MAIL_DRIVER=log MAIL_HOST=smtp.mailtrap.io MAIL_PORT=2525 @@ -38,16 +64,3 @@ MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="pixelfed@example.com" MAIL_FROM_NAME="Pixelfed" - -OPEN_REGISTRATION=true -ENFORCE_EMAIL_VERIFICATION=true -PF_MAX_USERS=1000 - -MAX_PHOTO_SIZE=15000 -MAX_CAPTION_LENGTH=150 -MAX_ALBUM_LENGTH=4 - -ACTIVITY_PUB=false -AP_REMOTE_FOLLOW=false -AP_INBOX=false -PF_COSTAR_ENABLED=false From 26da1c550d85b0bb68769a95777376312574d6ed Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 19:08:56 +0930 Subject: [PATCH 07/30] Delete .env.installer --- .env.installer | 66 -------------------------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 .env.installer diff --git a/.env.installer b/.env.installer deleted file mode 100644 index 28d37798..00000000 --- a/.env.installer +++ /dev/null @@ -1,66 +0,0 @@ -APP_NAME="Pixelfed" -APP_ENV="prod" -APP_KEY= -APP_DEBUG="false" - -#Instance Configuration -OPEN_REGISTRATION="false" -ENFORCE_EMAIL_VERIFICATION="false" -PF_MAX_USERS="1000" -OAUTH_ENABLED="true" - -#Media Configuration -PF_OPTIMIZE_IMAGES="true" -IMAGE_QUALITY="80" -MAX_PHOTO_SIZE="15000" -MAX_CAPTION_LENGTH="500" -MAX_ALBUM_LENGTH="4" - -# Instance URL Configuration -APP_URL="http://localhost" -APP_DOMAIN="localhost" -ADMIN_DOMAIN="localhost" -SESSION_DOMAIN="localhost" -TRUST_PROXIES="*" - -# Database Configuration -DB_CONNECTION="mysql" -DB_HOST="127.0.0.1" -DB_PORT="3306" -DB_DATABASE="pixelfed" -DB_USERNAME="pixelfed" -DB_PASSWORD="pixelfed" - -# Redis Configuration -REDIS_SCHEME="tcp" -REDIS_HOST="127.0.0.1" -REDIS_PASSWORD="null" -REDIS_PORT="6379" - -# Laravel Configuration -SESSION_DRIVER="database" -CACHE_DRIVER="redis" -QUEUE_DRIVER="redis" -BROADCAST_DRIVER="log" -LOG_CHANNEL="stack" -HORIZON_PREFIX="horizon-" - -# ActivityPub Configuration -ACTIVITY_PUB="false" -AP_REMOTE_FOLLOW="false" -AP_INBOX="false" -AP_OUTBOX="false" -AP_SHAREDINBOX="false" - -# Experimental Configuration -EXP_EMC="true" - -## Mail Configuration (Post-Installer) -MAIL_DRIVER=log -MAIL_HOST=smtp.mailtrap.io -MAIL_PORT=2525 -MAIL_USERNAME=null -MAIL_PASSWORD=null -MAIL_ENCRYPTION=null -MAIL_FROM_ADDRESS="pixelfed@example.com" -MAIL_FROM_NAME="Pixelfed" From 825365a6b6c296d397b51a013653380610f27c34 Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 19:09:19 +0930 Subject: [PATCH 08/30] Update Installer.php --- app/Console/Commands/Installer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 20d5b9ae..5897c5b2 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -113,7 +113,7 @@ class Installer extends Command { $this->line(''); if(!file_exists(app()->environmentFilePath())) { - exec('cp .env.installer .env'); + exec('cp .env.example .env'); } } From a0efe2b408e7e660ce4b7e41e20e05b7372692e3 Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 19:09:50 +0930 Subject: [PATCH 09/30] Update .env.example --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 28d37798..ee5e4918 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ APP_NAME="Pixelfed" -APP_ENV="prod" +APP_ENV="production" APP_KEY= APP_DEBUG="false" From df51e838bd0963c386620f73fd72af09588c4f9f Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 19:15:12 +0930 Subject: [PATCH 10/30] Update Installer.php --- app/Console/Commands/Installer.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 5897c5b2..da8a063b 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -371,9 +371,17 @@ class Installer extends Command if($confirm === 'Yes') { sleep(3); + $this->line(''); + $this->info('Migrating DB:'); $this->call('migrate', ['--force' => true]); + $this->line(''); + $this->info('Importing Cities:'); $this->callSilently('import:cities'); + $this->line(''); + $this->info('Creating Federation Instance Actor:'); $this->callSilently('instance:actor'); + $this->line(''); + $this->info('Creating Password Keys for API:'); $this->callSilently('passport:keys, ['--force' => true]); $confirm = $this->choice('Do you want to create an admin account?', ['Yes', 'No'], 0); From 6d76d027322d0a069f7eba79a35ac457c58b0470 Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 19:15:33 +0930 Subject: [PATCH 11/30] Update Installer.php --- app/Console/Commands/Installer.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index da8a063b..0a30725a 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -376,13 +376,13 @@ class Installer extends Command $this->call('migrate', ['--force' => true]); $this->line(''); $this->info('Importing Cities:'); - $this->callSilently('import:cities'); + $this->call('import:cities'); $this->line(''); $this->info('Creating Federation Instance Actor:'); - $this->callSilently('instance:actor'); + $this->call('instance:actor'); $this->line(''); $this->info('Creating Password Keys for API:'); - $this->callSilently('passport:keys, ['--force' => true]); + $this->call('passport:keys, ['--force' => true]); $confirm = $this->choice('Do you want to create an admin account?', ['Yes', 'No'], 0); if($confirm === 'Yes') { From fc811416f3158f4ec573ac30606171485a00a78e Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 19:16:11 +0930 Subject: [PATCH 12/30] Update Installer.php --- app/Console/Commands/Installer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 0a30725a..8dd7df4b 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -382,7 +382,7 @@ class Installer extends Command $this->call('instance:actor'); $this->line(''); $this->info('Creating Password Keys for API:'); - $this->call('passport:keys, ['--force' => true]); + $this->call('passport:keys', ['--force' => true]); $confirm = $this->choice('Do you want to create an admin account?', ['Yes', 'No'], 0); if($confirm === 'Yes') { From a2090f544527525a1343b4804e5354e976ae4cfb Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 19:32:51 +0930 Subject: [PATCH 13/30] Update Installer.php --- app/Console/Commands/Installer.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 8dd7df4b..f6b8b737 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -112,6 +112,7 @@ class Installer extends Command protected function envCreate() { $this->line(''); + $this->info('Creating .env if required'); if(!file_exists(app()->environmentFilePath())) { exec('cp .env.example .env'); } From a0bca2668ae02ebb79e52eac2d88170434142c80 Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 19:38:40 +0930 Subject: [PATCH 14/30] Update Installer.php --- app/Console/Commands/Installer.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index f6b8b737..61632d3c 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -111,6 +111,12 @@ class Installer extends Command protected function envCreate() { + if( $this->option('dangerously-overwrite-env') ) { + $this->line(''); + $this->error('Existing .env File Found - Renaming to .env.danger'); + exec('cp .env .env.danger'); + } + $this->line(''); $this->info('Creating .env if required'); if(!file_exists(app()->environmentFilePath())) { From 51eeb261857258c57bf54b3a38e4a80ea3fc4577 Mon Sep 17 00:00:00 2001 From: Shlee Date: Wed, 15 Jun 2022 19:40:35 +0930 Subject: [PATCH 15/30] Update .env.example --- .env.example | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index ee5e4918..ccab0d83 100644 --- a/.env.example +++ b/.env.example @@ -3,13 +3,13 @@ APP_ENV="production" APP_KEY= APP_DEBUG="false" -#Instance Configuration +# Instance Configuration OPEN_REGISTRATION="false" ENFORCE_EMAIL_VERIFICATION="false" PF_MAX_USERS="1000" OAUTH_ENABLED="true" -#Media Configuration +# Media Configuration PF_OPTIMIZE_IMAGES="true" IMAGE_QUALITY="80" MAX_PHOTO_SIZE="15000" @@ -64,3 +64,15 @@ MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="pixelfed@example.com" MAIL_FROM_NAME="Pixelfed" + +## S3 Configuration (Post-Installer) +PF_ENABLE_CLOUD=false +FILESYSTEM_DRIVER=local +FILESYSTEM_CLOUD=s3 +#AWS_ACCESS_KEY_ID= +#AWS_SECRET_ACCESS_KEY= +#AWS_DEFAULT_REGION= +#AWS_BUCKET= +#AWS_URL= +#AWS_ENDPOINT= +#AWS_USE_PATH_STYLE_ENDPOINT=false From 56ebd8c06ca7867e40dc18ebe42f2cba376a405c Mon Sep 17 00:00:00 2001 From: Shlee Date: Thu, 16 Jun 2022 10:06:47 +0930 Subject: [PATCH 16/30] Update Installer.php --- app/Console/Commands/Installer.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 61632d3c..f6b8b737 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -111,12 +111,6 @@ class Installer extends Command protected function envCreate() { - if( $this->option('dangerously-overwrite-env') ) { - $this->line(''); - $this->error('Existing .env File Found - Renaming to .env.danger'); - exec('cp .env .env.danger'); - } - $this->line(''); $this->info('Creating .env if required'); if(!file_exists(app()->environmentFilePath())) { From 83bb370ec9b9a40ce88ff62208d658af5a2d1596 Mon Sep 17 00:00:00 2001 From: Shlee Date: Thu, 16 Jun 2022 11:02:47 +0930 Subject: [PATCH 17/30] Update Installer.php --- app/Console/Commands/Installer.php | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index f6b8b737..94a75a55 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -81,6 +81,7 @@ class Installer extends Command $this->mediaSettings(); $this->dbMigrations(); $this->resetArtisanCache(); + $this->validateEnv(); } else { $this->info('Installer: Simple...'); $this->checkDiskPermissions(); @@ -92,6 +93,7 @@ class Installer extends Command $this->instanceSettings(); $this->dbMigrations(); $this->resetArtisanCache(); + $this->validateEnv(); } } @@ -394,15 +396,33 @@ class Installer extends Command protected function resetArtisanCache() { - $this->call('config:cache'); - $this->call('route:cache'); - $this->call('view:cache'); + $this->call('config:cache'); + $this->call('route:cache'); + $this->call('view:cache'); + } + + protected function validateEnv() + { + $this->checkEnvKeys('APP_KEY', "key:generate failed?"); + $this->checkEnvKeys('APP_ENV', "APP_ENV value should be production"); + $this->checkEnvKeys('APP_DEBUG', "APP_DEBUG value should be false"); } ##### # Installer Functions ##### + protected function checkEnvKeys($key, $error) + { + $envPath = app()->environmentFilePath(); + $payload = file_get_contents($envPath); + + if ($existing = $this->existingEnv($key, $payload)) { + } else { + $this->info("$key empty - $error"); + } + } + protected function updateEnvFile($key, $value) { $envPath = app()->environmentFilePath(); From 4da076c756a6a9993ffca218fce2d736099d2dcb Mon Sep 17 00:00:00 2001 From: Shlee Date: Thu, 16 Jun 2022 11:05:05 +0930 Subject: [PATCH 18/30] Update Installer.php --- app/Console/Commands/Installer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 94a75a55..ea939b89 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -80,8 +80,8 @@ class Installer extends Command $this->instanceSettings(); $this->mediaSettings(); $this->dbMigrations(); - $this->resetArtisanCache(); $this->validateEnv(); + $this->resetArtisanCache(); } else { $this->info('Installer: Simple...'); $this->checkDiskPermissions(); @@ -92,8 +92,8 @@ class Installer extends Command $this->activityPubSettings(); $this->instanceSettings(); $this->dbMigrations(); - $this->resetArtisanCache(); $this->validateEnv(); + $this->resetArtisanCache(); } } From e77400b62185912fd70a9e2ed6b27108d36c3d9c Mon Sep 17 00:00:00 2001 From: Shlee Date: Sun, 19 Jun 2022 14:58:33 +0930 Subject: [PATCH 19/30] Update Installer.php --- app/Console/Commands/Installer.php | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index ea939b89..738cd528 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -70,6 +70,7 @@ class Installer extends Command $this->info('Installer: Advanced...'); $this->checkPHPDependencies(); $this->checkFFmpegDependencies(); + $this->checkOptimiseDependencies(); $this->checkDiskPermissions(); $this->envProd(); $this->instanceDB(); @@ -141,7 +142,7 @@ class Installer extends Command ]; foreach($extensions as $ext) { if(extension_loaded($ext) == false) { - $this->error("\"{$ext}\" PHP extension not found, aborting installation"); + $this->error("- \"{$ext}\" PHP extension not found, aborting installation"); exit; } } @@ -155,13 +156,35 @@ class Installer extends Command $ffmpeg = exec('which ffmpeg'); if(empty($ffmpeg)) { - $this->error("\"{$ext}\" FFmpeg not found, aborting installation"); + $this->error("- \"{$ext}\" FFmpeg not found, aborting installation"); exit; } else { $this->info('- Found FFmpeg!'); } } + protected function checkOptimiseDependencies() + { + $this->line(' '); + $this->info('Checking for optional FFmpeg dependencies...'); + + $dependencies = [ + 'jpegoptim', + 'optipng', + 'pngquant', + 'gifsicle', + ]; + + foreach($dependencies as $dep) { + $which = exec("which $dep"); + if(empty($which)) { + $this->error("- \"{$dep}\" not found"); + } else { + $this->info ("- \"{$dep}\" found"); + } + } + } + protected function checkDiskPermissions() { $this->line(''); From 2e0587cef8ef257db51c8896cb94a33305a49a2d Mon Sep 17 00:00:00 2001 From: Shlee Date: Sun, 19 Jun 2022 15:00:08 +0930 Subject: [PATCH 20/30] Update Installer.php --- app/Console/Commands/Installer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 738cd528..e341d31a 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -166,7 +166,7 @@ class Installer extends Command protected function checkOptimiseDependencies() { $this->line(' '); - $this->info('Checking for optional FFmpeg dependencies...'); + $this->info('Checking for optional Media Optimisation dependencies...'); $dependencies = [ 'jpegoptim', From 211b497240aecdb2507705af77d9cb69aba58469 Mon Sep 17 00:00:00 2001 From: Shlee Date: Sun, 19 Jun 2022 15:15:13 +0930 Subject: [PATCH 21/30] Update Installer.php --- app/Console/Commands/Installer.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index e341d31a..f842379f 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -139,7 +139,13 @@ class Installer extends Command 'json', 'mbstring', 'openssl', + 'gd', + 'intl', + 'xml', + 'zip', + 'redis', ]; + foreach($extensions as $ext) { if(extension_loaded($ext) == false) { $this->error("- \"{$ext}\" PHP extension not found, aborting installation"); From dcd7a35384357d9782561d77c8a6e76c9a8d1bd5 Mon Sep 17 00:00:00 2001 From: Shlee Date: Sun, 19 Jun 2022 15:31:55 +0930 Subject: [PATCH 22/30] Update Installer.php --- app/Console/Commands/Installer.php | 32 +++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index f842379f..3e40cbd1 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -68,7 +68,8 @@ class Installer extends Command if($this->installType === 'Advanced') { $this->info('Installer: Advanced...'); - $this->checkPHPDependencies(); + $this->checkPHPRequiredDependencies(); + $this->checkPHPOptionalDependencies(); $this->checkFFmpegDependencies(); $this->checkOptimiseDependencies(); $this->checkDiskPermissions(); @@ -127,7 +128,7 @@ class Installer extends Command $this->installType = $type; } - protected function checkPHPDependencies() + protected function checkPHPRequiredDependencies() { $this->line(' '); $this->info('Checking for required php extensions...'); @@ -139,6 +140,23 @@ class Installer extends Command 'json', 'mbstring', 'openssl', + ]; + + foreach($extensions as $ext) { + if(extension_loaded($ext) == false) { + $this->error("- \"{$ext}\" Required PHP extension not found, aborting installation"); + exit; + } + } + $this->info("- Required PHP extensions found!"); + } + + protected function checkPHPOptionalDependencies() + { + $this->line(' '); + $this->info('Checking For Optional PHP Extensions...'); + + $extensions = [ 'gd', 'intl', 'xml', @@ -148,13 +166,13 @@ class Installer extends Command foreach($extensions as $ext) { if(extension_loaded($ext) == false) { - $this->error("- \"{$ext}\" PHP extension not found, aborting installation"); - exit; + $this->error("- \"{$ext}\" Optional PHP extension not found"); + } else { + $this->info ("- \"{$dep}\" Optional PHP extension found"); } } - $this->info("- Required PHP extensions found!"); - } - + } + protected function checkFFmpegDependencies() { $this->line(' '); From d2e0b9ace1d817afd38e3adfc69f523b57be4b45 Mon Sep 17 00:00:00 2001 From: Shlee Date: Sun, 19 Jun 2022 15:32:44 +0930 Subject: [PATCH 23/30] Update Installer.php --- app/Console/Commands/Installer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 3e40cbd1..830ba818 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -168,7 +168,7 @@ class Installer extends Command if(extension_loaded($ext) == false) { $this->error("- \"{$ext}\" Optional PHP extension not found"); } else { - $this->info ("- \"{$dep}\" Optional PHP extension found"); + $this->info ("- \"{$ext}\" Optional PHP extension found"); } } } From 097a04edc380d2808f1efa430ec911c6b2d0f72b Mon Sep 17 00:00:00 2001 From: Shlee Date: Sun, 19 Jun 2022 15:35:06 +0930 Subject: [PATCH 24/30] Update Installer.php --- app/Console/Commands/Installer.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 830ba818..629fad77 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -131,7 +131,7 @@ class Installer extends Command protected function checkPHPRequiredDependencies() { $this->line(' '); - $this->info('Checking for required php extensions...'); + $this->info('Checking for Required PHP Extensions...'); $extensions = [ 'bcmath', @@ -144,7 +144,7 @@ class Installer extends Command foreach($extensions as $ext) { if(extension_loaded($ext) == false) { - $this->error("- \"{$ext}\" Required PHP extension not found, aborting installation"); + $this->error("- \"{$ext}\" Required PHP Extension not found, aborting installation"); exit; } } @@ -154,7 +154,7 @@ class Installer extends Command protected function checkPHPOptionalDependencies() { $this->line(' '); - $this->info('Checking For Optional PHP Extensions...'); + $this->info('Checking For Additional PHP Extensions...'); $extensions = [ 'gd', @@ -166,9 +166,9 @@ class Installer extends Command foreach($extensions as $ext) { if(extension_loaded($ext) == false) { - $this->error("- \"{$ext}\" Optional PHP extension not found"); + $this->error("- \"{$ext}\" PHP extension not found"); } else { - $this->info ("- \"{$ext}\" Optional PHP extension found"); + $this->info ("- \"{$ext}\" PHP extension found"); } } } From b8526bfeb0de3787203ecd2b25422fbbff7b541c Mon Sep 17 00:00:00 2001 From: Shlee Date: Sun, 19 Jun 2022 15:56:55 +0930 Subject: [PATCH 25/30] Update Installer.php --- app/Console/Commands/Installer.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 629fad77..ed11b54d 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -154,7 +154,7 @@ class Installer extends Command protected function checkPHPOptionalDependencies() { $this->line(' '); - $this->info('Checking For Additional PHP Extensions...'); + $this->info('Checking For Optional PHP Extensions...'); $extensions = [ 'gd', @@ -176,7 +176,7 @@ class Installer extends Command protected function checkFFmpegDependencies() { $this->line(' '); - $this->info('Checking for required FFmpeg dependencies...'); + $this->info('Checking for Required FFmpeg dependencies...'); $ffmpeg = exec('which ffmpeg'); if(empty($ffmpeg)) { @@ -190,7 +190,7 @@ class Installer extends Command protected function checkOptimiseDependencies() { $this->line(' '); - $this->info('Checking for optional Media Optimisation dependencies...'); + $this->info('Checking for Optional Media Optimisation dependencies...'); $dependencies = [ 'jpegoptim', From d749b3c376832b0e7697c57743f241d944dcdc4f Mon Sep 17 00:00:00 2001 From: Shlee Date: Sat, 25 Jun 2022 11:51:50 +0930 Subject: [PATCH 26/30] Update .env.example --- .env.example | 1 + 1 file changed, 1 insertion(+) diff --git a/.env.example b/.env.example index ccab0d83..1e453aed 100644 --- a/.env.example +++ b/.env.example @@ -32,6 +32,7 @@ DB_USERNAME="pixelfed" DB_PASSWORD="pixelfed" # Redis Configuration +REDIS_CLIENT="predis" REDIS_SCHEME="tcp" REDIS_HOST="127.0.0.1" REDIS_PASSWORD="null" From 13a86ab2b54c1e5e7d9b197bdb964636de2d1b2a Mon Sep 17 00:00:00 2001 From: Shlee Date: Sat, 25 Jun 2022 11:52:52 +0930 Subject: [PATCH 27/30] bug fix --- app/Console/Commands/Installer.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index ed11b54d..0f80c8c9 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -282,6 +282,8 @@ class Installer extends Command $redis_password = $this->ask('Set redis password', 'null'); $redis_port = $this->ask('Set redis port', 6379); + + $this->updateEnvFile('REDIS_CLIENT', $redis_client); $this->updateEnvFile('REDIS_SCHEME', 'tcp'); $this->updateEnvFile('REDIS_HOST', $redis_host); $this->updateEnvFile('REDIS_PASSWORD', $redis_password); @@ -338,8 +340,8 @@ class Installer extends Command $this->updateEnvFile('SESSION_DRIVER', $session); $this->updateEnvFile('CACHE_DRIVER', $cache); - $this->updateEnvFile('QUEUE_DRIVER', $cache); - $this->updateEnvFile('BROADCAST_DRIVER', $cache); + $this->updateEnvFile('QUEUE_DRIVER', $queue); + $this->updateEnvFile('BROADCAST_DRIVER', $broadcast); $this->updateEnvFile('LOG_CHANNEL', $log); $this->updateEnvFile('HORIZON_PREFIX', $horizon); } From e0307babf866410ce22e1647eaefa50ef8f7289f Mon Sep 17 00:00:00 2001 From: Shlee Date: Sat, 25 Jun 2022 12:03:00 +0930 Subject: [PATCH 28/30] PHP check lists all PHP modules + linted --- app/Console/Commands/Installer.php | 196 ++++++++++++++--------------- 1 file changed, 92 insertions(+), 104 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 0f80c8c9..4ee9fe35 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -66,10 +66,9 @@ class Installer extends Command $this->envCreate(); $this->installType(); - if($this->installType === 'Advanced') { + if ($this->installType === 'Advanced') { $this->info('Installer: Advanced...'); $this->checkPHPRequiredDependencies(); - $this->checkPHPOptionalDependencies(); $this->checkFFmpegDependencies(); $this->checkOptimiseDependencies(); $this->checkDiskPermissions(); @@ -101,9 +100,9 @@ class Installer extends Command protected function envCheck() { - if( file_exists(base_path('.env')) && - filesize(base_path('.env')) !== 0 && - !$this->option('dangerously-overwrite-env') + if (file_exists(base_path('.env')) && + filesize(base_path('.env')) !== 0 && + !$this->option('dangerously-overwrite-env') ) { $this->line(''); $this->error('Existing .env File Found - Installation Aborted'); @@ -117,7 +116,7 @@ class Installer extends Command { $this->line(''); $this->info('Creating .env if required'); - if(!file_exists(app()->environmentFilePath())) { + if (!file_exists(app()->environmentFilePath())) { exec('cp .env.example .env'); } } @@ -125,7 +124,7 @@ class Installer extends Command protected function installType() { $type = $this->choice('Select installation type', ['Simple', 'Advanced'], 1); - $this->installType = $type; + $this->installType = $type; } protected function checkPHPRequiredDependencies() @@ -140,23 +139,6 @@ class Installer extends Command 'json', 'mbstring', 'openssl', - ]; - - foreach($extensions as $ext) { - if(extension_loaded($ext) == false) { - $this->error("- \"{$ext}\" Required PHP Extension not found, aborting installation"); - exit; - } - } - $this->info("- Required PHP extensions found!"); - } - - protected function checkPHPOptionalDependencies() - { - $this->line(' '); - $this->info('Checking For Optional PHP Extensions...'); - - $extensions = [ 'gd', 'intl', 'xml', @@ -164,22 +146,29 @@ class Installer extends Command 'redis', ]; - foreach($extensions as $ext) { - if(extension_loaded($ext) == false) { + foreach ($extensions as $ext) { + if (extension_loaded($ext) == false) { $this->error("- \"{$ext}\" PHP extension not found"); } else { - $this->info ("- \"{$ext}\" PHP extension found"); + $this->info("- \"{$ext}\" PHP extension found"); } } - } - + + $continue = $this->choice('Do you wish to continue?', ['no', 'yes'], 0); + if ($this->continue === 'no') { + $this->info('Exiting Installer.'); + exit; + } + + } + protected function checkFFmpegDependencies() { $this->line(' '); $this->info('Checking for Required FFmpeg dependencies...'); $ffmpeg = exec('which ffmpeg'); - if(empty($ffmpeg)) { + if (empty($ffmpeg)) { $this->error("- \"{$ext}\" FFmpeg not found, aborting installation"); exit; } else { @@ -191,7 +180,7 @@ class Installer extends Command { $this->line(' '); $this->info('Checking for Optional Media Optimisation dependencies...'); - + $dependencies = [ 'jpegoptim', 'optipng', @@ -199,12 +188,12 @@ class Installer extends Command 'gifsicle', ]; - foreach($dependencies as $dep) { + foreach ($dependencies as $dep) { $which = exec("which $dep"); - if(empty($which)) { + if (empty($which)) { $this->error("- \"{$dep}\" not found"); } else { - $this->info ("- \"{$dep}\" found"); + $this->info("- \"{$dep}\" found"); } } } @@ -217,11 +206,11 @@ class Installer extends Command $paths = [ base_path('bootstrap'), - base_path('storage') + base_path('storage'), ]; - foreach($paths as $path) { - if(is_writeable($path) == false) { + foreach ($paths as $path) { + if (is_writeable($path) == false) { $this->error("- Invalid permission found! Aborting installation."); $this->error(" Please make the following path writeable by the web server:"); $this->error(" $path"); @@ -236,12 +225,12 @@ class Installer extends Command { $this->line(''); $this->info('Enabling production'); - + $this->updateEnvFile('APP_ENV', 'production'); $this->updateEnvFile('APP_DEBUG', 'false'); $this->call('key:generate', ['--force' => true]); - } - + } + protected function instanceDB() { $this->line(''); @@ -265,10 +254,10 @@ class Installer extends Command $this->info('Testing Database...'); $dsn = "{$database}:dbname={$database_db};host={$database_host};port={$database_port};"; try { - $dbh = new PDO($dsn, $database_username, $database_password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); + $dbh = new PDO($dsn, $database_username, $database_password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); } catch (\PDOException $e) { - $this->error('Cannot connect to database, check your details and try again'); - exit; + $this->error('Cannot connect to database, check your details and try again'); + exit; } $this->info('- Connected to DB Successfully'); } @@ -282,7 +271,6 @@ class Installer extends Command $redis_password = $this->ask('Set redis password', 'null'); $redis_port = $this->ask('Set redis port', 6379); - $this->updateEnvFile('REDIS_CLIENT', $redis_client); $this->updateEnvFile('REDIS_SCHEME', 'tcp'); $this->updateEnvFile('REDIS_HOST', $redis_host); @@ -291,12 +279,12 @@ class Installer extends Command $this->info('Testing Redis...'); $redis = Redis::connection(); - if($redis->ping()) { - $this->info('- Connected to Redis Successfully!'); - } else { - $this->error('Cannot connect to Redis, check your details and try again'); - exit; - } + if ($redis->ping()) { + $this->info('- Connected to Redis Successfully!'); + } else { + $this->error('Cannot connect to Redis, check your details and try again'); + exit; + } } protected function instanceURL() @@ -307,18 +295,18 @@ class Installer extends Command $domain = $this->ask('Site Domain [ex: pixelfed.com]'); $domain = strtolower($domain); - if(empty($domain)) { - $this->error('You must set the site domain'); - exit; - } - if(starts_with($domain, 'http')) { - $this->error('The site domain cannot start with https://, you must use the FQDN (eg: example.org)'); - exit; - } - if(strpos($domain, '.') == false) { - $this->error('You must enter a valid site domain'); - exit; - } + if (empty($domain)) { + $this->error('You must set the site domain'); + exit; + } + if (starts_with($domain, 'http')) { + $this->error('The site domain cannot start with https://, you must use the FQDN (eg: example.org)'); + exit; + } + if (strpos($domain, '.') == false) { + $this->error('You must enter a valid site domain'); + exit; + } $this->updateEnvFile('APP_NAME', $name); $this->updateEnvFile('APP_URL', 'https://' . $domain); @@ -331,7 +319,7 @@ class Installer extends Command { $this->line(''); $this->info('Laravel Settings (Defaults are recommended):'); - $session = $this->choice('Select session driver', ["database", "file", "cookie", "redis", "memcached", "array"], 0); + $session = $this->choice('Select session driver', ["database", "file", "cookie", "redis", "memcached", "array"], 0); $cache = $this->choice('Select cache driver', ["redis", "apc", "array", "database", "file", "memcached"], 0); $queue = $this->choice('Select queue driver', ["redis", "database", "sync", "beanstalkd", "sqs", "null"], 0); $broadcast = $this->choice('Select broadcast driver', ["log", "redis", "pusher", "null"], 0); @@ -345,7 +333,7 @@ class Installer extends Command $this->updateEnvFile('LOG_CHANNEL', $log); $this->updateEnvFile('HORIZON_PREFIX', $horizon); } - + protected function instanceSettings() { $this->line(''); @@ -363,11 +351,11 @@ class Installer extends Command } protected function activityPubSettings() - { + { $this->line(''); $this->info('Federation Settings:'); $activitypub_federation = $this->choice('Enable ActivityPub federation?', ['false', 'true'], 1); - + $this->updateEnvFile('ACTIVITY_PUB', $activitypub_federation); $this->updateEnvFile('AP_REMOTE_FOLLOW', $activitypub_federation); $this->updateEnvFile('AP_INBOX', $activitypub_federation); @@ -376,38 +364,38 @@ class Installer extends Command } protected function mediaSettings() - { + { $this->line(''); $this->info('Media Settings:'); $optimize_media = $this->choice('Optimize media uploads? Requires jpegoptim and other dependencies!', ['false', 'true'], 1); $image_quality = $this->ask('Set image optimization quality between 1-100. Default is 80%, lower values use less disk space at the expense of image quality.', '80'); - if($image_quality < 1) { - $this->error('Min image quality is 1. You should avoid such a low value, 60 at minimum is recommended.'); - exit; - } - if($image_quality > 100) { - $this->error('Max image quality is 100'); - exit; - } + if ($image_quality < 1) { + $this->error('Min image quality is 1. You should avoid such a low value, 60 at minimum is recommended.'); + exit; + } + if ($image_quality > 100) { + $this->error('Max image quality is 100'); + exit; + } $this->info('Note: Max photo size cannot exceed `post_max_size` in php.ini.'); $max_photo_size = $this->ask('Max photo upload size in kilobytes. Default 15000 which is equal to 15MB', '15000'); - + $max_caption_length = $this->ask('Max caption limit. Default to 500, max 5000.', '500'); - if($max_caption_length > 5000) { - $this->error('Max caption length is 5000 characters.'); - exit; - } + if ($max_caption_length > 5000) { + $this->error('Max caption length is 5000 characters.'); + exit; + } $max_album_length = $this->ask('Max photos allowed per album. Choose a value between 1 and 10.', '4'); - if($max_album_length < 1) { - $this->error('Min album length is 1 photos per album.'); - exit; - } - if($max_album_length > 10) { - $this->error('Max album length is 10 photos per album.'); - exit; - } - + if ($max_album_length < 1) { + $this->error('Min album length is 1 photos per album.'); + exit; + } + if ($max_album_length > 10) { + $this->error('Max album length is 10 photos per album.'); + exit; + } + $this->updateEnvFile('PF_OPTIMIZE_IMAGES', $optimize_media); $this->updateEnvFile('IMAGE_QUALITY', $image_quality); $this->updateEnvFile('MAX_PHOTO_SIZE', $max_photo_size); @@ -421,11 +409,11 @@ class Installer extends Command $this->info('Note: We recommend running database migrations now!'); $confirm = $this->choice('Do you want to run the database migrations?', ['Yes', 'No'], 0); - if($confirm === 'Yes') { - sleep(3); + if ($confirm === 'Yes') { + sleep(3); $this->line(''); $this->info('Migrating DB:'); - $this->call('migrate', ['--force' => true]); + $this->call('migrate', ['--force' => true]); $this->line(''); $this->info('Importing Cities:'); $this->call('import:cities'); @@ -437,12 +425,12 @@ class Installer extends Command $this->call('passport:keys', ['--force' => true]); $confirm = $this->choice('Do you want to create an admin account?', ['Yes', 'No'], 0); - if($confirm === 'Yes') { - $this->call('user:create'); - } + if ($confirm === 'Yes') { + $this->call('user:create'); + } } } - + protected function resetArtisanCache() { $this->call('config:cache'); @@ -458,8 +446,8 @@ class Installer extends Command } ##### -# Installer Functions -##### + # Installer Functions + ##### protected function checkEnvKeys($key, $error) { @@ -467,7 +455,7 @@ class Installer extends Command $payload = file_get_contents($envPath); if ($existing = $this->existingEnv($key, $payload)) { - } else { + } else { $this->info("$key empty - $error"); } } @@ -502,14 +490,14 @@ class Installer extends Command fclose($file); } - protected function parseSize($size) { + protected function parseSize($size) + { $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); $size = preg_replace('/[^0-9\.]/', '', $size); if ($unit) { - return round($size * pow(1024, stripos('bkmgtpezy', $unit[0]))); - } - else { - return round($size); + return round($size * pow(1024, stripos('bkmgtpezy', $unit[0]))); + } else { + return round($size); } } } From ed2d4a9b348393b1d1b903d9a419219ea196de6e Mon Sep 17 00:00:00 2001 From: Shlee Date: Sat, 25 Jun 2022 12:06:15 +0930 Subject: [PATCH 29/30] Update Installer.php --- app/Console/Commands/Installer.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index 4ee9fe35..e22a6144 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -155,6 +155,7 @@ class Installer extends Command } $continue = $this->choice('Do you wish to continue?', ['no', 'yes'], 0); + $this->continue = $continue; if ($this->continue === 'no') { $this->info('Exiting Installer.'); exit; From 563b7af500682cbdc291c3535c8807b802253cbb Mon Sep 17 00:00:00 2001 From: Shlee Date: Sat, 25 Jun 2022 12:10:41 +0930 Subject: [PATCH 30/30] Update Installer.php --- app/Console/Commands/Installer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/Installer.php b/app/Console/Commands/Installer.php index e22a6144..9867b3d7 100644 --- a/app/Console/Commands/Installer.php +++ b/app/Console/Commands/Installer.php @@ -148,9 +148,9 @@ class Installer extends Command foreach ($extensions as $ext) { if (extension_loaded($ext) == false) { - $this->error("- \"{$ext}\" PHP extension not found"); + $this->error("- \"{$ext}\" not found"); } else { - $this->info("- \"{$ext}\" PHP extension found"); + $this->info("- \"{$ext}\" found"); } }