I have since taken another look at eZ Publish (now eZ Platform) and things have improved significantly. Details here.
This article was initially going to be a quick tip on how to install eZ Publish on Homestead in just a few steps. However, after I saw how much effort it took to get it up and working from scratch on a Vagrant box hosted on Windows, I decided to make it into a full article. I suffered, so you don’t have to :)
I’m hoping the eZ team will address the issues I state below, and as they do (if they do) I will alter this post accordingly. Granted, my environment is very specific: Vagrant on Windows. However, this shouldn’t matter. Every CMS, app, and framework I’ve tried to boot up in the same way was runnable in a matter of minutes. There is no reason in today’s modern web world for this not to work the same way on everything.
Let’s define the purpose of Vagrant. The purpose of Vagrant is team unity, and production / development parity regardless of host operating system. In other words, the purpose of Vagrant is twofold:
- Being able to provide each team member with the identical development environment to avoid “it works on my machine” excuses
- Being able to replicate the production environment as closely as possible without disrupting either the host machine, or the environments dedicated to other clients on the same machine
Therefore, we use Vagrant to have identical copies of VMs dedicated to a single project, which can be easily destroyed and rebuilt without repercussions for easier, faster and more scalable development, experimentation and deployment.
Through experimentation with the installation procedures below, I’ve found that eZ Publish does not make this easy. In 2014, most professional developers with multiple clients and/or projects use Vagrant even while soloing – having dedicated, separate, destructible and rebuildable environments for each project is priceless when considering the plethora of hosting options, tools, and versions of those tools at our disposal.
I’m disappointed to not see more apps adopt a Vagrant-first approach these days. Just like we need to think mobile first when developing front ends, we should think VM-first when developing back end libraries, frameworks and apps – otherwise the whole Docker / Vagrant compartmentalization story the world is focusing on is moot, and the apps that fail to adapt will be left behind as the world moves to Heroku, GAE, Amazon and others.
Let’s start the installation procedure now.
Important Note: If you’re not on Windows, Step 5 probably won’t happen to you. If you are on Windows, you can avoid Step 5 by running the entire procedure in an “elevated” Gitbash / command prompt (by running either as Administrator). Admin users are the only ones who have permission to create symlinks on Windows 8. There were rumors of this being fixable, but none of them reliably work. Running your dev environment as Admin opens a whole new can of worms, so do that at your own risk. If anyone successfully gives a regular Windows 8 user permission to create symlinks through Gitbash, please let me know.
Step 1: Homestead Improved
Have a Laravel Homestead Improved box prepared and working. If you did
vagrant up to see if it works, do
vagrant destroy so we can configure it.
Step 2: Add Site
Homestead.yaml file, and add a new site:
- map: ez.app to: /home/vagrant/Code/ezpub/web
ez.app to your host machine’s
hosts file, as described in the Laravel Homestead Improved quick tip. Basically, make sure your
hosts file contains
127.0.0.1 ez.app. Naturally, also map the shared folder.
Boot the VM with
vagrant up and enter the VM with
Step 3: Install Prerequisites
The project needs PHP to have the
php-xsl extensions installed. It will also ask you for
sendmail throughout the setup wizard. In Homestead, you can install all of these with:
sudo apt-get update sudo apt-get install php5-intl php5-xsl sendmail
Step 4: Get Code
cd Code composer create-project ezsystems/ezpublish-community ezpub
The above will create an eZ project for use, not for development. To get the development version, refer to their Github page.
Note that eZ Publish is ridiculously large, and will take a while to do this. It is almost guaranteed you’ll be hitting the “60 requests per hour” unauthenticated GitHub API rate limit, so you might have to input your username and password during the installation process to get through that barrier.
The process might fail a couple of times due to timeouts and the enormous amount of data that needs downloading. If that happens, just remove the entire
ezpub folder with
rm -rf ezpub and re-run the above
create-project command – it will be faster every time, because each time a package is downloaded, it is served from local cache on subsequent requests, rather than being re-downloaded.
The installer will ask you for some data near the end (secret, fallback locale, etc). Fill it out or just hit enter on each to use defaults.
The reason why we’re not using a prepared
tar archive downloaded from eZ Publish’s website is because the prepared archive is packed with symlinks – and those don’t work if your VM is hosted on a Windows machine. In an effort to keep things multi-platform friendly, I’ve opted for the
composer create-project approach.
Step 5: Handle Installer Bugs [Windows hosts only]
As it stands, eZ Publish isn’t really fine tuned for VMs or edge cases and there’s a lot the team didn’t consider – for example, running it in a VM on a Windows box. With all the dependencies, it’s guaranteed to break somewhere during installation. For me, and probably for you too, this will be the post install scripts that install Assets. Install assets is actually part of Symfony which, in the class which does it, does actually warn against Windows and symlinks, but doesn’t take it into consideration if the parent project forces symlinks, like eZ Publish does.
If this happens (you’ll get an error about symlinks and some such), open
composer.json and delete the line:
This will force the installer to copy the design assets rather than symlink them.
Then, re-run the post-install scripts by executing:
composer run-script post-install-cmd
You might still get an error about the legacy eZ version and a comments bundle of some sort, but I’m not sure how to fix that yet, or whether or not it matters.
Step 6: Create a Database
Create a database we’ll feed to eZ later on. Log into your MySQL instance in the VM with
mysql -u homestead -psecret. Then, run:
CREATE SCHEMA `ez` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
Step 7: Set Up Folder Permissions
This step can be skipped on Homestead, because the server already runs under the “vagrant” user, which owns all the subfolders in the ezpub folders.
Step 8: Run the Setup Wizard
Edit: see Jerome’s comment below for an approach that handles a part of Step 8 and Step 9 automatically.
ez.app:8000 and see the following screen.
This is where it gets super weird. For no reason, this happens. Yes, it’s a problem that has remained unfixed for two years now – seriously, it’s a two year old unresolved bug in a PHP project. Fixing it in the core would take seven seconds of work, including commit and push (see 8.2). There are two ways to get around it in our case. None is pleasant, so it’s up to you to pick one.
Step 8.1: Hilarity Ensues
In order to get around it, and I’m dead serious, this is not a joke – you need to open up dev tools, and put
ezsetup at the end of the form’s
action attribute, because by default it only says
index.php. It’s baffling how such an issue can still exist in 2014, but here we are:
Pick this approach if you don’t like altering a framework’s source files.
Step 8.2: Hacking the Guts
The second, perhaps slightly simpler approach is modifying the form of the wizard itself, and altering its action attribute.
ezpub\ezpublish_legacy\kernel\setup\ezsetup.php, and find the line:
$tpl->setVariable( 'script', $script );
Above it, put this:
$script = ($script == '/index.php') ? '/index.php/ezsetup' : $script;
After this, the action attribute will be fixed.
I do not recommend you try to manually set up eZ Publish by skipping the wizard because you will go insane. Objectively, their installation procedure and their documentation are some of the worst I’ve ever seen. You will lose all desire to even try it out if you attempt to follow their instructions. I hope the eZ team will soon completely remove all dependencies and references to their legacy system, leaving in place only the new core – I also hope they’ll soon update their documentation to something more readable and more 2014-like: people develop on dedicated VMs more and more now, and a short installation procedure along with ease of entry are the most crucial attributes of any CMS that wants to stand out.
Step 9: Ignore Wizard Errors
The eZ Publish setup is out of date enough to know only of one server (Apache) and as such thinks it isn’t running in Vhost mode:
Ignore this warning. Continue on to the next screen (if you used 8.1., don’t forget to alter the form action again, else you’ll start over).
At the end of the setup wizard, you’ll get an Nginx timeout error. This is because eZ Publish is notoriously slow due to it having to process both the awful legacy version and the new version, and due to running on a VM, so when that happens, just remove anything to do with
ezsetup from the URL and refresh. You will then be greeted by this beauty:
Step 10: Disable Cache
The error in the above screen happens while eZ is trying to create caches of PHP files, like this one:
/home/vagrant/Code/ezpub/ezpublish/cache/prod/stash/0fea6a13c52b4d47/25368f24b045ca84/a1e4f174919d040af6d06113d677c9e0/4a1c6be177996f9e/03934ae1c1c02ffc/9a0364b9e99bb480/dd25e1f0284c8555/caf9b6b99962bf5c/2264824231d7a40c/d3d9446802a44259/755d38e6d163e820.php (ugh, don’t ask…).
This cache engine isn’t clever enough to disable itself in case it fails, so we have to do it manually.
ezpub\ezpublish\config\ezpublish.yml change the
stash block to this:
stash: caches: default: handlers: - BlackHole inMemory: true registerDoctrineAdapter: false
“In memory” means the memory will be used for stash cache, instead of the File System. Clear the cache with
rm -rf ezpublish/cache/* and refresh. If need be, replace the cache engine with something more decent than FileSystem cache later on. I have no idea how else to alleviate the protocol error for mkdir – I know it’s VM-related, but not much more. Any advice is much appreciated.
You will now likely be greeted by yet another flurry of warnings and a 503 error at the end:
But at least we got the title to render!
Step 11: Bootstrap.php.cache and Response Limits
The file causing all these warnings is, in fact, a compilation of all the required PHP files for eZ to load up. They’ve been merged into one (!!!) and put into the
ezpublish folder, from whence it is served. The file is a mess of code and not easy to debug because, apart from not having the php extension and lacking IDE highlights, it also doesn’t respect any kind of coding standard (hence, dozens of classes in one file, no indentation and with that, no readability), it being “just a cache file”, after all. But when your entire application depends on a cache file, it would be nice to be able to debug it easily.
Horrible caching practices aside, we can disable this entire mess and just load up eZ Publish in debug mode by changing the
ENVIRONMENT environment variable. You can change this in
Homestead.yaml so it gets autoconfigured during boot by adding it to the “variables” block:
- key: ENVIRONMENT value: dev
Or, you can just edit the
index.php file under
ezpub/web and put
$environment = 'dev'; under
$environment = getenv( "ENVIRONMENT" ); on line 8.
At this point, the second approach is easier if you’ve followed along, because otherwise you’ll have to start over with the entire setup process if you
Finishing this, you should be able to get this to render:
Due to eZ Publish request responses being so absurdly large, we need to up Nginx’s limits:
sudo vim /etc/nginx/sites-available/ez.app
Under the root directive, paste the following:
fastcgi_connect_timeout 60; fastcgi_send_timeout 180; fastcgi_read_timeout 180; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k;
Save, exit, restart Nginx with
sudo service nginx restart.
Some pages will work (blog, discover), others, well, not so much. Debugging their Demo bundle, however, is outside the scope of this already too long article.
Step 12: Remove index.php from the URL
By default, all Symfony apps have “app.php” or in eZ Publish’s case “index.php” in their URL for some reason. I guess someone has to support those hosting providers and developers from 2001. Let’s bring both projects into the 21st century by removing it.
sudo vim /etc/nginx/sites-available/ez.app
As per instructions here, above the “location” block, add:
rewrite ^/index\.php/?(.*)$ /$1 permanent;
Save, exit, and restart nginx with
sudo service nginx restart.
Step 13: Rejoice
After an arduous process, we’re finally done. What took me more than a day, hopefully took you less than 10 minutes (excluding download times). Now you too can try this powerful, albeit overbloated, overcomplicated and outdated CMS on your own Homestead instance. Let me know how it works out!
Any CMS that requires this much work to get up and running on a Vagrant box is, in my mind, not a CMS worth paying attention to. Sure, you can probably easily install it onto a host machine and run it that way, but that’s not a professional approach – development environments need to be encapsulated and isolated, and developers need to be able to destroy and rebuild an instance on a whim. A CMS should have scripts that auto-execute, detect all possible problems (like Symlinks not being available and switching to hard-copy mode automatically) and set everything up (from the database to the folder permissions, if necessary), only asking for sudo along the way.
This process has installed eZ Publish, but was it worth it? That’s up to you to decide. While eZ definitely is a powerful CMS, the difficulties of getting into it are detrimental at best. You now have a common starting point to test it out on, and I’ll be sure to find out more about these issues from the eZ people at PHP Summer Camp and elsewhere. Until then, let’s get some eZ tutorials going on this box, shall we?
Put your feedback in the comments below, I’m eager to hear different approaches, especially if you’ve tried to do this on a non-Windows host and made the demo bundle work!
Edit: This Github repo has been brought to my attention. It is a prepared vagrant configuration of eZ Publish that works. There are two caveats, though:
- The point of the step-by-step here was to show you how simple it was to have an identical eZ instance up and running on any machine for development purposes (the fact that it turned out not to be simple is another story entirely). This is important because, for example, not everyone uses the same OS – the repo linked above is on CentOS, while Homestead is Ubuntu. The installation procedure should be equally simple on any OS.
- The eZ Publish files inside this VM are literally inside it – there is no sharing of folders to the outside world (host machine), ergo no chance of symlink issues, but also no chance of opening the app’s files in an IDE installed on the host machine in order to hack on them. This prevents an effective development workflow.