Skip to content

Instantly share code, notes, and snippets.

@olragon
Created March 13, 2026 16:03
Show Gist options
  • Select an option

  • Save olragon/b435b66b3d7e783d64880d05f8af0e6d to your computer and use it in GitHub Desktop.

Select an option

Save olragon/b435b66b3d7e783d64880d05f8af0e6d to your computer and use it in GitHub Desktop.

Upgrading Mautic 6.0.7 → 7.0.1 (Docker, MariaDB 11.8)

Environment

  • Docker: PHP 8.3-fpm + nginx + supervisord
  • MariaDB 11.8 (shared container)
  • Previous upgrade: 5.2.3 → 6.0.7 already completed

Gotcha: Unsigned FK Column vs Signed PK

Migrations Version20250828070131 (sms_messages) and Version20250923135527 (push_notifications) add a translation_parent_id column as unsigned int with a self-referencing FK to the id column, which is signed int.

Symptom:

General error: 1005 Can't create table `blagu_mautic`.`sms_messages`
(errno: 150 "Foreign key constraint is incorrectly formed")

Root cause: FK constraints require both columns to have matching types (including signedness). The migration uses 'unsigned' => true but the PK id is signed.

Fix: Apply the migration manually with the correct column type:

-- For sms_messages
ALTER TABLE sms_messages MODIFY translation_parent_id int(11) DEFAULT NULL;
ALTER TABLE sms_messages ADD INDEX IDX_SMS_TRANSLATION_PARENT (translation_parent_id);
ALTER TABLE sms_messages ADD CONSTRAINT FK_SMS_TRANSLATION_PARENT
  FOREIGN KEY (translation_parent_id) REFERENCES sms_messages (id) ON DELETE CASCADE;

-- For push_notifications
ALTER TABLE push_notifications MODIFY translation_parent_id int(11) DEFAULT NULL;
ALTER TABLE push_notifications ADD INDEX IDX_PUSH_NOTIFICATIONS_TRANSLATION_PARENT (translation_parent_id);
ALTER TABLE push_notifications ADD CONSTRAINT FK_PUSH_NOTIFICATIONS_TRANSLATION_PARENT
  FOREIGN KEY (translation_parent_id) REFERENCES push_notifications (id) ON DELETE CASCADE;

-- Mark migrations as executed
INSERT INTO migrations (version, executed_at, execution_time)
VALUES ('Mautic\\Migrations\\Version20250828070131', NOW(), 0);
INSERT INTO migrations (version, executed_at, execution_time)
VALUES ('Mautic\\Migrations\\Version20250923135527', NOW(), 0);

Then re-run doctrine:migrations:migrate --no-interaction to process remaining migrations.

Volume Sync (Same as 5→6)

After swapping source code, sync plugins and themes from the image to volumes:

docker compose stop mautic
for vol in plugins themes; do
  VOL_PATH=$(docker volume inspect mautic_mautic-${vol} --format '{{.Mountpoint}}')
  rm -rf ${VOL_PATH}/*
  docker run --rm -v mautic_mautic-${vol}:/dest --entrypoint bash mautic-mautic \
    -c "cp -r /var/www/html/${vol}/* /dest/"
done
# Clear cache
VAR_PATH=$(docker volume inspect mautic_mautic-var --format '{{.Mountpoint}}')
rm -rf ${VAR_PATH}/cache/*
docker compose up -d

Dockerfile Simplification

Mautic 7.0.1 ships with pre-built frontend assets (CKEditor, CSS with Remix Icons). The Node.js build step from the 5.x Dockerfile is no longer needed:

# Before (5.x)
COPY html/ /var/www/html/
RUN apt-get install -y nodejs && npm install && npx webpack ...

# After (7.x) — assets ship pre-built
COPY html/ /var/www/html/
RUN chown -R www-data:www-data /var/www/html

Verification Checklist

  • docker exec mautic php bin/console --version → Mautic 7.0.1
  • Login page loads (200)
  • Tracking JS: curl -I https://your-domain/mtc.js → 200
  • Config page: 403 (if nginx deny rule set) or loads with auth
  • Cron log: docker exec mautic tail /var/www/html/var/logs/cron.log
  • Email campaigns: test send works
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment