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.
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.
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:
-
Get a server with Ubuntu 20.04 LTS installed, from any cloud provider. (e.g. DigitalOcean, Linode, Vultr, AWS, Google Cloud, Hetzner, etc.)
-
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.
-
CD into code directory of your project locally (where composer.json file is located):
cd /path/to/your-saasykit-based-app
-
Install composer packages (if you didn't already):
composer install
-
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 servertipDon't change the
$remoteUser
variable if you provision the server using Deployer, as it will create a new user with the namedeployer
and add it to thesudo
group, you need to use this user to connect to the server and deploy the app. -
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.tipDon't confuse the user that you will use to connect to the server in the above command (
remote_user={{user}}
) with theremoteUser
variable in thedeploy.php
file. TheremoteUser
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. -
Deployer will ask you a few questions (like which database you want to use, the credentials, etc.), answer them and press enter.
-
Go have a cup of coffee and wait for the provisioning to finish. โ๏ธ (might take 5 minutes or more depending on your server specs)
-
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
-
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:
-
(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.
-
Add your server's SSH key to your GitHub account to be able to access the repository from the server.
warningIf 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.tipYou can use the handy shortcut command
./vendor/bin/dep ssh
to login to your server using SSH, then runcat ~/.ssh/id_rsa.pub
to get the public key, and then add it to your GitHub account. -
(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 servertipIf 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. -
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. -
Create a
.env
file:./vendor/bin/dep ssh
cp .env.example ../../shared/.env -
Edit the
.env
file and set the necessary configuration:nano ../../shared/.env
tipSet the APP_ENV to
production
, adjust the LOG_LEVEL, APP_DEBUG, APP_URL values and set the database credentials, redis, etc. -
Generate a new application key:
php artisan key:generate
-
Exit the SSH session:
exit
-
Deploy the app again:
./vendor/bin/dep deploy
This time the deployment should succeed without any warnings! ๐
-
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:
-
Login to your server using SSH:
./vendor/bin/dep ssh
-
Run the following command:
php artisan app:create-admin-user
-
Enter your user's email, and a password will be generated for your new account and displayed on the screen.
-
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) -
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
).
Only admin users can access the Horizon dashboard.
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