Wednesday, 2 January 2019

Using Wodby (drupal4docker) to create our local development environment.

Using Wodby to create a Drupal local development environment using docker.

I have used the official Drupal docker image to create a local dev environment, it certainly does work but does not really tie in with how we currently use and develop on Drupal.

I have checked Wodby drupal4docker and it seems to do what I expect and want the local dev environment.

How to set this up

Obviously there is a documentation on how to set this up even though the documentation is quite thorough I still struggled a bit so wanted to create a documentation for myself and anyone who happens to stumble on this link.

My setup will consist of a local Drupal 8 code base with custom modules and themes, I save my code base in git including the Drupal code, this may not be really needed in the future as we are moving to using composer but for now I am sticking to keeping the Drupal codebase in my repository.

I also have a separate docker image that I build from this code base which is used for CI and eventually becomes a package which is deployed to production. 

If starting a new project use the recommended way to install Drupal with composer like so

composer create-project drupal-composer/drupal-project:8.x-dev drupal8 --stability dev --no-interaction

This will download the Drupal code base, and install dependencies and configure a web root the directory structure looks like this. In the above command “drupal8” is our project root but now where your would traditionally expect the Drupal code base to be, this is under web. For rest of the purpose of this document the project root is “drupal8” and we will use this interchangeably.

Now we will download the latest stable release of docker4drupal which is a collection of files, most importantly the .env file with the parameters which you can define and change to your hearts content and the docker-compose.yml file that defines how these services interact with each other. After copying the files in the project root the folder structure looks like this.

Now we need to delete the docker-compose.override.yml as this is not needed if you use your own codebase and not the Vanilla as it is known. We will also need to create a .env file that allows us to conveniently change the properties without changing the docker compose file, this is much cleaner in my opinion, also the properties may be reused and duplicated hence hence it makes sense to have them in a .env file rather than hardcode in the compose file.

I have created a .env file from we can then remove the properties that we will not use.

I struggled a bit earlier till I realised this would work only If you used the docker for Mac and not docker toolbox, so thats what I did installed docker for Mac enabled the nfs volume section and use the user guided caching to get a better performance for Mac users. So my final docker compose file with things I did not need, removed is as follows (note I have kept portioner and traefik but just don’t show in the docker compose file below for berevity if we decide not to use traefik later we we will to expose the appropriate ports in the compose file.:

We also need to create a docker volume like so:

docker volume create --name=docker-sync

And a host entry for the Drupal site which is drupal.docker.localhost

Also ensure you have docker-sync installed and are running it. If you are just checking the docker4drupal and performance is not that bad, you can just skip the docker-sync parts. The docker-sync uses the docker-sync.yml which is also in the archive we downloaded from docker4drupal earlier. The first time sync will take a little longer but then it should give you a good performance boost. If not using docker-sync the performance will be quite shockingly bad though.

Now we can run docker-compose up -d to create the containers, first time it will be slower as it downloads all the images but following this the Drupal site will be available as http://drupal.docker.localhost:8000, run through the installer, once the site is installed the database files are inside the data folder, docker storage is not persistent unless external volumes are used in this case we have used data folder to store the files. We can also take a dump of the database and keep in our codebase which we can place in the marinade-init folder to pre-populate the site content and configuration.

Saturday, 3 November 2018

Add behat in Symfony 4

To add behat in Symfony 4 i have generally followed this link

However i ran into problems so i thought of sharing this info.

The steps are

run composer req behat/behat --dev

but stumbled on the following error:

~/work/thefootie-behat $ composer req behat/behat --dev

Using version ^3.5 for behat/behat

./composer.json has been updated

Loading composer repositories with package information

Updating dependencies (including require-dev)

Restricting packages listed in "symfony/symfony" to "4.1.*"

Your requirements could not be resolved to an installable set of packages.

  Problem 1

    - Installation request for behat/behat ^3.5 -> satisfiable by behat/behat[v3.5.0].

    - behat/behat v3.5.0 requires symfony/class-loader ~2.1||~3.0 -> satisfiable by symfony/class-loader[3.4.x-dev] but these conflict with your requirements or minimum-stability.

Installation failed, reverting ./composer.json to its original content.

It seems I had to choose to downgrade my minimum stability to dev to install this, as this is dev only packages I don't really mind.

~/work/thefootie-behat $ composer config minimum-stability dev

Following which I did not have any problems with the rest of the instructions.

Installation and adding config in behat.yml was fine, but when i tried to run behat i got the error below:

~/work/thefootie-behat $ ./vendor/behat/behat/bin/behat

PHP Warning:  require_once(/Users/devuser/work/thefootie-behat): failed to open stream: Undefined error: 0 in /Users/devuser/work/thefootie-behat/vendor/symfony/dependency-injection/ContainerBuilder.php on line 1097

Warning: require_once(/Users/devuser/work/thefootie-behat): failed to open stream: Undefined error: 0 in /Users/devuser/work/thefootie-behat/vendor/symfony/dependency-injection/ContainerBuilder.php on line 1097

PHP Fatal error:  require_once(): Failed opening required '/Users/devuser/work/thefootie-behat/' (include_path='.:/usr/local/Cellar/php/7.2.5/share/php/pear') in /Users/devuser/work/thefootie-behat/vendor/symfony/dependency-injection/ContainerBuilder.php on line 1097

Fatal error: require_once(): Failed opening required '/Users/devuser/work/thefootie-behat/' (include_path='.:/usr/local/Cellar/php/7.2.5/share/php/pear') in /Users/devuser/work/thefootie-behat/vendor/symfony/dependency-injection/ContainerBuilder.php on line 1097

After some googling i came across, a post and downgraded the behat/symfony2-extension to 2.1.5 - this seemed to have resolved the issue.

Turned out we used the behat/symfony2-extension with dev-master stability.

"Downgrading" to 2.1.5 resolved the issue.

After downgrading i can see the demo steps passed!

~/work/thefootie-behat $ ./vendor/behat/behat/bin/behat 
  In order to prove that the Behat Symfony extension is correctly installed
  As a user
  I want to have a demo scenario

  Scenario: It receives a response from Symfony's kernel # features/demo.feature:10
    When a demo scenario sends a request to "/"          # FeatureContext::aDemoScenarioSendsARequestTo()
    Then the response should be received                 # FeatureContext::theResponseShouldBeReceived()

1 scenario (1 passed)
2 steps (2 passed)
0m0.20s (20.80Mb)

Monday, 15 October 2018

Update Drupal 8 DB to allow Updates to be run again for testing and dev purposes

When working with Drupal 7 and indeed Drupal 8 we may sometimes need to run updates (hook_update) again. In Drupal 7 updating system table should have been sufficient. In D8 things are a little bit different.

Run a database update as follows:
  • SELECT collection, name, substring(value, 1, 2500) FROM key_value WHERE collection="system.schema" and name="modulenameinquestion"
    • The above will give us the last update hook that was run on this database.
  • UPDATE key_value SET value = 'i:9999' where collection="system.schema" and name="modulenameinquestion"

Hope this helps.

Monday, 18 June 2018

Use Behat BDD tests with Drupal 7

Behat is a framework that allows us to write BDD tests, aka given-when-then tests. The language of test specification is quite simple and easy to read and is more business friendly, to know more about BDD you can go here

To use BDD with our drupal 7 site we need to go in the code base, create a folder under sites folder called behat. Installing Behat is done best using composer, so we need to create a composer.json file with the following content

  "require": {
    "drupal/drupal-extension": "~3.0"
  "config": {
    "bin-dir": "bin/"
and save as composer.json 

Instructions are from adding starting steps or steps to make things clear.

Assume composer is installed system wide (you can find better guides to install composer by searching on google).

composer install

This will install all required dependencies (exactly why composer is such a good idea).

Your console will fill up with a lot of information like this:

Once everything is installed, we are ready to start writing tests - but we need to tell behat where to store our context and features first, so wait ... what are context and features? more about that in the excellent BDD guide i linked above. 

Lets just say context is where you have your definitions, transformations and hooks, and features where you define your acceptance criteria or your tests in the given-when-then format.

The first step we need to do is initialise behat, to do that we say

./bin/behat --init

This creates the features and context as discussed above and shows you the following message.

If we have installed behat correctly we should be able to see a lot of context already defined for use in our Drupal projects thanks to Drupal Behat extensions. To see the context and maybe use it for reference later do this

./bin/behat -dl

This should list all the context as below:

There are quite a few context defined, in fact they are enough to get us started and take us much further than that. For eg. we will not write a single custom context but try to reuse existing context and write our features to add content and validate.

Remember this if your BDD tests are not working as expected, this could be more because you have modules that have hooks that modify default drupal behaviour and you may have to write your own context by extending the DrupalContext. 

Using Wodby (drupal4docker) to create our local development environment.

Using Wodby  to create a Drupal local development environment using docker. I have used the official Drupal ...