Setting up a Winter application with Cleavr

Ben Thomson
Posted on Nov 09, 2021. is a server management app that takes the headache out of server and application management, with fantastic integration for cloud server providers like DigitalOcean, Amazon Web Services, Linode and Vultr. It sports first-rate support for development workflows by linking directly to GitHub, Bitbucket and Gitlab repositories, atomic deployments, database and backup management, and much more.

And it handles Winter with ease!

This tutorial will walk you through the steps of setting up a Winter application on a Cleavr-managed server. It assumes that you have already got a Cleavr account and a Laravel-Optimized server set up with your cloud server provider and linked to your Cleavr account. Review the pricing for Cleavr and the documentation on provisioning a server before proceeding.

Before starting

To take full advantage of Cleavr's automated deployment, you will need a repository for your Winter installation available. You can either fork the main Winter repository or use one of the other installation methods to create a local Winter installation, and commit your local Winter installation to your repository.

Keep your repository details handy, as you will need these going forward.

Step 1: Set up a site

To start, navigate to your server and click on Sites in the left menu. Click Add Site to begin setting up a new site.

Add a site

You will be prompted to configure the site. The following options should be applied:

  • App Type: PHP
  • Domain Name: The domain name of your site. You can also choose to use a temporary domain if you wish.
  • Install Free SSL: This should be enabled unless your domain name is not set up.
  • Advanced Options
    • PHP Version: At least 7.2 - preferably 8.0 or above.
    • Web Directory: public
    • Supercharge with FastCGI cache: Enabled
    • Setup Database: Enabled
    • Database Type: Any should work, but recommend MariaDB 10.4.
    • Database Name, User and Password: Any value for these fields is fine, just keep note of them.

Cleavr will then commission your application hosting on the server. You will be alerted when this process is complete. When the site is commissioned, a "webapp" will also be commissioned linked to this site.

Step 2: Configure the webapp

Navigate to Webapps / Deployments in the main menu, and you will see your new site's webapp listed. Click on this webapp to get started with configuring the webapp.

To set up automated deployments, a repository must be linked to the webapp. Click on Deployments in the left menu to set this up.

Configure repository

You must click on the Code repository tab and enter in the details to your repository. If you have not yet set up a source provider, follow the instructions to set this up.

Repository configured

By enabling Push to Deploy, Cleavr will track changes made to the given repository and branch, and automatically run the deployment process when it detects new changes.

Click Update to save the changes.

Step 3: Configure deployment hooks

Before running your first deployment, you will need to configure the deployment hooks. We will use these deployment hooks to do the following:

  • Install or update the Composer dependencies
  • Run any pending database migrations
  • Symlink the global storage folder to the new release
  • Clear the cache
  • Set up the public webroot folder
  • Create a new release and swap it out with the current release.

The great news is, both the first and last steps are already configured by Cleavr!

Click on the Deployment Hooks on the left menu, and you will be presented with the default hooks for a PHP application.

Deployment hooks

Before going any further, enable the Install Composer Dependencies hook by clicking the three dots and the right and choosing Enable. This ensures that all Composer dependencies are installed in the deployment process.

Next, we'll need to add four new hooks. Click the Add Hook button and call the hook Run Database Migrations. It needs to have the following bash script:

cd {{ releasePath }}
php artisan winter:up

Add a hook

Make sure that your server is ticked, then click the Add button to save the hook. Using the 4 bars on the left of the hook in the hooks list, drag this new hook so that is ordered just before the Activate New Deployment hook.

Now repeat this process for the second hook, calling it Symlink Storage and using the following bash script:


if [ ! -d "{{ projectPath }}/$STORAGE_DIR" ]; then
    echo "Creating new global storage directory at {{ projectPath }}/$STORAGE_DIR"
    mv "{{ releasePath }}/$STORAGE_DIR" "{{ projectPath }}/$STORAGE_DIR"

if [ -d "{{ releasePath }}/$STORAGE_DIR" ]; then
    echo "Remove release storage directory"
    rm -rf "{{ releasePath}}/$STORAGE_DIR"

echo "Symlink global storage to release"
ln -s "{{ projectPath }}/$STORAGE_DIR" "{{ releasePath }}/$STORAGE_DIR"

A bit of detail about this script - on the first deploy, this script will move the first deployment's storage directory to a global location and will form the basis of the storage directory for all subsequent releases and will be symlinked to the release's storage directory. On subsequent deployments, the storage directory retrieved from the repository will be deleted and the global storage directory will be symlinked in its place, ensuring that your media and uploaded files are kept between releases.

Once this hook is saved, move it between the Run Database Migrations and Activate New Deployment hooks.

Now repeat this process for the third hook, calling it Clear Cache and using the following bash script:

cd {{ releasePath }}
php artisan cache:clear

Once added, you should drag this new hook to be between Symlink Storage and Activate New Deployment hooks.

Finally, repeat this process for the fourth hook, calling it Set Up Public Folder and using the following bash script:

cd {{ releasePath }}
php artisan winter:mirror public/

Once added, you should drag this new hook to be between Clear Cache and Activate New Deployment.

The final result should look similar to this:

Hooks configured

The hooks are now set up. One more step to go before running our first deployment.

Step 4: Prepare Winter and environment

For this last step, we need to allow Winter to work with environment variables. On your local copy of Winter, run php artisan winter:env to generate an environment file (.env) and change the configuration files to use this environment file for configuration.

Adjust the values as necessary for your local environment, and then copy the contents of this file. You will need to commit the changes to the configuration files into your repository (note: this may trigger a deployment on Cleavr, don't worry if this fails - we're going to redeploy the site shortly).

On Cleavr, click the Environment link in the left menu to bring up the project's environment variables.

Paste the contents of your environment file into the environment variables textarea. We will then need to adjust the contents of this file to match the environment on your server. You should incorporate the following changes:

  • APP_DEBUG: false
  • APP_URL: Either your domain or the temporary domain of the project
  • APP_KEY: A random 32-character string
  • DB_CONNECTION: mysql or postgres depending on your DB type.
  • DB_HOST: localhost
  • DB_DATABASE, DB_USERNAME and DB_PASSWORD: Your database details from earlier
  • CACHE_DRIVER: redis
  • SESSION_DRIVER: memcached
  • QUEUE_CONNECTION: database
  • MAIL_DRIVER: sendmail (or smtp if you have your own mail server)
  • ROUTES_CACHE: true
  • ASSET_CACHE: true

Click Sync to save the environment file on your server. You're now ready to go!

Step 5: Deploy!

Your site is now ready for deployment. Click Deployments in the left menu, and click the Deploy button to trigger your first deployment.


Cleavr will deploy your code base and run through all the hooks you created earlier.

Deployment progress

Note that on the first migration, an admin account will be automatically created with a random password. You can open up the logs for the Run Database Migration task after it is completed by clicking on the hook in the list, and scrolling down to the bottom of the logs for the password. You will need this to log in to the admin account initially.

Once completed, your new project is now live! You can use the Visit Site link on the left menu to visit the site. Congratulations on the launch!

Final thoughts

Now that the setup is complete, on subsequent pushes to your repository and branch, Cleavr will automatically deploy a new release of your website. As this is done atomically, you should have no downtime - the release process is run concurrently to the website, and is only switched over when it is confirmed working. If the release process fails, the current release is kept and your website remains working.

Since Cleavr configures your servers for performance, your website should be blazingly quick - for reference, this particular tutorial was done on a 1 CPU core, 2GB RAM VPS instance and the results were impressive - around 55ms response times for the public site, and around 90ms response times in the Backend. Cleavr allows multiple caching strategies to cater your particular application, so it's indeed possible even further performance increases can be achieved.

We hope you enjoyed this tutorial. If you have any suggestions or questions in relating to this article, join us on Discord and feel free to get in touch with the maintainer team and community on there.


Keep informed

Sign up to our newsletter and receive updates on Winter releases, new features in the works, plugin and theme promotions and much more!