Drupal 7 to Drupal 10/11 Site Migration
Drupal 7 reached EOL in January 2025. There is no direct upgrade path — this is a full migration. Drupal 7 and Drupal 10 are architecturally different systems: D7 doesn't use Composer, OOP, Symfony components. Content is migrated via Migrate API, code is rewritten.
Migration Strategies
Migrate API (recommended) — content is migrated programmatically from D7 database to D10. Configured migrations can be run repeatedly until switchover day, minimizing downtime.
Manual content migration — for small sites (< 100 nodes) export via Views + import via Migrate or manual copy. Faster to setup, longer to execute.
Big bang — complete D7 shutdown, D10 setup, migration. Downtime from hours to days.
D7 Site Analysis
# List active D7 modules
drush pm-list --status=enabled --type=module
# Node types and counts
drush sql-query "SELECT type, COUNT(*) FROM node GROUP BY type"
# Database size
drush sql-query "SELECT table_name, ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'MB' FROM information_schema.TABLES WHERE table_schema = DATABASE() ORDER BY (data_length + index_length) DESC"
# Custom modules
ls sites/all/modules/custom/
D10 Site Setup with Migrate API
On new D10 server:
composer create-project drupal/recommended-project drupal10-site
cd drupal10-site
composer require drupal/migrate_plus drupal/migrate_tools \
drupal/migrate_upgrade drupal/migrate_source_csv
drush en migrate migrate_plus migrate_tools migrate_upgrade -y
Connect D7 as additional database in settings.php:
$databases['migrate']['default'] = [
'driver' => 'mysql',
'database' => 'drupal7_db',
'username' => 'db_user',
'password' => 'db_pass',
'host' => '127.0.0.1',
'port' => '3306',
'prefix' => '',
];
Generating Migrations
# Auto-generate migration configurations from D7
drush migrate:upgrade --legacy-db-key=migrate --legacy-root=/path/to/d7/files
# View what was generated
drush migrate:status
Migrate Upgrade creates YAML configs for: users, roles, taxonomy vocabularies, terms, content types, fields, nodes, media files, blocks, menus.
Migration Execution Order
Dependencies matter — can't migrate nodes before taxonomy and files:
# 1. Configuration (roles, content types, fields)
drush migrate:import upgrade_d7_user_role
drush migrate:import upgrade_d7_node_type
drush migrate:import upgrade_d7_field
drush migrate:import upgrade_d7_field_instance
# 2. Taxonomy vocabularies
drush migrate:import upgrade_d7_taxonomy_vocabulary
drush migrate:import upgrade_d7_taxonomy_term
# 3. Users
drush migrate:import upgrade_d7_user
# 4. Files
drush migrate:import upgrade_d7_file
# 5. Content (nodes)
drush migrate:import upgrade_d7_node_complete
# 6. Menus and blocks
drush migrate:import upgrade_d7_menu
drush migrate:import upgrade_d7_block
Problem Areas
CCK/Field API — D7 CCK fields migrate well. Field Collection (D7 equivalent of Paragraphs) — no direct support, needs custom migrate.
composer require drupal/migrate_field_collection
Views — Views 3 (D7) migrates partially. Complex views with relationships need recreation.
Custom D7 modules — need full rewrite: D7 uses procedural code, hook_schema, hook_menu. D10 — classes, annotations, routes via YAML.
Media files — migrate files from D7 filesystem:
# Configuration for copying files
source:
plugin: d7_file
source_base_path: 'https://old-d7-site.com' # or local path
process:
uri:
plugin: file_copy
source:
- '@source_path'
- 'public://'
Rewriting Custom Modules
// D7 (procedural)
function mymodule_menu() {
return [
'admin/config/mymodule' => [
'title' => 'My Module Settings',
'page callback' => 'drupal_get_form',
'page arguments' => ['mymodule_settings_form'],
],
];
}
// D10 (OOP + YAML routes)
// mymodule.routing.yml:
// mymodule.settings:
// path: '/admin/config/mymodule'
// defaults:
// _form: '\Drupal\mymodule\Form\SettingsForm'
Delta Migration: Minimizing Downtime
# Primary migration (hours/days before switchover)
drush migrate:import --all
# On switchover day:
# 1. Enable maintenance mode on D7
# 2. Update changed content
drush migrate:import --all --update
# 3. Switch DNS to D10
# 4. Disable maintenance mode on D10
Timeline
| Site Type | Duration |
|---|---|
| Simple (< 100 nodes, standard types) | 2–3 weeks |
| Medium (500–5000 nodes, custom modules) | 4–8 weeks |
| Large (50k+ nodes, complex dependencies) | 3–6 months |







