New greener region discount. Save 3% on Upsun resource usage. Learn how.
LoginFree trial
FeaturesPricingBlogAbout us
Blog

Is Upsun a match for modern Drupal development?

DrupalGitGitOpsUpsunifyCLI
19 March 2024
Marine Gandy
Marine Gandy
DevRel Engineer

So you have a Drupal website and you’re wondering if Upsun is a good fit for you. The short answer is: yes, of course! But let’s dig a little deeper and get acquainted with how to get the smoothest experience possible hosting your Drupal applications with us. 

I’m not going to detail how to modify your application to run on Upsun in this post (what we call “upsunifying” your apps), only highlighting some features that I think matter in particular when it comes to Drupal. But we do have a very handy getting started guide and onboarding upsunify guide for you to explore—and you can always take advantage of our free trial to experiment. 

A simple, Git-based workflow

The first thing to understand is that Upsun leverages both Infrastructure-as-Code (IaC) and GitOps to manage and deploy applications. More specifically, we use YAML files to define your application's infrastructure needs: runtime version, memory and storage requirements, and extra services like databases. 

With Git as the single source of truth, any change in both application and infrastructure is just a commit away, and deploying becomes a simple matter of merging into your main branch. This workflow is great for tracking changes, making it easy to test but also rollback if needed—after all, it’s only a matter of git revert.

Now, you might be thinking, “Uh oh, are they saying that I need to commit everything, even my vendors?” Let me reassure you right away: no, we are not monsters! Our job is to make your life easy, that’s why Upsun assumes that your build flavor will be Composer, so simply commit your composer.json and composer.lock files and let us worry about the rest.

Once your application is built, the filesystem will be read-only, ensuring that the only thing altering your code will be your next commit. “But wait,  how am I supposed to handle user-uploaded media if I can’t write on the filesystem?” Worry not my friend, we have you covered, simply define mounts for the folders you need write access to, and you’re good to go. For example, with Drupal, you might want to define several mounts for media, cache, logs, and more.  

Take a look at this excerpt of the .upsun/config.yaml file for an example of the mounts that Drupal requires:

applications:
  drupal-app:
    mounts:
      # The default Drupal files directory.
      '/web/sites/default/files':
        source: "storage"
        source_path: 'files'
      # Drupal gets its own dedicated tmp directory.
      '/tmp':
        source: tmp
        source_path: 'tmp'
      # Private file uploads are stored outside the web root.
      '/private':
        source: "storage"
        source_path: 'private'
      # Drush needs a scratch space for its own caches.
      '/.drush':
        source: "storage"
        source_path: 'drush'
      # Drush will try to save backups to this directory, so it must be
      # writeable even though you will almost never need to use it.
      '/drush-backups':
        source: "storage"
        source_path: 'drush-backups'

 

How to commit to production 

By now, you may be worried about your Drupal config files. After all, you might make changes in production and want to commit these. The standard flow here is pretty simple:

1. Create a new environment from the environment you modified, for example, your production environment. This is easy peasy with our Upsun CLI    

upsun environment:branch [new-branch-name]

 

Note: upsun branch is an alias you can use for upsun environment:branch

Upsun will then work its magic and provide you with a new preview environment, complete with a byte-for-byte copy of the parent’s data. It means that any code that you change now will be applied to the same context as the parent, so if your CI/CD tests are green, you can deploy.

2. Pull your newly created environment locally and do what you have to do

To work locally, we suggest you use DDEV, as it is the preferred option for Drupal, and because we are proud to have DDEV maintainer Randy Fay on our team. To find out more information on this, you can follow our install docs or DDEV’s install docs

Please note: we have a dedicated DDEV integration for Platform.sh to make things even smoother. Coming soon on Upsun!

Long story short, once you have DDEV installed and configured, you can switch to the new branch and pull the data in two commands as shown below:

upsun checkout [new-branch-name]
ddev pull upsun

And that’s it! You now have your identical local environment up and running and you can do everything you need using ddev drush (yes, you’ll probably need to start with ddev drush cr anyway). Time to export, commit, push, and open a pull request (PR).

3. A new preview environment will be created for your PR, allowing you to review the result before you merge—or should I say, deploy! 

All in all, this is a standard flow for our GitOps approach, as anything that is not versioned would be lost at the next deployment—especially if you use our build and deploy hooks to automate boring tasks, like importing configs or clearing the cache.

Take a look at this excerpt of the .upsun/config.yaml file, particularly within the deploy section, which has some comments and action examples that you can perform using our deploy hook:

# Hooks allow you to customize your code/environment as the project moves through the build and deploy stages
# More information: https://docs.upsun.com/create-apps/app-reference.html#hooks
hooks:
  deploy: |
    set -eux
    cd web
    bash $PLATFORM_APP_DIR/drush/platformsh_deploy_drupal.sh

Below you can take a look at the content of the drush/platformsh_deploy_drupal.sh file which was called in the previous code section: 

    #!/usr/bin/env bash
#
# We don't want to run drush commands if drupal isn't installed.
# Similarly, we don't want to attempt to run config-import if there aren't any config files to import
# @todo expand further to pass --uri for all sites, with an eye towards multisite
if [ -n "$(drush status --field=bootstrap)" ]; then
  drush -y cache-rebuild
  drush -y updatedb
  if [ -n "$(ls $(drush php:eval "echo realpath(Drupal\Core\Site\Settings::get('config_sync_directory'));")/*.yml 2>/dev/null)" ]; then
    drush -y config-import
  else
    echo "No config to import. Skipping."
  fi
else
  echo "Drupal not installed. Skipping standard Drupal deploy steps"
fi

A little extra tip for you: you can use drush on your Upsun environments very easily if you need to (drush uli, anyone?), thanks to our CLI command upsun drush. See? We’ve always had Drupal sites in mind.

In my next post, we’ll go a little further and see how you can export Drupal content and more importantly how you can automate these exports. You can check our Platform.sh Drupal 10 template or browse the awesome-platformsh repo for inspiration. Finally, don’t hesitate to ask questions or share your Drupal tips on our community site!

Upsun Logo
Join the community