Drupal Hosting Requirements: What to Check Before You Buy

Drupal hosting requirements come down to five things: a PHP release Drupal still supports, with the extensions its installer checks for; MySQL, MariaDB, PostgreSQL or SQLite; a web server that rewrites URLs; command-line access for Composer and Drush; and enough PHP memory for logged-in editors, who cost far more to serve than anonymous visitors.

The first three come straight from drupal.org, along with a memory minimum. The rest is practical, not official. It decides whether an inexpensive plan works. A plan can meet the official requirements and still fail the practical ones, which is how a site that installed cleanly in ten minutes becomes a site nobody can update six months later.

Drupal Hosting Requirements, Straight From drupal.org

The project publishes its system requirements and revises them with each major release. Use that page for version numbers. Any figure printed here would be wrong within a release or two, because each major version of Drupal raises its PHP floor and drops older database versions.

PHP comes first. You want a host that lets you pick the PHP branch per site and switch it yourself, because a Drupal major upgrade usually needs a newer PHP than the release before it, and the safe order is to move PHP first and Drupal second. The installer checks for a set of extensions before it lets you continue. GD, which image styles depend on, and the PDO driver for your database are the two most likely to be missing on a bare configuration. OPcache is not strictly required, but an uncached Drupal request loads a great many PHP files, and the status report warns when it is off.

For the database, MySQL or MariaDB is the ordinary choice on shared hosting, and PostgreSQL works where a host offers it. SQLite is supported too. I would keep it on your laptop. The whole database is one file, and a write locks all of it, so two editors saving at the same moment queue behind each other.

One MySQL detail is worth checking once the site is up. The status report at /admin/reports/status warns when the transaction isolation level is REPEATABLE READ and recommends READ COMMITTED, which cuts down on deadlocks when several writes land together. The fix goes in the database array in settings.php, not in the server configuration, so shared hosting is no obstacle.

Then the web server. Clean URLs (/about rather than /index.php/about) need rewriting: on Apache, mod_rewrite reading the .htaccess file Drupal ships, and on Nginx, a server block somebody has written for Drupal, since Nginx ignores .htaccess entirely.

One requirement sits outside that list, and it is the one that catches people on shared hosting. A Composer-built Drupal site keeps its public code in a web/ subdirectory, with vendor/ and your exported configuration one level above it, where no browser can reach them. The domain has to point at web/, not at the top of the project. Ask whether you can set a domain's document root to a subfolder before you pay.

Can You Run Drupal Without a Command Line?

For a few months, perhaps.

WordPress can be installed and updated entirely from a browser, which is why our post on what WordPress hosting actually needs never asks you to open a shell. Current Drupal is different. It is built and updated with Composer, PHP's dependency manager. A new site starts like this:

bash composer create-project drupal/recommended-project mysite

And a routine core update looks like this:

bash composer update "drupal/core-*" --with-all-dependencies drush updatedb drush cache:rebuild

drupal.org still offers a downloadable archive of core. That works until you add a contributed module that declares dependencies of its own, and from then on Composer is the only practical way to resolve them. Drush is the other half of the toolkit: it applies database updates, imports configuration, rebuilds caches and runs cron, all from a shell, where the browser versions of those jobs are slower or missing.

Most owners without SSH end up in the same place. They run Composer on their own laptop, then upload the entire project, vendor/ included, over FTP. It works. It also turns every security release into a local build followed by an upload of thousands of small files, and a transfer that dies halfway leaves the live site running a mix of old and new code. The laptop's PHP version quietly decides which package versions get installed, too, which is a fine way to deploy code the server cannot run.

My view: if a plan has no SSH access, do not put Drupal on it. Buy a different plan. That usually rules out free hosting, since free tiers seldom include a shell, and it is one of the practical reasons the case for paid hosting is stronger for a Drupal site than for most.

Once you have a shell, run php -v and compare the answer with the PHP version on the status report. On some shared hosts the command-line PHP is a different, older binary than the one serving web requests, and Composer will then resolve packages for the wrong version. Calling a specific binary by its full path fixes it, and your host's documentation should say which one.

Memory Is Set by Your Editors, Not Your Visitors

An anonymous visitor to a well-configured Drupal site barely touches PHP. The Internal Page Cache module stores the finished page for anonymous users and hands it back without rebuilding anything.

Logged-in users never get that. Dynamic Page Cache and the render cache help them by storing the parts of a page that do not change from one user to the next. But an editor saving content, a site builder working in the Views UI, a module install and a configuration import all run with those caches partly or wholly out of the picture. Those are the requests that set your memory floor.

The PHP requirements page on drupal.org gives the minimum memory_limit. Treat it as the floor for a bare install, not a target for a real site running a few dozen contributed modules.

When the limit runs out, PHP stops in the middle of the request and writes a fatal error to the log:

text PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 262144 bytes)

The first number is your limit in bytes. The browser gets Drupal's generic "The website encountered an unexpected error" page, or a blank one. It shows up on admin pages first.

Caching does not rescue a cache rebuild. drush cache:rebuild empties every cache bin, and the next requests rebuild the service container and every cached render from nothing, which makes it the heaviest thing a routine Drupal site does. If it runs out of memory from the shell, the limit to raise is the command-line one, which is often configured separately from the web limit. That limit governs composer update too, and Composer resolves the whole dependency tree in memory.

Raising the limit is the right fix when the error appears on admin pages. If it appears on anonymous front-end pages, something is bypassing the page cache, and more memory will only hide it until traffic grows.

If the Installer Stops at settings.php

The installer needs to write two things: sites/default/settings.php, which it creates from default.settings.php, and the public files directory at sites/default/files. If either is not writable by the user PHP runs as, the installer halts on its requirements screen and names the path.

After installation, reverse it. The status report complains, under Configuration files, if sites/default and settings.php are still writable:

bash chmod 555 web/sites/default chmod 444 web/sites/default/settings.php

Public files are served straight from disk at a URL anyone can guess. Drupal writes an .htaccess into that directory to stop uploaded files running as scripts, which does nothing on Nginx. By default it also keeps compiled Twig templates under sites/default/files/php, so the public directory holds generated PHP as well as uploads.

Private files are for anything Drupal should check permissions on before a download, such as invoices or member documents. Set the path in settings.php:

php $settings['file_private_path'] = '../private'; $settings['config_sync_directory'] = '../config/sync';

Relative paths resolve from the web root, so ../private lands beside web/, where no URL maps to it at all. Drupal will write a deny-all .htaccess into a private directory placed inside the web root, but that file means nothing on Nginx, or after somebody changes the server configuration a year from now. Exported configuration belongs outside for the same reason, since it describes the entire site.

The last warning nearly every new install shows is Trusted Host Settings. Set $settings['trusted_host_patterns'] to a pattern such as '^www\.example\.com$', and Drupal will refuse requests that arrive with some other host name.

Shared, Semi-Dedicated or a VPS?

For Drupal, the deciding number is how many people are logged in at once.

A brochure site, or a small organization site with one or two editors and mostly anonymous traffic, sits comfortably on shared hosting, because the page cache answers nearly every request. The strain arrives with logged-in users, whether that is a membership site or a newsroom with several editors working through the day. Each of those requests runs PHP for real, and on shared hosting they compete with every other request on your account for a limited pool of concurrent processes.

Semi-dedicated is the next step when the application is still ordinary PHP and MySQL but the logged-in load has grown, and our comparison of semi-dedicated and VPS hosting covers what actually changes on the machine. A VPS becomes the answer when Drupal needs software a shared environment does not run, such as Apache Solr for search or a queue worker that has to run around the clock. A Drupal Commerce store adds the checkout concerns in our guide to hosting requirements for an online store.

Your Drupal site Sensible tier What gives out first
Brochure or small organization site, one or two editors Shared Memory on admin pages and cache rebuilds
Content site with several editors through the day Semi-dedicated Concurrent PHP processes when editors and crawlers overlap
Membership site or intranet where most users log in Semi-dedicated or VPS Uncached authenticated requests
Site that needs Solr, queue workers or custom server software VPS Root access, which shared tiers do not give

BestPaidHosting's Drupal hosting plans run on the Hepsia control panel rather than cPanel, so where a Drupal tutorial shows a cPanel screen for picking a PHP version or adding a cron job, look for the Hepsia equivalent instead. The plan page carries the current specifications.

What to Do Next

Before you order anything, get four answers from the host:

  1. Can I log in over SSH, and does the command-line PHP match the web PHP?
  2. Can I point a domain at a subfolder, so the document root is web/?
  3. Can I choose the PHP version per site, and switch it back?
  4. Is there a scheduler that can run drush cron on an interval I set? Otherwise Drupal falls back to its Automated Cron module, which only runs when someone visits.

A plan with four yes answers has what Drupal needs from a host, and plan size can wait until you know how many people log in. If this site is part of getting a business online for the first time, the order that actually works puts the domain and email ahead of the hosting purchase. Settle those first.

Leave a Comment

Your email address will not be published. Required fields are marked *