Can I run multiple Symfony applications while using preloading?

Viewed 798

I have 2 separate Symfony installations on different subdomains.
However, when I try to visit the 2nd domain, it says:

Fatal error: Cannot redeclare Symfony\Component\String\u() (previously declared in /var/www/public_api/releases/20200904200316/vendor/symfony/string/Resources/functions.php:14) in /var/www/public_test_api/releases/20200909003532/vendor/symfony/string/Resources/functions.php on line 14

Note that the conflict is between different directories, which have nothing to do with each other.

Is this a cache issue? How do I solve this? I tried to disable OPCache for the 2nd installation, but it didn't change anything. APCu is enabled too.

I'm having the same problem with a 3rd party software too, which also uses Symfony.

Disabling opcache.preload setting seems to get rid of this issue.

Is there a way for run all these applications on the same server and benefit from preloading?

1 Answers

You can't use preloading for classes that are used more than once in the same server.

Preloading keeps the relevant definitions in memory by reading the files specified in opcache.preload. If you preload one Symfony instance and then attempt to load a different Symfony instance, you'll get definitions clashes (as it's happening to you).

In practice, to be able to benefit from preloading you need to have isolated "dedicated" servers, even if the servers are not physical machines but virtual machines or containers.

As explained in the original RFC for this feature:

[...] this approach will not be compatible with servers that host multiple applications, or multiple versions of applications - that would have different implementations for certain classes with the same name - if such classes are preloaded from the codebase of one app, it will conflict with loading the different class implementation from the other app(s).


TLDR; you can't use preloading on the same server for multiple instances of the same classes. You have to turn preloading off, or move each application in its own dedicated container where they won't share a PHP-FPM process.

Related