Wodby Drupal

Hello Jeremy and thank you for response, I didn't get any docker errors, it juste saying 'getway time out' when I tried to connect to the urls mention in my docker-composer.yml ( zakaria.project2.localhost:82 and zakaria.project.localhost:82 ). PHP docker container image for Drupal. Contribute to wodby/drupal-php development by creating an account on GitHub. Vanilla Drupal: ⬆️ Updated: 9.1.0, 8.9.11, 7.77; ↩️ Drupal console returned to Drupal 8 image; PHP: ⭐️ PHP 8 (not all pecl extensions supported, see wodby/php#129 for more details) 🗑 PHP 7.2 dropped (EOL) ⬆️ Updates 7.4.13, 7.3.25; ⬆️ Drupal console launcher updated to 1.9.7; ⬆️ Updated pecl extensions: ast 1.0.10. Wodby 1.0 documentation. This changelog is for Solr for Drupal stack on Wodby, to see image changes see tags description on repository page.

Docker4Drupal is an open-source project (GitHub page) that provides pre-configured docker-compose.yml file with images to spin up local environment on Linux, Mac OS X and Windows.


  • Install Docker (Linux, Docker for Mac or Docker for Windows (10+ Pro))
  • For Linux additionally install docker compose


Database data persistence

By default Docker will create a persistent volume for your DB data and unless you explicitly remove volumes the files will not be deleted. However, if you run docker-compose down (it's ok to use stop though) these volumes will not be reattached when you run docker-compose up. If you want to have your DB data all-time persistent and attached, we recommend using a bind mount. To use a bind mount uncomment to corresponding line under db server's volumes: in your docker-compose.yml and update the host path to your data directory.

There are 2 options how to use docker4drupal – you can either run vanilla Drupal from the image or mount your own Drupal codebase:

Vanilla Drupal¶

  1. Clone docker4drupal repository and switch to the latest stable tag or download/unpack the source code from the latest release
  2. Optional: for Drupal 8 or 7 comment out corresponding DRUPAL_TAG and NGINX_VHOST_PRESET in .env file
  3. From project root directory run docker-compose up -d or make up to start containers. Give it 10-20 seconds to initialize after the start
  4. That's it! Proceed with Drupal installation at http://drupal.docker.localhost:8000. Default database user, password and database name are all drupal, database host is mariadb
  5. You can see status of your containers and their logs via portainer: http://portainer.drupal.docker.localhost:8000

Mount my codebase¶

  1. If you're starting a new project we recommend you to fork drupal-composer/drupal-project project
  2. Download and unpack docker4drupal.tar.gz from the latest stable release to your project root
  3. Delete docker-compose.override.yml as it's used to deploy vanilla Drupal
  4. Ensure NGINX_SERVER_ROOT (or APACHE_DOCUMENT_ROOT) is correct, by default set to /var/www/html/web for composer-based projects where Drupal is in web subdirectory
  5. Ensure database access settings in your settings.php corresponds to values in .env file, e.g.:
  6. Optional: for Drupal 8 or 7 update NGINX_VHOST_PRESET correspondingly in your .env file
  7. Optional: uncomment lines in the compose file to run redis, solr, varnish, etc
  8. Optional: import existing database
  9. Optional: macOS users please read this
  10. Optional: Windows users please read this
  11. Run containers: make up or docker-compose up -d
  12. Your drupal website should be up and running at http://drupal.docker.localhost:8000
  13. You can see status of your containers and their logs via portainer: http://portainer.drupal.docker.localhost:8000

You can stop containers by executing make stop or docker-compose stop.

Optional files

If you don't need to run multiple projects and don't use mutagen to improve bind mounts performance on macOS feel free to delete traefik.yml and mutagen that come within docker4drupal.tar.gz

Get updates

We release updates to images from time to time, you can find detailed changelog and update instructions on GitHub under releases page


Traefik container used for routing. By default, we use port 8000 to avoid potential conflicts but if port 80 is free on your host machine just replace traefik's ports definition in the compose file.

By default BASE_URL set to drupal.docker.localhost, you can change it in .env file.

Add drupal.docker.localhost to your /etc/hosts file (some browsers like Chrome may work without it). Do the same for other default domains you might need from listed below:



Xdebug troubleshooting

Enable xdebug logs to get more information by adding $PHP_XDEBUG_REMOTE_LOG=/tmp/php-xdebug.log environment variable to PHP container

Debugging web requests¶

  1. Uncomment these lines for PHP service in your docker-compose file (environment variables changed since xdebug 3.x)
  2. Restart containers (make)
  3. Start debugging in IDE
  4. Start your browser debug helper plugin (Chrome or Firefox) and open the page you want to debug. Alternatively, enable auto start by adding PHP_XDEBUG_START_WITH_REQUEST: 'yes'

Debugging CLI requests¶

  1. Enable Xdebug as described in the previous section
  2. Uncomment the following environment variables for PHP service in your composer file
  3. Perform configuration as described below depending on your OS and Docker version:

Linux, Docker¶

  1. Uncomment PHP_XDEBUG_REMOTE_HOST: for PHP service
  2. Restart containers (make)

macOS, Docker¶

  1. Uncomment PHP_XDEBUG_REMOTE_HOST: host.docker.internal for PHP service
  2. Restart containers (make)


  1. Uncomment PHP_XDEBUG_REMOTE_HOST: host.docker.internal for PHP service
  2. Restart containers (make)
  3. Allow listen connection for your IDE in Windows Firewall > Allow an app ..

Also, you might need to update your hosts file.

IDE configuration¶

You must additionally configure your IDE to debug CLI requests.


  1. Open Run > Edit Configurations from the main menu, choose Defaults > PHP Web Page in the left sidebar
  2. Click to [...] to the right of Server and add a new server
    • Enter name my-ide (as specified in PHP_IDE_CONFIG)
    • Enter any host, it does not matter
    • Check Use path mappings, select path to your project and enter /var/www/html in the right column (Absolute path on the server)
  3. Choose newly created server in 'Server' for PHP Web Page
  4. Save settings


Crond enabled by default and runs every hour. The default command is:

You might need to change if your HTTP root is different. Runs from www-data user.

Database import and export¶


Known issues with indexes rebuild

Wodby/drupal-php Docker Hub

Issues have been reported when MariaDB does not build indexes when dump imported using mariadb-init bind mount. For safety use the workaround described at https://github.com/wodby/mariadb/issues/11

if you want to import your database, uncomment the line for mariadb-init bind mount in your compose file. Create the directory ./mariadb-init in the same directory as the compose file and put there your .sql .sql.gz .sh file(s). All SQL files will be automatically imported once MariaDB container has started.

Exporting all databases:

Exporting a specific database:


if you want to import your database, uncomment the line for postgres-init volume in your compose file. Create the volume directory ./postgres-init in the same directory as the compose file and put there your .sql .sql.gz .sh file(s). All SQL files will be automatically imported once Postgres container has started.

Make commands¶


We provide Makefile that contains commands to simplify the work with your local environment. You can run make [COMMAND] to execute the following commands:


Docker for mac¶

There two major problems macOS users face with when using Docker for mac:

macOS permissions issues¶

To avoid any permissions issues caused by different user id (uid), group id (gid) between your host and a container use -dev-macos version of php image (uncomment the environment variables in .env files) where the default user wodby has 501:20 uid/gid that matches default macOS user.

Bind mounts performance¶

By default, we use :cached option on bind mounts to improve performance on macOS (on Linux it behaves similarly to consistent). You can find more information about this in docker blog. However, there's the synchronisation with Mutagen which is a faster alternative.


The core idea of this project is to use an external volume that will sync your files with a file synchronizer tool.

  1. Uncomment Mutagen volume and service definitions in your compose file
  2. Replace codebase volumes definitions of services with the option below marked as 'Mutagen'
  3. Start the mutagen container docker-compose up -d mutagen
  4. Start Mutagen: mutagen project start -f mutagen/config.yml (or just run make mutagen instead of steps 3 and 4)
  5. Start other containers docker-compose up -d (or make)
  6. When you no longer need mutagen run mutagen project terminate

Now when you change your code on the host machine Mutagen will sync your data to php and nginx/apache containers.

For more information visit Mutagen project page.

Permissions issues¶

You might have permissions issues caused by non-matching uid/gid on your host machine and the default user in php container.


Since version 5.0 the default php container user wodby has uid/gid 1000 that matches the default uid/gid for most popular Linux distributions.


Use -dev-macos version of php image where default wodby user has 501:20 uid/gid that matches default macOS user.


Since you can't change owner of mounted volumes in Docker for Win, the only solution is to run everything as root, add the following options to php service in your docker-compose file:

Different uid/gid?¶

You can rebuild the base image wodby/php with custom user/group ids by using docker build arguments WODBY_USER_ID, WODBY_GROUP_ID (both 1000 by default)

Running multiple Projects¶

This project uses træfik to route traffic to different containers. Træfik is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease. To understand the basics of Traefik it is suggested to check Træfik's documentation page: https://docs.traefik.io/

Image: Multi-domain set-up example(Source: traefik.io)

There are two ways how you can run multiple projects:

Single port¶

In this case you will run a stand-alone traefik that will be connected to docker networks of your projects:

  1. Download traefik.yml file (part of docker4x.tar.gz archive). Place it separately from your projects, it will be a global traefik container that will route requests to your projects on a specified port
  2. Now we need to provide traefik names of docker networks of our projects. Let's say projects directories with docker-compose.yml named foo and bar. Docker Compose will create default docker networks for these projects called foo_default and bar_default. Update external networks names accordingly in traefik.yml
  3. In docker-compose.yml of your projects comment out traefik service and make sure traefik.http.* labels have ${PROJECT_NAME}_ prefix
  4. Make sure$PROJECT_BASE_URL and $PROJECT_NAME (in .env file) differ, both hosts point to in /etc/hosts
  5. Run your projects: make (or docker-compose up -d)
  6. Run stand-alone traefik: docker-compose -f traefik.yml up -d
  7. Now when you visit URL from $PROJECT_BASE_URL, traefik will route traffic to the corresponding docker networks

Different ports¶

Alternatively, instead of running a stand-alone traefik, you can just run default traefik containers on different ports. Just a few things to make sure:

  • Ports of traefik service in your docker-compose.yml files differ
  • traefik.http.* labels have ${PROJECT_NAME}_ prefix
  • $PROJECT_BASE_URL and $PROJECT_NAME (in .env file) differ, both hosts point to in /etc/hosts

Storybook is an open-source tool for developing UI components for React, Svelte, Vue, Mithril, Web Components, and other similar systems. It's an evolution of design system frameworks and style kits like Pattern Lab, Zurb Foundation, or Bootstrap.

Over the years we've released various integrations with these tools for Drupal 7 through Drupal 9, providing popular theme implementations for Neato and Zurb Foundation, plus dozens of custom themes for projects based around Pattern Lab. These days, we find ourselves relying more on Storybook for new projects and less on older generation design systems.

The most common problem we've identified through implementation, README documentation, issue queues, and demos is that wrangling all the required resources to run tools like Storybook locally can be really tough. The mix of operating systems and configurations from computer to computer makes it difficult to provide a streamlined onboarding technique. Installation and development experiences vary from person to person.

That's where Docker comes in.

Run Storybook in Docker

We've been running Drupal in Docker since the start of 2018. Gone are the days of Virtualbox and Vagrant, for many of the same reasons we've already noted. The goal is consistent, predictable, and scalable onboarding for local development, and Docker can give that to us easily.

Assuming you're already running a project in Docker (there are numerous community and commercially supported Docker stacks out there), you can create a container for Storybook in just a few lines of code in your docker-compose.yml file:

This provides you with two Node containers. One for executing Node tasks as a service, and the other for serving Storybook on your machine. We use Traefik to expose the Storybook container at the URL 'storybook.myproject.docker.localhost'.

The Storybook container is passed a command to run when the container is started. This executes the start-storybook command using the ./build folder in the container as the root, specifying port 8080.

With those two containers in place, anyone working on the project now has the ability to work on and view Storybook without having to install the correct version of NodeJS or NVM, deal with differences in Windows vs Mac vs Linux, or worry about any other host of issues. It also reduces the technical barrier of entry for project participants from hours to seconds. All that's required is checking out the code and starting your containers.

Now anyone on the team, developer and non-developer alike, can jump in at any point in the project and access the UI components in their browser:

Running Node Tasks in Docker


Now that you don't need project members to install Node or related tools, you need a way to do execute NPM/Gulp/Node inside the Docker container. The good news is nothing changes about these commands. The only change is the system that executing them.

Let's say you want to run a Gulp task called 'build'. Under a project controlled by Docker, that command could look like this:

This is also tough for users unfamiliar with Docker. It can be a lot to remember, especially if you're running these tasks a lot. We solved this in our projects by also shipping them with an Ahoy! yaml file providing simple abstracted commands to get the same result:

That long command above can now be done as:

Developers and designers of any skillset can load, run, and build for Storybook without needing to know about installing software and package dependencies on their machine or getting hung up on any number of hurdles in that process.

This ensures the same consistent result across the board in local development - no more issues with build servers or team members having slightly different versions of Node or NPM packages.


Wodby Drupal Console

Since this is also based on Docker, the commands can be used in a build/deploy continuous integration pipeline with the same images. An example GitLab CI job may look like the following:

Integrating to Drupal 9

Now you have one codebase powering two applicationsStorybook and Drupal 9 in Docker. Both are accessible in the browser, and all your tools are available via the provided Ahoy! command file. Developers and designers can work in one codebase without stepping on each other's toes and the flexibility of Docker can allow more skilled developers to create additional integrations without interfering with anyone else's workflow.

Integrating Storybook and Drupal 9 can be done using the Components module. The Components module provides a way for developers to register namespaces in their Twig templates to reference any defined path in the project—not just ones limited to a specific set of directories. Examples of this implementation can be seen with the Bootstrap Storybook theme project, bridging the two together. Amazee Labs has a great series of posts around GraphQL, Twig and Storybook for Drupal. The Emulsify design system for Drupal provides another great example of integrating Storybook with Drupal.

Whidbey Drupal

You can also just start with your own Storybook as we did above and work it into your project, based on your own needs. We have created several custom themes for clients and delivered the same tools in this article to their teams. We can provide assistance tailoring a Storybook design system and styleguide for your organization and integrating it with Drupal and other web properties.

Wodby Drupal 9

Reach out today to talk about how we can enable your teams on Drupal 9 and Storybook for your next project.