Setting up the local environment

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:

  1. Run the Linux virtual machine provided by OrbStack in the Mac local environment — runs as a container by default
  2. 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

  1. Terminal: iTerm 3.5.10 > Shell: Mac default Zch
  2. Package manager: Homebrew 4.3.22
  3. Local server (required to run Drupal on Mac): OrbStack Pro V1.8.2
  4. Local Docker environment: DDEV v1.23.4 > updated to 1.24.0
  5. PHP 8.3.10
  6. MariaDB 10.11.8
  7. Composer Version 2.7.9 > updated to 2.8.3
  8. Drupal Core 11.0.4 > updated to 11.0.9 / Bootstrap5 Theme
  9. Drupal Core 10.0.3 > updated to 10.3.10 / Civic Theme
  10. Bootstrap5 4.03
  11. Civic Theme 1.8.1 > updated to 1.9.0

Editor: Vscord 1.93.1 > 1.95.3

  1. GitHub Copilot 1.229.0 > 1.248.0 Vscord extension
  2. Japanese Language Pack 1.93 > 1.95 Vscord extension
  3. PHP Debag 1.35.0 Vscord extension
  4. Remote SSH 0.114.3 > 0.115.1 Vscord extension
  5. SSH: Editing Configuration Files 0.86.0 > 0.87.0 Vscord extension
  6. Remote Explorer 0.4.3 Vscord extension
  7. 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:

  1. Launch OrbStack from the Mac GUI
  2. Launch iTerm and navigate to the Drupal project directory: $ cd drupal11-bootstrap5[project-name]
  3. Start DDEV: $ ddev start — the virtual server starts and Drupal becomes available
  4. Access the Drupal site at https://drupal11-bootstrap5[project-name].site
  5. Log in to the Drupal Admin console
  6. 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

  1. 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.
  2. 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.
  3. 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:

  1. Composer 2.7.9 > 2.8.3
  2. Drush 13.1.1 > 13.3.3
  3. Drupal Core 11.0.4 > 11.0.9
  4. 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.9

Updates 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.php

settings.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-agent

The 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 cr

SSHed 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.

Next article.

Civic Theme

An article about Civic Theme — the theme that got me interested in Drupal and led me through building and publishing a site.

Last update
Contributor
S.Takeda
Article

Powered by Drupal 11.4.2 and Bootstrap 5.0.4

Published AWS Jamstack by Drupal