A Fresh Start: Moving to Drupal 11 and Ubuntu 24.04
The site has moved again. I can barely recall the last time this happened, let alone when the site truly began. The first entry mentions a previous move to Drupal 4.7. I suspect the very beginning was a simple web board or something similar. For context, my last two servers ran Ubuntu 18.04 (with Drupal 8) and before that, Ubuntu 16.04 (I believe with Drupal 6). My most recent post was in 2018.
Anyway, this latest move was prompted by an impending hardware failure: the HDD on the old Ubuntu 18.04 server is dying. So, here we are in 2025, and it's time to migrate the entire server to Drupal 11 on Ubuntu 24.04.
This content migration was a considerable effort. I chose a fresh install and migration over a standard upgrade because the old server had been compromised, and I couldn't risk carrying over any hidden malicious code.
Server Setup & Tooling
To manage the new environment, I've adopted DDEV. It's an excellent, convenient open-source wrapper and configuration tool that orchestrates Docker images for Drupal development, providing a clean, containerized setup.
- DDEV Configuration: I followed the standard instructions, which resulted in the project folder being inside my home directory. DDEV's Docker image then maps this directory to its internal filesystem path, typically
/var/www/html
. - Management: All command-line operations are now handled through DDEV's prefix, specifically using
ddev drush xxx
for alldrush
commands. - Multi-site Setup: Implementing a Drupal multi-site was straightforward. I simply created a new directory at
$DRUPAL_ROOT/web/sites/xxxx
(wherexxxx
is the site's hostname) and placed the requiredsettings.php
file inside it.
Migration
I made a deliberate choice to import only the title and body fields of all existing content, ignoring the previous site structure entirely. The process was roughly as follows:
- Database Dump: The old content was directly dumped from the MySQL database into a CSV file. I used the
SELECT ... INTO OUTFILE
command to ensure that all fields were properly enclosed by double quotes ("), which is crucial for handling complex, multi-line data. - CSV Character Fix: I ran into an issue where MySQL's dump process generated carriage return characters (
^M
) that the migrate_plus module couldn't handle, causing the import to fail. I had to use sed to remove them (the slurp command reads the whole file before substitution):sed ':a;N;$!ba;s/\r\\//g'
- Custom Migration Module: The corrected CSV was then imported using the migrate_plus module. All migration configuration details are contained within a simple custom module:
$DRUPAL_ROOT/web/modules/custom/xxx_content_migration
. - Configuration Workflow: Crucially, whenever I modify the configuration files inside the custom migration module, it must be purged and reloaded to take effect. This is the command sequence I use for a complete rollback, reload, and re-import:
ddev drush --uri=www.nattee.net pmu dae_content_migration
ddev drush --uri=www.nattee.net cr
ddev drush --uri=www.nattee.net en dae_content_migration
ddev drush --uri=www.nattee.net migrate:rollback --all
ddev drush --uri=www.nattee.net migrate:import --all
Important Migration Notes
- Required Fields: The CSV must include values for the content_type and body_format. If these values are missing, or if they reference a content type or text format that doesn't exist on the new Drupal 11 site, the migration will crash the site entirely.
- Recovery: If the site crashes, a simple rollback of the migration will usually bring the site back to life, allowing you to debug your CSV or migration configuration.
- Log in to post comments