After launching this site on AWS, I hadn't touched the Drupal local environment on my Mac — but I fired up Drupal via OrbStack > DDEV for the first time in a while to check on the Bootstrap5 and CivicTheme projects installed locally.
OrbStack and DDEV were covered in earlier articles, but here's a quick refresher.
- OrbStack is a Linux virtual machine that runs locally on Mac and can be used as Docker.
- From the OrbStack website: "OrbStack is a fast, light, and simple drop-in replacement for Docker Desktop on macOS. It runs containers and Linux machines."
- DDEV is a tool for building LAMP and Node.js local environments, bringing Docker workflows to a local setup.
- DDEV is for local builds, so for container use on a VPS, Docker or Kubernetes configuration would be done in OrbStack. In my setup I'm just running CMS platforms like Drupal and WordPress as an individual, so I don't use collaborative development tools like Docker or Git.
- I do use Git occasionally, but I haven't used containers yet — something I'd like to try when the opportunity comes.
Using these two applications, Drupal runs as follows:
- Run the Linux virtual machine provided by OrbStack in the Mac local environment — runs as a container by default
- Use DDEV on the Linux virtual machine to set up a LAMP environment (optimized for Drupal) and install Drupal
Introduction.
Since it's been a while since I ran the local environment, there are several updates to apply — DDEV, Composer, Drush, Drupal Core, themes, and modules. The setup below is the local environment I introduced in #C01. OrbStack is used via GUI, so update notifications appear on launch and the latest version installs by following the prompts.
There were also numerous updates for Vscord and its installed extensions, but since those complete within Vscord itself, the steps are omitted here.
MacBook Pro M1 (2021) / macOS Sequoia 15.1.1
- Terminal: iTerm 3.5.10 > Shell: Mac default Zch
- Package manager: Homebrew 4.3.22
- Local server (required to run Drupal on Mac): OrbStack Pro V1.8.2
- Local Docker environment: DDEV v1.23.4 > updated to 1.24.0
- PHP 8.3.10
- MariaDB 10.11.8
- Composer Version 2.7.9 > updated to 2.8.3
- Drupal Core 11.0.4 > updated to 11.0.9 / Bootstrap5 Theme
- Drupal Core 10.0.3 > updated to 10.3.10 / Civic Theme
- Bootstrap5 4.03
- Civic Theme 1.8.1 > updated to 1.9.0
Editor: Vscord 1.93.1 > 1.95.3
- GitHub Copilot 1.229.0 > 1.248.0 Vscord extension
- Japanese Language Pack 1.93 > 1.95 Vscord extension
- PHP Debag 1.35.0 Vscord extension
- Remote SSH 0.114.3 > 0.115.1 Vscord extension
- SSH: Editing Configuration Files 0.86.0 > 0.87.0 Vscord extension
- Remote Explorer 0.4.3 Vscord extension
- Vim 1.28.1 > 1.29.0 Vscord extension
As of Friday, December 6, 2024. This round covered DDEV, Composer, Drupal Core, and module/theme updates. A backlog had piled up from not starting it in a while.
My Drupal site-building workflow in the local environment:
- Launch OrbStack from the Mac GUI
- Launch iTerm and navigate to the Drupal project directory: $ cd drupal11-bootstrap5[project-name]
- Start DDEV: $ ddev start — the virtual server starts and Drupal becomes available
- Access the Drupal site at https://drupal11-bootstrap5[project-name].site
- Log in to the Drupal Admin console
- Build the site in the Admin console
The updates this time are done using Homebrew and Composer in iTerm.
The local Drupal environment is used for testing modules before installation, checking for version dependency issues, testing features like content types and Views, reviewing configurations, and roughing out the site design. Once a setup is reasonably complete, a matching environment is created on the production server and work continues there.
The reason I'm running the local environment this time is to set up a test environment for upgrading the currently live 10.3.x site to the 11.x series. The site design was also thrown together in a hurry, so I want to think about making it more readable — the local environment will also serve as a design sandbox.
Let's get into the updates.
On terminal prompt notation
- The % prompt in terminal output is because the shell I normally use in iTerm is macOS's default Zsh. All terminal commands for the Mac environment use % as the prompt.
- Later in the article I log into an OrbStack container — OrbStack containers run Linux with Bash, so the prompt switches to $. All terminal commands for the Linux environment use $ as the prompt.
- Terminal commands in other articles are mostly for Lightsail and Bitnami work, where the default shell is Bash, so those also use $ as the prompt.
1.DDEV 1.23.4 > 1.24.0
Updated DDEV from 1.23.4 to 1.24.0. The update uses Homebrew — just a version check and an update command.
1-1. Updating DDEV
DDEV is updated using Homebrew.
// Check current version
% DDEV --version
ddev version v1.23.4
---
// Update to latest version
% brew upgrade ddev/ddev/ddev
---
==> Auto-updating Homebrew...
Adjust how often this is run with HOMEBREW_AUTO_UPDATE_SECS or disable with
HOMEBREW_NO_AUTO_UPDATE. Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> Downloading https://ghcr.io/v2/homebrew/portable-ruby/portable-ruby/blobs/sha256:303bed4c7fc431a685db3c3c151d873740114adbdccd23762ea2d1e39ea78f47
######################################################################### 100.0%
==> Pouring portable-ruby-3.3.6.arm64_big_sur.bottle.tar.gz
==> Auto-updated Homebrew!
Updated 4 taps (homebrew/services, ddev/ddev, homebrew/core and homebrew/cask).
==> New Formulae
action-docs fltk@1.3 php@8.3
afl++ foot pie
--- Done ---
// Check version
---
% DDEV --version
ddev version v1.24.0
---
// Updated to latest version v1.24.0
---2.DrupalCore11x / Bootstrap5
Checking the update status for Drupal Core 11.x and Bootstrap5 Theme installed in the OrbStack > DDEV environment and applying updates. The following updates are being applied:
- Composer 2.7.9 > 2.8.3
- Drush 13.1.1 > 13.3.3
- Drupal Core 11.0.4 > 11.0.9
- Bread Crumb 2.0.8 > 2.0.9
Updating Composer from 2.7.9 to 2.8.3.
2-1. Updating Composer
Composer is updated using the Composer self-update command.
// Check current version
% composer --version
Composer version 2.7.9 2024-9-04 12:34:56
---
// Update to latest version
% composer self-update
---
// Confirm the update
% composer --version
Composer version 2.8.3 2024-11-17 13:13:04
PHP version 8.4.1 (/opt/homebrew/Cellar/php/8.4.1_1/bin/php)
Run the "diagnose" command to get more detailed diagnostics output.
// Updated to 2.8.3
---
// To view Composer overview and available commands, run:
% composer -v
---
______
/ ____/___ ____ ___ ____ ____ ________ _____
/ / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
/_/
Composer version 2.8.3 2024-11-17 13:13:04
Usage:
command [options] [arguments]
Options:
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
--profile Display timing and memory usage information
--no-plugins Whether to disable plugins.
--no-scripts Skips the execution of all scripts defined in composer.json file.
-d, --working-dir=WORKING-DIR If specified, use the given directory as working directory.
--no-cache Prevent use of the cache
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
about Shows a short information about Composer
archive Creates an archive of this composer package
audit Checks for security vulnerability advisories for installed packages
browse [home] Opens the package's repository URL or homepage in your browser
bump Increases the lower limit of your composer.json requirements to the currently installed versions
check-platform-reqs Check that platform requirements are satisfied
clear-cache [clearcache|cc] Clears composer's internal package cache
completion Dump the shell completion script
config Sets config options
create-project Creates new project from a package into given directory
depends [why] Shows which packages cause the given package to be installed
diagnose Diagnoses the system to identify common errors
dump-autoload [dumpautoload] Dumps the autoloader
exec Executes a vendored binary/script
fund Discover how to help fund the maintenance of your dependencies
global Allows running commands in the global composer dir ($COMPOSER_HOME)
help Display help for a command
init Creates a basic composer.json file in current directory
install [i] Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json
licenses Shows information about licenses of dependencies
list List commands
outdated Shows a list of installed packages that have updates available, including their latest version
prohibits [why-not] Shows which packages prevent the given package from being installed
reinstall Uninstalls and reinstalls the given package names
remove [rm|uninstall] Removes a package from the require or require-dev
require [r] Adds required packages to your composer.json and installs them
run-script [run] Runs the scripts defined in composer.json
search Searches for packages
self-update [selfupdate] Updates composer.phar to the latest version
show [info] Shows information about packages
status Shows a list of locally modified packages
suggests Shows package suggestions
update [u|upgrade] Updates your dependencies to the latest version according to composer.json, and updates the composer.lock file
validate Validates a composer.json and composer.lock
---The output shows an overview and options for the [create-project] and [update] commands used to install and update Drupal Core and modules.
Updating Drush from 13.1.1 to 13.3.3.
2-2. Updating Drush
Drush is updated using Composer's require command with the --update-with-all-dependencies option.
// Check current version
% ddev drush --version
Drush Commandline Tool 13.1.1.0
---
// Update to latest version
% composer require drush/drush:^13 --update-with-all-dependencies
---
./composer.json has been updated
Running composer update drush/drush --with-all-dependencies
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 15 updates, 0 removals
- Upgrading chi-teck/drupal-code-generator (4.0.0 => 4.1.0)
- Upgrading consolidation/config (3.0.0 => 3.1.0)
- Upgrading consolidation/output-formatters (4.5.0 => 4.6.0)
- Upgrading consolidation/robo (5.0.0 => 5.1.0)
- Upgrading drush/drush (13.1.1 => 13.3.3)
- Upgrading grasmash/expander (3.0.0 => 3.0.1)
- Upgrading illuminate/collections (v11.23.5 => v11.34.2)
---中略---
- Upgrading chi-teck/drupal-code-generator (4.0.0 => 4.1.0): Extracting archive
- Upgrading drush/drush (13.1.1 => 13.3.3): Extracting archive
Generating autoload files
43 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
--- Done ---
---
// Confirm the update
% ddev drush --version
Drush Commandline Tool 13.3.3.0
// Updated to latest version 13.3.3.0
---
// Commonly used Drush commands include:
$ drush updatedb
$ drush cache:rebuild
// — used after installs and updates for cache clearing and DB updates, but Drush also has
// shell-like functionality. Combining commands and options allows bash-like use —
// for example, listing Views at a glance:
---
% ddev drush views:list --fields=machine-name,status
------------------------- ----------
Machine name Status
------------------------- ----------
block_content Enabled
comment Enabled
comments_recent Enabled
content Enabled
content_recent Enabled
files Enabled
frontpage Enabled
list_footer Enabled
taxonomy_term Enabled
term_list Enabled
test Enabled
user_admin_people Enabled
vews_life_style_article Enabled
views_post78 Enabled
watchdog Enabled
who_s_new Enabled
who_s_online Enabled
archive Disabled
glossary Disabled
------------------------- ----------
Updating Drupal Core from 11.0.4 to 11.0.9.
2-3. Updating Drupal Core
Drupal Core is updated using Composer's update command with the --with-all-dependencies option.
// Check current version
% ddev drush core:status --field=drupal-version
11.0.4
---
// Update to latest version
---
# Clear cache
% ddev drush cache:rebuild
[success] Cache rebuild complete.
---
# Update
% ddev composer update "drupal/core-*" --with-all-dependencies
---
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 27 updates, 0 removals
- Upgrading composer/semver (3.4.2 => 3.4.3)
- Upgrading drupal/core (11.0.4 => 11.0.9)
- Upgrading drupal/core-composer-scaffold (11.0.4 => 11.0.9)
- Upgrading drupal/core-project-message (11.0.4 => 11.0.9)
- Upgrading drupal/core-recommended (11.0.4 => 11.0.9)
--- Output abbreviated below ---
--- Done ---
// Clear cache and update database
% drush updatedb
[success] No pending updates.
% drush cache:rebuild
[success] Cache rebuild complete.
---
// Confirm the update
% ddev drush core:status --field=drupal-version
11.0.9
// Updated to 11.0.9
---
// Use core:status to confirm the update status
---
% ddev drush core:status
---
Drupal version : 11.0.9
Site URI : https://drupal11-bootstrap5.ddev.site
DB driver : mysql
DB hostname : db01test
DB port : 3306
DB username : db01test
DB name : db
Database : Connected
Drupal bootstrap : Successful
Default theme : b5subtheme
Admin theme : claro
PHP binary : /usr/bin/php8.3
PHP config : /etc/php/8.3/cli/php.ini
PHP OS : Linux
PHP version : 8.3.14
Drush script : /var/www/html/vendor/bin/drush.php
Drush version : 13.3.3.0
Drush temp : /tmp
Drush configs : /var/www/html/vendor/drush/drush/drush.yml
Install profile : standard
Drupal root : /var/www/html/web
Site path : sites/default
Files, Public : sites/default/files
Files, Temp : /tmp
Updating Bread Crumb from 2.0.8 to 2.0.9.
2-4. Updating Bread Crumb
Bread Crumb is updated the same way as Drupal Core — using Composer's update command with the --with-all-dependencies option.
// Check current version
% ddev composer show drupal/easy_breadcrumb
---
name : drupal/easy_breadcrumb
descrip. : Adds configuration to the system breadcrumbs.
keywords :
versions : * 2.0.8
type : drupal-module
license : GNU General Public License v2.0 or later (GPL-2.0-or-later) (OSI approved) https://spdx.org/licenses/GPL-2.0-or-later.html#licenseText
homepage : https://www.drupal.org/project/easy_breadcrumb
source : [git] https://git.drupalcode.org/project/easy_breadcrumb.git 2.0.8
dist : [zip] https://ftp.drupal.org/files/projects/easy_breadcrumb-2.0.8.zip 2.0.8
path : /var/www/html/web/modules/contrib/easy_breadcrumb
names : drupal/easy_breadcrumb
support
source : https://git.drupalcode.org/project/easy_breadcrumb
issues : https://www.drupal.org/project/issues/easy_breadcrumb
---
// Update to latest version
---
# Clear cache
% ddev drush cache:rebuild
[success] Cache rebuild complete.
---
# Update
% ddev composer update drupal/easy_breadcrumb --with-all-dependencies
---
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 10 updates, 0 removals
- Upgrading drupal/easy_breadcrumb (2.0.8 => 2.0.9)
- Upgrading symfony/dependency-injection (v6.4.15 => v6.4.16)
---
--- Output abbreviated below ---
--- Done ---
// Clear cache and update database
---
% ddev drush updatedb
[success] No pending updates.
% ddev drush cache:rebuild
[success] Cache rebuild complete.
---
// Confirm the update
% ddev drush pm:list
---
--------------------- ---------------------------------- ---------- ----------
Package Name Status Version
--------------------- ---------------------------------- ---------- ----------
Core Announcements Enabled 11.0.9
(announcements_feed)
Core Automated Cron (automated_cron) Enabled 11.0.9
~~~ 中略 ~~~
Navigation Easy Breadcrumb Enabled 2.0.9
(easy_breadcrumb)
---
// Updated to latest version 2.0.9Updates for the Drupal Core 11.0.9 / Bootstrap5 Theme project installed in OrbStack's DDEV are now complete.
3. Resolving an error
The Drupal install in OrbStack's DDEV is showing the following error — investigating and resolving it.
Home > Administration > Reports > Status report
Protection disabled
The file sites/default/settings.php is not protected against modifications, which is a security risk. Please change the file permissions to read-only.
This error is a settings.php permissions issue. Drupal sets settings.php to 644 at installation, so it needs to be changed to 444 (read-only). The following command normally resolves this. The same command fixed it when installing Drupal on Xserver. Bitnami installs a preconfigured Drupal instance, so this error doesn't appear there.
$ cd web
$ chmod 444 sites/default/settings.php
Let's apply the fix.
3-1. Changing permissions
Running the command in iTerm to change permissions.
// Navigate to the web directory
% cd web
---
// Change settings.php permissions
% chmod 444 sites/default/settings.php
---
// Confirm the change
% ls -l sites/default/settings.php
---
// Changed to 444.
% -r--r--r-- 1 s-takeda drupal 65432 Dec 6 10:00 settings.phpsettings.php permissions have been changed to read-only — let's verify in the Drupal Admin console.
The error hasn't disappeared? Let's investigate.
The same change worked on web servers like Xserver, but the Mac local change isn't taking effect — suggesting the issue is in the DDEV setup. Checking DDEV and OrbStack reveals the cause.
3-2. DDEV configuration
DDEV runs in containers. Here's the configuration diagram.
|-ddev-drupal11-bootstrap5
| |-db
| |-web
|
|-ddev-router
| |-ddev-router
|
|-ddev-ssh-agent
|-ddev-ssh-agentThe settings.php whose permissions need to change is not in drupal11-bootstrap5/web on the Mac terminal — it's in the OrbStack container ddev-drupal11-bootstrap5/web. To change permissions there, you need to SSH into the ddev-drupal11-bootstrap5/web container using DDEV's ssh command.
3-3. SSH into the DDEV container
Using DDEV's ssh to enter the container and change settings.php permissions.
// Log into the container using ddev ssh
% ddev ssh
---
// Shell switches from zsh to bash
s-takeda@drupal11-bootstrap5-web:/var/www/html$ ls -al
// Commands from here use $ notation
---
drwxr-xr-x 1 s-takeda dialout 406 Dec 6 22:14 vendor
drwxr-xr-x 1 s-takeda dialout 336 Nov 26 18:44 web
---
// Check directory structure
$ cd web
$ ls -al
---
-rw-r--r-- 1 s-takeda dialout 2005 Sep 17 05:21 robots.txt
drwxr-xr-x 1 s-takeda dialout 168 Sep 17 05:21 sites
drwxr-xr-x 1 s-takeda dialout 46 Sep 17 06:17 themes
---
$ cd sites/default
$ ls -al
---
-rw------- 1 s-takeda dialout 2015 Dec 6 22:08 settings.ddev.php
---
// settings.php permissions are read/write
-rw------- 1 s-takeda dialout 36727 Dec 7 18:37 settings.php
---
// Change permissions
$ chmod 444 settings.php
// Confirm the change
$ ls -al
---
-rw------- 1 s-takeda dialout 2015 Dec 6 22:08 settings.ddev.php
// Changed to 444 (read-only)
-r--r--r-- 1 s-takeda dialout 36727 Dec 7 18:37 settings.php
---
// Clear cache
$ drush cr
[success] Cache rebuild complete.
---
// Exit SSH
$ exit
---
// Note: When working from the Mac terminal, commands require the ddev prefix due to path
// differences — inside the container, ddev is not needed.
// Mac terminal
% ddev drush cr
// Inside the OrbStack container
$ drush crSSHed into the DDEV container and changed web:/var/www/html/web/sites/default/settings.php from read/write to read-only.
Checking the error in the Drupal Admin console.
Home > Administration > Reports > Status report
32 checked. Details
The error is gone.
Conclude.
As part of setting up the local environment, I updated DDEV, Composer, Drush, Drupal Core, and modules. I also resolved the security warning from settings.php permissions that had been sitting unaddressed since the initial install.
Drupal-related updates happen frequently on the production site so the process is familiar. DDEV, Composer, and Drush updates are less routine — I'll typically read through a tutorial or look up commands beforehand, which turns out to be a good opportunity to pick up knowledge I didn't have before.
This was a local environment task, but Composer and Drush updates can be applied on the live Lightsail and Xserver environments too — I'll find an opportunity to do those as well.
The settings.php security warning had been there since I first set up Drupal on the Mac, but since it's a local environment I ignored it and kept building — and the production servers had their own permissions fix applied, so it just sat there. Looking into it this time, it turned out to be a simple problem: DDEV runs in containers, so the change made from the regular Mac terminal wasn't being applied inside the container. I'd been using DDEV without really thinking of it as a container environment — just treating it like a LAMP local server the same as MANP — which is why it had slipped through.
OrbStack and DDEV's biggest advantages are ease of setup and fast browsing. MAMP > WordPress is also easy to set up, but doesn't match OrbStack and DDEV for browsing speed. I'd been using it purely for that advantage — but this time, having actually touched containers in a local context, the vague mental image of "what containers are" has come into focus. I'd like to try a proper Docker environment when the opportunity comes.
I'm not a developer, so I mostly use CMS platforms like Drupal and WordPress through the web interface — which has meant Git and Docker simply haven't come up. But they're technologies you can't avoid if you want to keep up with how the web is evolving, so I want to find some way to use them.
I'd originally planned to also cover the Civic Theme update in OrbStack's DDEV this time — alongside the Bootstrap5 work — but the article got long, so that goes in the next one.
An article about Civic Theme — the theme that got me interested in Drupal and led me through building and publishing a site.