— Artikel — № 007

007 —Drupal

Drupal 7 end-of-life: checklist voor klanten die blijven

Drupal 7 ging in januari 2025 end-of-life. De sites die er medio 2026 nog op draaien doen dat niet per ongeluk, maar uit pure verwaarlozing.

Gesloten leren logboek met zijden lint, messing penpunt op rode lakzegel, gedateerde kaart op eiken bureau.
Hero · gestileerd stilleven№ 007

Een senior engineer bij een Nederlands bureau waar we mee samenwerken logde vorige week in op de Drupal 7-admin van een klant en vond veertien contrib-modules zonder Drupal 10-equivalent, een Features-module geschreven door een freelancer die in 2018 vertrok, en een node_revision-tabel van 9,2 miljoen rijen. De briefing was 'een kleine refresh van de homepage'. De daadwerkelijke klus is een migratie van meerdere maanden waar niemand budget voor heeft gereserveerd.

Dit is de standaardsituatie in 2026. Drupal 7 bereikte end-of-life op 5 januari 2025, na drie afzonderlijke verlengingen. Wie er nu nog op draait doet dat op geleende tijd, op vendor-patches, of op moedwillige onwetendheid. Geen van die drie schaalt. De checklist hieronder is wat we doornemen met bureaus en interne teams die een oude Drupal-legacy site hebben geërfd die niet op tijd is gemigreerd. Het is geen verkooppraatje voor een rewrite, want in ruwweg een derde van de gevallen is het juiste antwoord verlengen, hardenen en uitstellen. De kunst is weten welk derde.

Wat end-of-life feitelijk veranderde

De mechanische verandering op 5 januari 2025 was het einde van de community security advisories van het Drupal Security Team voor core en contrib. Nieuwe CVE's tegen Drupal 7 worden niet meer getrieerd op drupal.org/security. Bestaande advisories blijven gepubliceerd, maar er komen geen nieuwe meer bij, tenzij een ELTS-vendor er een uitbrengt tegen zijn eigen gepatchte fork.

De praktische verandering is trager en lelijker. Contrib-maintainers reageren niet meer op issue queues. Composer-geïnstalleerde dependencies beginnen te falen omdat hun D8+-tegenhangers PHP 7-support hebben gedropt. Hosts weigeren PHP 7.4 op shared plans. De site blijft verkeer serveren, maar elk stuk infrastructuur eromheen rot er parallel naast weg.

De audit die je doet voor al het andere

Je kunt dit soort migratie niet plannen vanuit een projectbriefing. Je plant het vanuit de daadwerkelijke codebase. Het eerste dat we tijdens de audit doen zijn dezelfde vijf commando's, in deze volgorde:

drush status
drush pm-list --type=module --status=enabled --no-core
drush sqlq "SELECT COUNT(*) FROM node_revision"
drush sqlq "SELECT name, schema_version FROM system WHERE type='module' AND status=1"
find . -path ./sites/default/files -prune -o -name "*.module" -print | xargs wc -l

De eerste vertelt je de PHP-versie, MySQL-versie en de Drupal point-release. De tweede is je migratie-risicoregister. De derde vertelt je of de migratie in een onderhoudsvenster past of een gestreamde cutover moet worden. De vierde vangt modules met een openstaande DB-update, en dat is veruit de meest voorkomende reden dat een legacy-naar-D10 migratie halverwege ontploft. De vijfde meet het oppervlak van je custom modules, en dat is wat je daadwerkelijk met de hand moet herschrijven.

Met die vijf outputs kun je de klant binnen een dag een echte inschatting geven. Zonder die outputs zit je te gokken, en gokken op dit soort migraties zit er een factor drie naast.

Kies een pad en commit

Er zijn precies drie eerlijke paden voor een Drupal-site zonder support in 2026. Hybride plannen pakken meestal het slechtste van alle drie.

Pad A: extended vendor support. Vendors als Tag1, MyDropWizard en HeroDevs verkopen betaalde security-patches tegen Drupal 7-core en de longtail van veelvoorkomende contrib-modules. Tarieven liggen ruwweg tussen €2.000 en €8.000 per jaar, afhankelijk van contrib-dekking. Dit is het juiste pad als de site minder dan twee jaar verwachte levensduur heeft, het redactieteam stabiel is, en herbouw geen nieuwe businesswaarde oplevert. Het is het verkeerde pad als de contrib-dekking dun is (check de coveragelijst van de vendor voor je tekent) of als je tegelijk ook PHP-EOL op de host aan het bestrijden bent.

Pad B: migreren naar Drupal 10 of 11. Gebruik de core Migrate-, Migrate Drupal- en Migrate Drupal UI-modules. Bouw een verse Drupal 11-site, wijs de migratiebron aan op de bestaande database en draai de migratie eerst in dry mode:

drush migrate:status --group=migrate_drupal_7
drush migrate:import --group=migrate_drupal_7 --limit=100
drush migrate:messages d7_node_article

Het lastige deel is nooit de core content. Het zijn de contrib-modules zonder D10-equivalent (begin met Upgrade Status), de Features-geëxporteerde configuratie die niet meer mapt naar het config-systeem van D10, en de custom modules waarvan de hook_-implementaties services en event subscribers moeten worden. Begroot twee keer zo veel tijd voor die drie dingen als je denkt.

Pad C: herbouwen op iets anders. Soms is het juiste antwoord niet Drupal 10. Als de site een content-marketingsite is met vijf redacteuren en geen commerce, gaat een headless CMS met een statische frontend langer mee dan nog een Drupal-cyclus en kost het een kwart van de operationele kosten. We hebben dergelijke sites verhuisd naar Statamic, naar Sanity plus Next.js, en in twee gevallen naar WordPress omdat het redactieteam dat sterk prefereerde. Het migratiescript is lastiger (geen Migrate-module om op te leunen) maar de lange-termijn onderhoudslast daalt.

Stopgap-hardening voor de achterblijvers

Sommige klanten committen zich dit kwartaal niet aan een exit-pad. Prima. Laat de site dan niet kaal staan terwijl ze beslissen. De minimale hardening voor een installatie zonder support bestaat uit vier wijzigingen.

Blokkeer PHP-uitvoering in sites/default/files op de webserver. Drupal 7 heeft historisch RCE-paden gehad via file uploads, en alleen directory-permissions zijn niet genoeg op shared hosting:

<Directory "/var/www/html/sites/default/files">
    <FilesMatch "\.(php|phtml|php3|php4|php5|php7|phar)$">
        Require all denied
    </FilesMatch>
    Options -ExecCGI
    RemoveHandler .php .phtml .phar
</Directory>

Zet de MySQL-user vast op het minimum aan grants dat de site daadwerkelijk nodig heeft. De default install-instructies vertellen je om ALL PRIVILEGES toe te kennen, wat tijdens installatie prima is en daarna roekeloos:

REVOKE ALL PRIVILEGES ON drupal_prod.* FROM 'drupal'@'localhost';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE TEMPORARY TABLES,
      LOCK TABLES, EXECUTE
   ON drupal_prod.* TO 'drupal'@'localhost';
FLUSH PRIVILEGES;

Schakel de modules uit die een CVE-historie hebben en die de site niet actief gebruikt. De usual suspects: PHP Filter (zou al uit moeten staan, check toch), Webform als er geen formulieren actief zijn, RESTful Web Services, Services. Draai drush pm-list --status=enabled en bevraag elke regel.

Voeg een offsite database-dump op schema toe. Niet de 'managed backup' van de host. Een echte mysqldump die naar S3 of B2 verstuurd wordt met 30 dagen retentie. Als de site in 2026 omvalt, valt-ie hard om, en het backup-venster van de host is vaak korter dan de tijd die het kost voor iemand het merkt.

De migratie-generale repetitie

Als je voor Pad B hebt gekozen, migreer dan niet tegen productie. Bouw een staging-kloon van de bron-database (met mysqldump | gzip | scp, niets fancy), wijs een verse Drupal 11-installatie ernaar en draai de volledige migratie op een werkstation of een wegwerp-VM. Log elke waarschuwing. De eerste run brengt honderd problemen aan het licht. De tweede, nadat je de field mappings voor je custom content types hebt geschreven, brengt er tien aan het licht. De derde zou schoon moeten zijn.

Houd een lopende lijst bij van elke contrib-module die een handmatige vervanger nodig had en elke custom hook die herschreven moest worden. Die lijst geef je de klant aan het eind van de migratie als onderhouds-baseline voor de nieuwe site. Ze lezen hem niet. Je bent blij dat je hem schreef de eerste keer dat er in jaar twee een CMS-eigenaardigheid opduikt.

Toen we Pier bouwden, brachten we meer tijd door op Drupal 7-sites dan op enig ander CMS, omdat het overerfingspatroon zo consistent is: het bureau dat het bouwde is weg, de freelancer die het patchte is weg, en de enige persoon die weet waar de custom code staat is de redacteur die er negen jaar omheen werkt. We losten dat uiteindelijk op door elk bestand en elke tabel op de server beschikbaar te maken via één chat-oppervlak, met one-click version history op elke wijziging, zodat de engineer die de audit doet door de live site kan rommelen zonder iets te slopen. De MySQL editor zit in hetzelfde venster als de bestandsboom, en dat is wat een audit op dit CMS feitelijk nodig heeft.

Het kleinste wat je vandaag kunt doen: draai de vijf audit-commando's hierboven op elke oude Drupal-site waar je nog verantwoordelijk voor bent, plak de output in één tekstbestand per klant en mail het bestand naar jezelf. Je hebt geen tijd om dit te doen in het kwartaal waarin je inbox in brand staat.

— Vragen —

Heeft Drupal 7 daadwerkelijk geen support meer?

Klopt. De community security-support eindigde op 5 januari 2025, na drie verlengingen. Nieuwe CVE's tegen Drupal 7 worden niet meer getrieerd op drupal.org. Betaalde ELTS bestaat, maar dekt een beperkte set contrib-modules.

Kan ik Drupal 7 direct upgraden naar Drupal 11?

Niet in-place. Je bouwt een verse Drupal 11-site en migreert de D7-database erin met de core Migrate Drupal-modules. Er is geen upgradepad dat de bestaande codebase behoudt.

Hoe lang duurt een typische migratie van Drupal 7 naar Drupal 10?

Drie tot negen maanden voor een niet-triviale site, afhankelijk van het aantal contrib-modules en de hoeveelheid custom code. Begroot twee keer je eerste inschatting. De contrib-gaten en de Features-config zijn waar de tijd in gaat zitten.