A full-featured multi-tenant app with Laravel Part 7 — Deployment

Ashok Gelal
6 min readMay 30, 2018
Photo by Efe Kurnaz

Part 0, Part 1, Part 2, Part3, Part4, Part 5, Part 6, Part 7 👇

In this part of we’ll accomplish the following small tasks:

✅ Provision a DigitalOcean server using Cleavr

✅ Setup a system database and a super admin user

✅ Create a wildcard SSL/TLS supported multi-tenant Laravel site

✅ Setup local git repository for deployments

✅ Create and sync environment variables to remote server

✅ Setup deployment hooks

✅ Deploy

If you are looking for an easy way to provision a server and deploy your Laravel apps, try Cleavr 👇

Need help deploying your Laravel apps? Get some on Cleavr Forum.

Before we march forward to adding more features to our Townhouse app, let’s first learn how to deploy it to a real server. This way we can push new features in small increments as they are done and get feedback quickly. If you have done fair amount of software development, whether web or not, you should know the advantages of such approach.

There are number of ways to deploy a Laravel application. You can also do this manually as well, of course!

Deploying is best left for automation but automating deployments from scratch is going to cost you either money, time, or both.

To address these issues, I’ve written a cross-platform desktop app called Cleaver to help individual developers provision and deploy servers on, for now, DigitalOcean and Vultr, for free. It is still in beta but is stable enough to use for production servers.

Cleaver helps you create servers ready for deploying your web apps with zero downtime.

Cleaver supports not just provisioning and deployments but also managing Let’s Encrypt SSL certificates, Database management, unlimited rollbacks, deployment hooks, jobs scheduling, process monitoring via Supervisor, setting up Nginx redirects and more.

Because I know Cleaver better than any other tool and also it is free (and awesome), I’ll be using it for deploying our multi-tenant app. You should too!

Prerequisites:

  • Have an account on DigitalOcean. If you don’t have it already, using this link to signup will add $10 to your account so that you can follow this tutorial without spending a penny.
  • Download Cleaver. Head to https://getcleaver.com and get Cleaver for the OS of your choice. It’s available for Mac, Windows, and Linux. If you have time, I recommend you going through Cleaver’s Laravel documentation at least once.
  • Have a domain name that is pointed to the nameservers of DigitalOcean (ns1.digitalocean.com, ns2.digitalocean.com, and ns3.digitalocean.com). For this tutorial we will use townhouse.site for the domain.
    I strongly recommend not adding DNS records manually as Cleaver will do it smartly for you. You may have to wait for few hours to make sure that the DNS entries have been propagated through out the world before creating the site. But don’t worry, Cleaver is smart enough to let you know if you have misconfigured/inaccessible nameservers.

1. Add DigitalOcean Profile

We need to get an API token from DigitalOcean so that Cleaver can provision servers on your behalf. Read here on how to do it: https://docs.getcleaver.com/cloud-providers/digitalocean.html

2. Provision a DigitalOcean Server

Once you have added a profile, it’s time to provision server. Here are the steps: https://docs.getcleaver.com/servers/provisioning.html

Name the server townhouse-server and make sure you have selected MySQL 5.7, NodeJS with NPM, as well as PHP 7.2

Select MySQL 5.7, PHP 7.2 and check Install NodeJS and click Create

As your server is being provisioned, make note of your database root password. We are going to need this soon. Just FYI, Cleaver copies the passwords to your keychain as well. So don’t worry if you forgot to copy it.

3. Add a Database and a User

Once the server is provisioned and active, select the server and create a database. Call it townhousedb. Once the database is created, create a database user called townhouseadmin and allow it to access townhousedb. The password you entered will be saved in your keychain as well.

With Cleaver creating databases and users is very easy and intuitive

The user townhouseadmin can access townhousedb but we need more privileges for our townhouseadmin user, just like in our database in the first part of this series. If you are using SequelPro, you should be able to do this very easily!

Login using root as shown in the screenshot below. For the SSH key use your private key in ~/.ssh/cleaver/townhouse-server-xxxxxx

Once you login to your remote database server, give townhouseadmin global privileges so that it can create additional databases and users.

4. Create a secure multi-tenant Laravel site

Select the server you just provisioned and add a Laravel site using your domain name. Make sure to check all three advanced options — allow any subdomain, add DNS records, and secure with Let’s Encrypt.

Really, it takes just this much to get a very secure site created with Cleaver

5. Setup GIT repository for deployments

Now let’s select the local townhouse git repository that we want to deploy. Select the site you created in step 4 and click Repo Settings. Browse the local townhouse git repository directory, give the branch that you’d like to deploy, and hit Done. You can always come back and modify this if you want to.

6. Create and sync environment variables to remote server

Let’s create a dedicated .env file that would hold all our production environment variables. Cleaver will sync this for you and also copy it over every time you deploy. Very handy!

Copy .env file to something like .env.cleaver and modify the variables. Make sure you have edited at least these variables:

APP_ENV=production
APP_KEY=<create a new key>
APP_DEBUG=false
APP_URL_BASE=<your domain name>
APP_URL=https://${APP_URL_BASE}
DB_CONNECTION=system
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=<name of database created in step 3>
DB_USERNAME=<name of admin user created in step 3>
DB_PASSWORD=<password for the database created in step 3>
...

Now switch to Environment tab and input the full path to your .env.cleaver file and then hit Sync with Server. Make sure your .env file is not committed otherwise Cleaver won’t copy your .env file during deployments.

7. Setup deployment hooks

Cleaver auto installs default deployment hooks appropriate for your project type. In our case, we need hook few extra scripts when deploying. Cleaver let’s you add, copy, disable/enable, and reorder hooks so that you could customize your deployment actions.

Switch to Hooks tab and click Add New Hook button. Repeat this process to add following hooks (don’t worry about the order):

  • Name: Install Tenancy
cd {{ release }}
php artisan tenancy:install
  • Name: Migrate System Database
cd {{ release }}
php artisan migrate --force
  • Name: Migrate tenancy databases
cd {{ release }}
php artisan tenancy:migrate --force
  • Name: Seed tenant
cd {{ release }}
php artisan tenancy:db:seed

Once you are done adding all the above hooks, reorder them so that the orders look like this (make sure to hit Save Order button after you are done reordering):

8. Deploy

We are done with the setup and ready to Deploy. Hit that green DEPLOY button and wait a minute or two to see your awesome multi-tenant web app come alive!

It may look like lots of steps for a deployment but remember we did everything from scratch and from this point on you only have to follow Step 8 every time you want to deploy your app.

It’s now time to create a tenant and test it. Fire up your terminal, login to your server, and create a demo tenant:

$ ssh cleaver@<server-ip-address> -i ~/.ssh/cleaver/townhouse-server-xxxxxxxx
$ cd /home/cleaver/<your domain>/current
$ php artisan tenant:create demo demo@example.com

Visit https://demo.<your-domain> and you should be greeted by your secure multi-tenant site!

You can also use Cleaver’s Quick Script to create a tenant if you don’t feel like logging into your server using SSH.

Play with Cleaver a bit more and see all its other super powers. If you feel like it is missing some super powers, please join Cleaver’s Slack channel and suggest. You’ll be pleasantly surprised how receptive we are of users’ feedback and comments. See you in the next post!

--

--

Ashok Gelal

Learner. Achiever. Loves writing clean code and craft beautiful products. 👉 https://alpas.dev