Drupal CMS is installed on my MacBook Pro — primarily for checking the latest features rather than active development, and it had been left untouched for a while with updates piling up. Time to run those updates.
The installed version is a pre-release. As noted in earlier articles, Drupal CMS was released while still in development, meaning beta modules are in use — and as a result, errors and warnings show up in the admin panel.
Forced module deletions and other workarounds were applied to deal with those errors and warnings, leaving the Drupal CMS installation in a somewhat irregular state.
Drupal Core was still on 11.1.5, so the goal is to update to the current latest version, Drupal Core 11.2.2. Running an update via Composer, the process stalls at Drupal Core 11.1.8 — a dependency conflict prevents moving on to 11.2.0.
The update is blocked by dependency conflicts with modules that had irregular configurations applied. Attempting to update those modules to fix the dependency chain fails with errors and can't proceed.
After researching the options, a clean reinstall seems faster and more sensible in the long run than trying to repair the existing errors. The decision is made to delete the current Drupal CMS installation and start fresh.
The Drupal development environment on my MacBook Pro uses OrbStack and DDEV. Adding and removing projects like this is extremely straightforward — a useful reminder of the benefits of a Docker-based environment.
- The advantages of virtual machines and containers are starting to make more practical sense. It is easy to spin up separate LAMP environments with different specifications — different PHP versions, different DB versions, and so on.
- Being able to develop in environments with different specifications (different PHP versions, different DB versions, etc.) is a major benefit when building multiple websites running on different platforms.
Using these two applications, Drupal runs in the following configuration.
- A Linux virtual machine provided by OrbStack runs in the Mac local environment, operating as a container by default.
- DDEV is used on the Linux virtual machine to set up a LAMP environment optimized for Drupal, with Drupal installed inside it.
Introduction.
The local environment hadn't been run in a while, and the commands for DDEV, Composer, and Drush had largely been forgotten. Since the local environment doesn't have the SSH admin restrictions that apply to production, most of the work can be handled in VS Code. Having code review, directory structure inspection, and terminal access all in one place is genuinely efficient.
As an aside, the live Drupal site is managed through the Drupal admin panel and SSH rather than VS Code + Git. Since Drupal is a CMS where most work happens in the admin panel, managing it with VS Code and Git adds unnecessary overhead — so that combination isn't used for the production site.
For editor-based tasks like CSS changes, vi is used from the terminal. While the actual work is done in the terminal, when it helps to get a quick visual overview of file locations and directory structure, an SFTP client (Transmit, in this case) makes it easy to see the server layout in a GUI. sudo access beyond SSH is not granted, so file operations via SFTP aren't possible — but being able to see the server structure visually is still useful.
There are a number of advantages to using an SFTP client — something worth covering in a future article.
Work overview
- Update the installed Drupal CMS > Update fails to complete — decide to reinstall > Delete the existing Drupal CMS
- Try installing fresh Drupal CMS via the App > App installation runs into problems — give up > Delete the Drupal CMS installed via the App
- Install Drupal CMS with DDEV > Check and address errors
1. Deleting Drupal CMS
Forcing fixes for errors and warnings from development modules left the Drupal CMS with dependency problems among its modules. As a result, the update to Drupal Core 11.2.x isn't going through cleanly. Given the likely path ahead, deleting and reinstalling seems like the better outcome — so the existing Drupal CMS is removed.
Since Drupal CMS is also managed with DDEV, the deletion is handled using DDEV.
Deleting a Drupal Project with DDEV
Deleting a DDEV Drupal project means removing the web and DB containers DDEV manages. After the DDEV deletion, Drupal's configuration files remain in the directory — if the directory isn't needed, it can be safely removed entirely, so that gets deleted too.
// Delete the DDEV project
---
% ddev delete drupal-cms --omit-snapshot --yes
---
# ddev delete : delete the project
# drupal-cms : project directory
# --omit-snapshot : skip DB backup
# --yes : skip deletion confirmation
---
// Confirm DDEV projects
% ddev list
┌──────────┬────────────────────┬────────────┬───────────────────────────┬──────────┐
│ NAME │ STATUS │ LOCATION │ URL │ TYPE │
├──────────┼────────────────────┼────────────┼───────────────────────────┼──────────┤
│ dr-cv-tm │ stopped │ ~/dr-cv-tm │ │ drupal11 │
├──────────┼────────────────────┼────────────┼───────────────────────────┼──────────┤
│ dr103 │ stopped │ ~/dr103 │ │ drupal10 │
├──────────┼────────────────────┼────────────┼───────────────────────────┼──────────┤
│ dr11 │ stopped │ ~/dr11 │ │ drupal11 │
├──────────┼────────────────────┼────────────┼───────────────────────────┼──────────┤
│ Router │ OK │ ~/.ddev │ http://127.0.0.1:10999 │ │
└──────────┴────────────────────┴────────────┴───────────────────────────┴──────────┘
# drupal-cms has been deletedWith the DDEV project deletion complete, the directory can now be removed. Select the directory in Finder and choose "Move to Trash", then empty the Trash to delete it completely. To delete from the command line:
# Remove the Drupal CMS directory
% rm -rf drupal-cms
# Check the path to drupal-cms before running2. Installation via the Drupal-CMS Desktop App
Drupal CMS can also be installed via a desktop app, so this time that was tried.
- Download the desktop app (Apple Silicon).
- Extract the zip file.
- Move the desktop app to the Mac Applications directory.
- Launch the desktop app and install.
— and the installation is complete, surprisingly easily.
A problem appears when trying to log in to the admin panel after installation. The specified URL is localhost:8888, but accessing it in the browser shows an error.
The website encountered an unexpected error.
To track down the cause, the installation location is checked. Looking at the directories served by the local Apache setup — htdocs and similar paths — the drupal-cms directory is nowhere to be found.
Searching for drupal-cms in Finder was a surprise: the installation ended up in the Mac Documents directory. That simply isn't workable, so the first attempt at the Drupal-CMS Desktop App is abandoned, and the familiar approach of using DDEV and Composer is used instead.
The Drupal CMS installed via the App and the App itself are both no longer needed, so they get deleted. There are no particular dependencies, so selecting them in Finder and choosing "Move to Trash" is sufficient. That said, it is worth confirming that MySQL or Apache aren't still running before deleting — the following command checks for that.
% ps aux | grep drupal
s-takeda 28475 0.0 0.0 410724848 1440 s002 S+ 3:56AM 0:00.00 grep drupal
# Only the grep drupal process is shown — Drupal and MySQL are not running.3. Installing Drupal CMS
With the previous Drupal CMS deleted and the Desktop App removed as well, DDEV is used to install Drupal CMS.
Installing Drupal CMS with DDEV
Since it had been a while since DDEV was used to install Drupal on the MacBook, a quick review of DDEV usage is in order.
The basic unit in DDEV is the project directory. A .ddev folder is placed inside the directory to manage the project.
# Create and move into the project directory
% mkdir dcms-01 && cd dcms-01
---
# Configure the project
% ddev config --project-type=drupal11 --php-version=8.3 --docroot=web
# Project type: Drupal 11 — --project-type=drupal11
# PHP version: 8.3 — --php-version=8.3
# Set document root to the web directory — --docroot=web
# Normally the DB settings and other options need to be specified, but QuickInstall handles these defaults.
---
# Start DDEV
% ddev start
---
# Install Drupal CMS
% ddev composer create-project drupal/cms
# Uses Composer to install.
---
# Launch and configure Drupal
% ddev launch
# Drupal CMS launches — select a site type (Blog selected here)
# Enter email and password to log in to the Drupal CMS admin panel.
---That completes the DDEV Drupal CMS installation.
Checking the Installation Status
Running ddev describe shows the full configuration. Since this is a local environment, the DB password is db/db and root/root — on a production server, use a User/Pass that can't be guessed.
The setup includes web, db, and Mailpit (handy for testing local form mail) running as containers. One of the benefits of Docker is being able to set a different PHP version and DB version on a per-project basis.
# Check the installation status
% ddev describe
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Project: dcms-01 ~/dcms-01 https://dcms-01.ddev.site │
│ Docker platform: orbstack │
│ Router: traefik │
├──────────────┬──────┬──────────────────────────────────────────────────────────────────────────────┬────────────────────┤
│ SERVICE │ STAT │ URL/PORT │ INFO │
├──────────────┼──────┼──────────────────────────────────────────────────────────────────────────────┼────────────────────┤
│ web │ OK │ https://dcms-01.ddev.site │ drupal11 PHP 8.3 │
│ │ │ InDocker -> Host: │ Server: nginx-fpm │
│ │ │ - web:80 -> 127.0.0.1:32788 │ Docroot: 'web' │
│ │ │ - web:443 -> 127.0.0.1:32789 │ Perf mode: mutagen │
│ │ │ - web:8025 -> 127.0.0.1:32790 │ Node.js: 22 │
├──────────────┼──────┼──────────────────────────────────────────────────────────────────────────────┼────────────────────┤
│ db │ OK │ InDocker -> Host: │ mariadb:10.11 │
│ │ │ - db:3306 -> 127.0.0.1:32791 │ User/Pass: 'db/db' │
│ │ │ │ or 'root/root' │
├──────────────┼──────┼──────────────────────────────────────────────────────────────────────────────┼────────────────────┤
│ Mailpit │ │ Mailpit: https://dcms-01.ddev.site:8026 │ │
│ │ │ Launch: ddev mailpit │ │
├──────────────┼──────┼──────────────────────────────────────────────────────────────────────────────┼────────────────────┤
│ Project URLs │ │ https://dcms-01.ddev.site, https://127.0.0.1:32789, │ │
│ │ │ http://dcms-01.ddev.site, http://127.0.0.1:32788 │ │
└──────────────┴──────┴──────────────────────────────────────────────────────────────────────────────┴────────────────────┘
The language is set to English by default, so it needs to be switched to Japanese.
Installing Translations with Drush
The default language under Language settings at /admin/config/regional/language is English. Japanese is added and set as the default — but even after selecting Japanese there, the admin panel doesn't immediately switch and stays entirely in English. Using Drush to push through all the translations at once switches the admin panel to Japanese.
# List projects with available translation updates
% ddev drush locale:check
---
# Download and import translation files
% ddev drush locale:update
---
# Clear cache
% ddev drush cr
--- That switches the admin panel from English to Japanese.
Thinking through the errors
The Drupal Core in this freshly installed Drupal CMS is the latest version, 11.2.2. Modules are also at their latest versions, but some development modules installed in the core are generating errors and warnings.
These errors and warnings from the development modules are officially recognized by Drupal. (The errors and warnings can essentially be ignored.) The root cause of the automatic_updates and package_manager errors and warnings that caused so much trouble last time turns out to be that Drupal itself had officially acknowledged those errors and warnings — and the whole saga was a result of fighting to suppress what should have been left alone.
Drupal CMS is evolving to broaden its reach — moving away from the traditional image of Drupal as a developer-focused CMS and toward something accessible to general users, like WordPress.
The interface is being refined, a full GUI workflow, pre-packaged distributions for different purposes, and a more user-friendly CMS overall are all in the works — the system is mid-transformation, and the experimental modules released as part of that process are what's generating these errors and warnings.
Features like one-click module and theme downloads from the admin panel, automatic installation, and automatic updates via cron — so users never have to think about the underlying system — are being implemented. The errors and warnings are a side effect of that work being in progress.
# Error
Package Manager
Package Manager is available for early testing. To install the module set the value of 'testing_package_manager' to TRUE in your settings.php file.
# Warning
Experimental modules installed
Experimental modules found: Navigation, Package Manager. Experimental modules are provided for testing purposes only. Use them at your own risk.

Drupal CMS
When the Project Browser GUI enables module and theme searching, and Package Manager enables one-click installation and updates from the GUI, the experience will match what WordPress offers for themes and plugins.
That creates the potential for a third-party marketplace to form. Excellent modules and themes could command a price — and as development advances and the user base grows, a positive cycle of Drupal adoption becomes possible.
For developers, this is the growing pains of adapting to an interface that's different from what they've known. The experimental modules distributed as part of that transition are what was stumbled into — and the whole episode of fighting errors that should have been left alone starts to make sense. It's a straightforward story once the context is clear.
There is a tendency to update immediately and fix issues right away — that impatience applies to both updates and bugs. For large-scale updates like this one, where the system itself is changing, some patience and observation is probably the wiser approach. This turned out to be a useful reminder of that.
Changing settings.php Permissions
Home > Administration > Reports > Status report
Protection disabled
The file sites/default/settings.php is not protected against modifications and poses a security risk. Change the file permissions to prevent write access.
Since this is a local environment, it can generally be ignored — but it's a standard Drupal installation routine, so it gets addressed here. On a production server, this must always be done.
This error is a permissions issue with settings.php. At the time of Drupal installation, settings.php is set to 644 — the permissions need to be changed to 444 (read-only). Normally the following commands resolve it.
$ cd web
$ chmod 444 sites/default/settings.php
Let's apply the change.
Changing Permissions
Commands are entered from iTerm to change the permissions.
DDEV Structure
DDEV runs in containers. The structure is as follows.
|-ddev-dcms-01
| |-db
| |-web
|
|-ddev-router
| |-ddev-router
|
|-ddev-ssh-agent
|-ddev-ssh-agentThe settings.php that needs its permissions changed is not in the dcms-01/web directory shown in the Mac terminal — it's in the OrbStack container ddev-dcms-o1/web. To change the permissions of that settings.php, SSH access to the ddev-dcms-o1/web container is needed. SSH into a container is done using DDEV's ssh command.
SSH into the Container with DDEV
Use DDEV SSH to log into the container and change the settings.php permissions.
# Log in to the container using DDEV SSH.
% ddev ssh
---
# Check the directory structure
$ cd web/sites/default
$ ls -al
# settings.php permissions are currently set to read/write.
-rw--r--r--- 1 s-takeda dialout 36727 Dec 7 18:37 settings.php
---
# Change the permissions.
$ chmod 444 settings.php
# Confirm the change.
$ ls -al
// Now set to read-only (444).
-r--r--r-- 1 s-takeda dialout 36727 Dec 7 18:37 settings.php
---
# Clear the cache.
$ drush cr
[success] Cache rebuild complete.
---
# Exit SSH
$ exit
---
# Note: When working from the Mac terminal, prefix commands with ddev because of the path;
# inside the container, ddev is not needed.
# Mac terminal
% ddev drush cr
# Inside the OrbStack container
$ drush crSSH into the DDEV container, changed the permissions on web:/var/www/html/web/sites/default/settings.php from read/write to read-only, and resolved the "Protection disabled" warning.
Checking Errors in the Admin Console
Home > Administration > Reports > Status report
1 error, 1 warning, 29 checked
There is 1 error and 1 warning from the development modules, but the update completed without issue.
Conclude.
Drupal CMS was released in December 2024, and six months have now passed. A little more time is needed before using it in a production environment. From the pre-release state, it has evolved considerably over those six months. The admin panel felt unfamiliar at first, but taking time this round to go through each feature and its placement reveals an interface that has become genuinely polished.
Having worked with Drupal for less than a year, there is still a lot to understand — but compared to WordPress, the points where Drupal excels and where it suits me personally are numerous. Contrary to the general assessment, the strictness of Drupal's structure and rules is the main reason I use it.
That strictness brings to mind something from about thirty years ago — the era of PC-UNIX, when UNIX was ported to personal computers and became practically usable, which led to the emergence and spread of Linux and FreeBSD. Looking back now, Linux spread overwhelmingly while FreeBSD never quite matched that adoption.
At the time, the engineers around me were using Linux (Red Hat-based) almost universally, and FreeBSD was clearly the minority. The reasoning made sense — Red Hat-based distributions had the largest user base, established methods, and had secured their position as the industry standard. My preference, though, was FreeBSD.
The reason was that its structure and rules were rigorously enforced, making it easy to know where everything lived. On the lean hardware of the time, stripping out unnecessary components — removing drivers and so on — to build a light system was a practical need, and FreeBSD was well suited to that purpose.
Drupal's philosophy feels, in some ways, close to what FreeBSD stood for at the time — and that's the main reason I use it.
The hope is that this release of Drupal CMS will carry forward the best of what Drupal has always been while opening the door to a wider audience.
(Tentative) Drupal Security Management
This article was originally planned to also cover Drupal security management, but that content has been moved to a separate article. Since it deals with security-related topics, deciding how much to cover in a public article is a challenge worth thinking through carefully.