Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
meltmedia/meltconsole / src / App / Commands / SetupServerCommand.php
Size: Mime:
<?php

namespace MeltConsole\App\Commands;

use Symfony\Component\Console\Exception\LogicException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Filesystem\Filesystem;


// 1. mkdir <PROJECTNAME>-<ENV>
// 1. mkdir docroot/.well-known && chmod 775 docroot/.well-known
// 1. sudo copy sites-available/TEMPLATE.drupal.twig -> /etc/nginx/sites-available/<PROJECTNAME>-<ENV>
// 1. sudo ln -s /etc/nginx/sites-available/<PROJECTNAME>-<ENV> /etc/nginx/sites-enabled
// 1. If `sudo nginx -t` is 'ok' then `sudo systemctl reload nginx` else throw error (testNginx)
// 1. Run sudo certbot certonly --webroot -w /var/www/apps/{{ project }}/docroot/ -d {{ project }}.{{ platform}}.meltdemo.com
// 1. ^ if (fileexists(/etc/letsencrypt/live/TEMPLATE.meltdemo.com/fullchain.pem)) (sudo copy ssl/ssl_TEMPLATE.conf.twig -> /etc/nginx/ssl/ssl_{{ project }}.conf)
// 1. Backup /etc/nginx/sites-available/<PROJECTNAME>-<ENV> -> /etc/nginx/sites-available/<PROJECTNAME>-<ENV>-backup
// 1. Read /etc/nginx/sites-available/<PROJECTNAME>-<ENV> and remove `##--` to uncomment `include ssl/ssl_{{ project }}.conf;` line && sudo rewrite file /etc/nginx/sites-available/<PROJECTNAME>-<ENV>
// 1. If `sudo nginx -t` is 'ok' then `sudo systemctl reload nginx` else throw error (testNginx)
// 1. Cleanup by `sudo rm /etc/nginx/sites-available/<PROJECTNAME>-<ENV>-backup`
// 1. Log url to user

/**
 * Handles the functionality to create new environments on the server.
 *
 * This command is ran for us in the `CreateEnvironmentCommand` class. If this
 * command needs to be ran, run it on the server.
 *
 * @package MeltConsole\App\Commands
 */
class SetupServerCommand extends MeltCommand {

  /**
   * Environment.
   *
   * @var string
   */
  private $env;

  /**
   * {@inheritdoc}
   */
  protected function configure() {

    // Initial config for command.
    $this
      ->setName('melt:setup-server')
      ->setAliases(['melt:ss'])
      ->setDescription('Prepares server prior to lando intialization.')
      ->addOption('projectName', null, InputOption::VALUE_REQUIRED, 'Project name')
      ->addOption('projectRoot', null, InputOption::VALUE_REQUIRED, 'Project root');
  }

  /**
   * {@inheritdoc}
   */
  protected function execute(InputInterface $input, OutputInterface $output) {
    $projectName = $input->getOption('projectName');
    $projectRoot = $input->getOption('projectRoot');


    $dbName = str_replace('-', '_', $projectName);
    $dbUser = $this->getLocalEnvVar('MELT_DB_USER');
    $dbPass = $this->getLocalEnvVar('MELT_DB_PASS');

    if (!empty($projectName) && !empty($projectRoot)) {

      // Create database to connect to
      $this->runLocalCommands([
        "cd {$projectRoot}",
        "mysql -u{$dbUser} -p{$dbPass} -e 'CREATE DATABASE {$dbName}'"
      ]);

      // Add local.settings.php file.
      $this->renderFile(
        'local.settings.php.twig',
        "{$projectRoot}/docroot/sites/default/settings/local.settings.php",
        [ 'db_name' => $dbName ],
         'server'
      );

      // Add nginx config to `/tmp` folder
      $this->renderFile(
        'sites-available/TEMPLATE.drupal.twig',
        "/tmp/{$projectName}/sites-available/{$projectName}",
        ['projectName' => $projectName],
        'server'
      );

      // Add ssl config to `/tmp` folder
      $this->renderFile(
        'ssl/ssl_TEMPLATE.conf.twig',
        "/tmp/{$projectName}/ssl/ssl_{$projectName}.conf",
        ['subDomain' => "{$projectName}.drupal"],
        'server'
      );

      // Create symbolic link to `sites-enabled` directory from `sites-available` dir.
      $this->runLocalCommands([
        "sudo cp /tmp/{$projectName}/sites-available/{$projectName} /etc/nginx/sites-available",
        "sudo ln -sfn /etc/nginx/sites-available/{$projectName} /etc/nginx/sites-enabled"
      ]);


      if($this->testNginx() == 'OK'){

        // Create `docroot/.well-known` directory before we setup out SSL certificate
        // See https://letsencrypt.readthedocs.io/en/latest/using.html#webroot
        $this->runLocalCommands([
          "cd {$projectRoot}",
          'mkdir -p docroot/.well-known',
          'chmod 755 docroot/.well-known',
        ]);

        // Begin commands to setup SSL
        $this->runLocalCommands([
          // Reload nginx
          'sudo systemctl reload nginx' ,

          // Setup SSL with letsencrypt using `certbot` using the `webroot` plugin.
          // certbot: https://certbot.eff.org/lets-encrypt
          // webroot: https://letsencrypt.readthedocs.io/en/latest/using.html#webroot
          "sudo certbot certonly --webroot -w /var/www/apps/{$projectName}/docroot/ -d {$projectName}.drupal.meltdemo.com",

          // Check to make sure pem file was created by the `certbot` command above
          "sudo [ -e /etc/letsencrypt/live/{$projectName}.drupal.meltdemo.com/fullchain.pem ]",

          // If `fullchain.pem` exists, copy it over to `/etc/nginx/ssl/`
          "sudo cp /tmp/{$projectName}/ssl/ssl_{$projectName}.conf /etc/nginx/ssl/"

        ]);

        // Make backup of before we remove the SSL include
        $this->runLocalCommands([
          "cp /tmp/{$projectName}/sites-available/{$projectName} /tmp/{$projectName}/sites-available/{$projectName}-backup"
        ]);

        // Uncomment the SSL include
        $nginxConfData = file_get_contents("/tmp/{$projectName}/sites-available/{$projectName}");
        $nginxConfData = str_replace('##--', '', $nginxConfData); // uncomment ssl conf include
        file_put_contents("/tmp/{$projectName}/sites-available/{$projectName}", $nginxConfData);

        $this->runLocalCommands([
          'sudo nginx -t',
          'sudo systemctl reload nginx',
          'sudo systemctl reload php7.2-fpm'
        ]);

      } else {
        throw new \Exception('NGINX error');
      }

    }
    else {
      throw new LogicException('Value(s) missing for `--projectName` and `--projectRoot` option(s).');
    }

  }

  protected function testNginx(){
    $process = $this->runLocalCommands([
      'sudo nginx -t && echo "OK"'
    ]);

    return trim($process->getOutput());
  }

}