Skip to main content

Production & Deployment (PHP Deployer)

SaaSykit comes with integration of PHP Deployer for deployment. You can use it to provision and deploy your application to any server.

You can also provision and deploy your SaaSykit-based app using Laravel Forge, a server provisioning tool that allows you to deploy your app to a server with a few clicks. For more info on how to use Laravel Forge, check the Laravel Forge docs.

Deployer offer a zero downtime deployment, rollbacks, parallel deployment (in case your have multiple servers), and many more features. All that using a single deployment command.

It's not necessary to use Deployer for provisioning your server if you prefer to do it on your own. You can use Deployer only for deployment.

Best configuration for productionโ€‹

It's highly recommended that you use a faster cache for production (redis) for session and cache driver. It's also important to adjust the queue driver to use redis for better performance.

Here is a recommended .env configuration for production:

APP_ENV=production
APP_DEBUG=false

CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis

Provisioning your serverโ€‹

If you prefer to provision your server on your own, you can skip this step.

warning

Deployer only supports Ubuntu 20.04 LTS (focal) for provisioning. So make sure that your server is running Ubuntu 20.04 LTS before proceeding.

How Deployer provisions your serverโ€‹

Deployer comes with a set of recipes that are divided into tasks. Each task is responsible for a specific job. For example, the deploy:prepare task is responsible for creating the necessary directories for deployment.

Deployers works from within your local machine, it connects to your server using SSH and executes the tasks on the server. You can configure it to run within CI/CD pipelines as well.

Deployer uses the deploy.php file (shipped in SaaSykit code already) to configure the deployment/provisioning process. It will install the necessary packages like (php, mysql, redis, caddy web server, etc.) and configure them for you.

tip

If you plan to have your application deployed on multiple servers, you would need to edit the deploy.php file and add the necessary configuration for each server.

If you choose to use Deployer to provision your server, it will create a new user with the name deployer and add it to the sudo group. This will be the user that will be used for deployment.

To provision your server using Deployer:

  1. Get a server with Ubuntu 20.04 LTS installed, from any cloud provider. (e.g. DigitalOcean, Linode, Vultr, AWS, Google Cloud, Hetzner, etc.)

  2. Add your project to a new repository on GitHub. Deployer will use that repository to deploy your app. You will need to add your SSH key to your GitHub account to be able to push to the repository later in the deployment section below.

  3. CD into code directory of your project locally (where composer.json file is located):

    cd /path/to/your-saasykit-based-app
  4. Install composer packages (if you didn't already):

    composer install
  5. Open the deploy.php file and set the following configuration:

    $remoteUser = 'deployer';   // the user that will be used to connect to remote server and deploy the app
    $sudoPassword = ''; // the sudo password of the remote user

    $deployPath = '~/app'; // the path where the app will be deployed on the remote server

    $host = ''; // the host of the remote server (can be an IP or domain)
    $domain = ''; // the domain of the app

    $repository = '[email protected]:username/saasykit.git'; // has to be in the SSH format
    $subDirectory = 'saasykit'; // the subdirectory of the repository where the app is located (this is the directory that contains the composer.json file)

    $phpVersion = '8.3'; // the version of PHP to be installed on the server
    tip

    Don't change the $remoteUser variable if you provision the server using Deployer, as it will create a new user with the name deployer and add it to the sudo group, you need to use this user to connect to the server and deploy the app.

  6. Run the provisioning command:

    ./vendor/bin/dep provision -o remote_user={{user}}  -o become=root -o identity_file=~/path/to/private/key.pem -vvv

    Replace {{user}} with the user that you will use to connect to the server.

    tip

    Don't confuse the user that you will use to connect to the server in the above command (remote_user={{user}}) with the remoteUser variable in the deploy.php file. The remoteUser variable is the user that will be created on the server and used for deployment, but in order to create that user, you need to connect to the server using a different user that you typically receive from your cloud provider (e.g. ubuntu).

    Feel free to remove the identity_file option in the command above if you don't use a private key to connect to the server.

  7. Deployer will ask you a few questions (like which database you want to use, the credentials, etc.), answer them and press enter.

  8. Go have a cup of coffee and wait for the provisioning to finish. โ˜•๏ธ (might take 5 minutes or more depending on your server specs)

  9. If the provisioning process fails at the provision:website step, this means that there might be a permission problem (related to admin permissions), so please run the following:

    ./vendor/bin/dep provision --start-from provision:website -vvv
  10. Once done, your server should be ready to go. Now let's deploy the app.

Deploying your appโ€‹

Now you are about to experience the magic of Deployer. Deployer will deploy your app to the server with a single command.

To configure the deployment process:

  1. (If you haven't already), create a new repository on GitHub (or Gitlab) to host your app. Deployer will use that repository to deploy your app on the server.

  2. Add your server's SSH key to your GitHub account to be able to access the repository from the server.

    warning

    If you provisioned your server using Deployer, make sure that the SSH public key you'll add to Github is the one for deployer user (which will be used for deployment), otherwise use the SSH public key for the user that you will use to deploy the app if you provisioned the server on your own.

    tip

    You can use the handy shortcut command ./vendor/bin/dep ssh to login to your server using SSH, then run cat ~/.ssh/id_rsa.pub to get the public key, and then add it to your GitHub account.

  3. (If you haven't already), open the deploy.php file and set the following configuration:

    $remoteUser = 'deployer';   // the user that will be used to connect to remote server and deploy the app
    $sudoPassword = ''; // the sudo password of the remote user

    $deployPath = '~/app'; // the path where the app will be deployed on the remote server

    $host = ''; // the host of the remote server (can be an IP or domain)
    $domain = ''; // the domain of the app

    $repository = '[email protected]:username/saasykit.git'; // has to be in the SSH format
    $subDirectory = 'saasykit'; // the subdirectory of the repository where the app is located (this is the directory that contains the composer.json file)

    $phpVersion = '8.2'; // the version of PHP to be installed on the server
    tip

    If you used Deployer to provision the app, set the "remoteUser" variable to deployer, otherwise set it to the user that you will use to connect to the server and deploy the app.

    For more info on each variable, read the comments beside each variable in the deploy.php file.

  4. Run the deployment command:

    ./vendor/bin/dep deploy 

    During your first deployment you will get the warning warning Your .env file is empty! Skipping.... This is normal, as the .env file is not created yet. You will need to create it in the next step.

  5. Create a .env file:

    ./vendor/bin/dep ssh
    cp .env.example ../../shared/.env
  6. Edit the .env file and set the necessary configuration:

    nano ../../shared/.env
    tip

    Set the APP_ENV to production, adjust the LOG_LEVEL, APP_DEBUG, APP_URL values and set the database credentials, redis, etc.

  7. Generate a new application key:

    php artisan key:generate
  8. Exit the SSH session:

    exit
  9. Deploy the app again:

    ./vendor/bin/dep deploy

    This time the deployment should succeed without any warnings! ๐ŸŽ‰

  10. Open your browser and visit your website's domain, you should see the app running.

In the future, if do changes to your app, then push your changes to the repository and all what you have to do is to run the deployment command again ./vendor/bin/dep deploy, and Deployer will take care of the rest.

For more info on how to use Deployer, check the deployer official documentation.

Now you will need to create your admin user to be able to access the admin panel.

Creating your admin userโ€‹

To create an admin user:

  1. Login to your server using SSH:

    ./vendor/bin/dep ssh
  2. Run the following command:

    php artisan app:create-admin-user
  3. Enter your user's email, and a password will be generated for your new account and displayed on the screen.

  4. Head to /admin on your website's domain (e.g. https://example.com/admin) and login using the email and password that you just created. (You can change the password later from the admin panel)

  5. Once logged in, you will be redirected to the admin dashboard where you can start configuring your app.

Next stepsโ€‹

Now that you have your app deployed, you will need to configure the aspects of your app like the settings, email providers, payment providers, login providers, plans & products, users, etc, before building your awesome SaaS product on top of SaaSykit.

Check out the product check list for a more comprehensive list of things to do before launching your product.

Queue workersโ€‹

SaaSykit uses Laravel Horizon to manage the queue workers. Horizon comes with a beautiful dashboard that allows you to monitor your queue workers, jobs, and failed jobs.

To open the dashboard, visit the /horizon route on your website's domain (e.g. https://example.com/horizon).

tip

Only admin users can access the Horizon dashboard.

tip

If you provisioned your server on your own, you will need to configure supervisor to monitor the queue workers and keep horizon running in the background. If you provisioned your server using Deployer, supervisor will be configured for you automatically.

Troubleshooting & FAQsโ€‹

The connection for this site is not secure?โ€‹

If your server uses Caddy as web server (included in Deployer provisioning), This might be related to Caddy not being able to get the SSL certificate from Let's Encrypt (because of domain name issue). Have a look at the logs of Caddy and see if you can find any error:

./vendor/bin/dep logs:caddy