Skip to main content

In this section we will cover the steps needed to get a Drupal 9 site installed and running locally using docker and the code being hosted in BitBucket.


Create Bitbucket repository

A standard procedure at the beginning of any new project for us is to create a private BitBucket repository. There are alternatives such as GitHub, GitLab etc, but in the early days I picked BitBucket because you get free private repositories. In the years since they have massively added to their ecosystem with pipelines, Jira, Confluence, Trello and such and now I just think they are the better provider as a result. BitBucket Pipelines are crucial to this tutorial.

Follow this link to find out how to create a BitBucket account and create a new repository.


Install Drupal 9

The app we’re building is of course drupal 9. In your empty git directory, run the following command to install the Drupal codebase and any composer dependencies. *PHP and Composer are required for this step.

composer create-project drupal/recommended-project my_site_name_dir

Where my_site_name_dir you should change to your desired project name.

See full instructions here:

At this point we have the codebase, but we can’t yet run it as we haven’t configured our local hosting environment. I was quite late to party as far as Docker/containerisation is concerned, I always felt it created more problems than it solved. I’m a bit of a convert these days, it can be pretty cool… when it works.


Setup Docker

Install Docker onto your host system:

In addition to core Docker, we also want to install Docker-compose:

In your new code directory, add a new file docker-compose.yml. This will be used to spin up & down the containers that we need to serve the application locally (the setup differs slightly for test/production deployments). 

In this document, insert the following:

version: "3"

   image: webdevops/php-nginx-dev:7.4
   container_name: "nginx"
   hostname: nginx.local
     - PHP_DISMOD=ioncube,redis,memcached,apcu,bcmath,bz2,calendar,dom,exif,ftp,imagick,ldap,mongodb,mysqli,mysqlnd,pcre,pdo_pgsql,pgsql,posix,readline,Reflection,shmop,sockets,sodium,vips
     - XDEBUG_REMOTE_HOST=host.docker.internal
     - WEB_DOCUMENT_ROOT=/app/web
     - PHP_DEBUGGER=xdebug
     - "8100:80"
     #    - ./:/app
     - d-sync:/app
     - ./nginx/vhost.conf:/opt/docker/etc/nginx/main.conf
   image: selenium/node-chrome:4.0.0-alpha-7-prerelease-20200907
   container_name: chrome
     - ./dev/shm:/dev/shm
     - selenium.local
     - SE_EVENT_BUS_HOST=selenium.local
     - START_XVFB=false
     - "6900:5900"
   image: selenium/hub:4.0.0-alpha-7-prerelease-20200907
   hostname: selenium.local
   container_name: selenium.local
     - "4444:4444"
   image: wodby/mariadb:10.4-3.8.6
   container_name: "d9_base_mariadb"
   stop_grace_period: 30s
     MYSQL_DATABASE: drupal
     MYSQL_USER: drupal
     MYSQL_PASSWORD: pword
 ## Docker-sync for macOS users
   external: true


This configuration file contains the description and configuration for 4 different Docker containers:

  • Nginx - This container comes with the latest nginx and PHP 7.4 (with xdebug enabled)
  • Chrome - This is only needed for automated browser-based tests.
  • Selenium - This is only needed for automated browser-based tests.
  • MariaDB - This can be either used to host your Drupal database, or for testing only. If you want to use it instead of a DB on your host machine then make sure to add a persistent volume so that your DB isn’t lost when the container is shut down. For my purposes, this is only used for testing


Important note: one of the drawbacks of Docker is that sharing file systems can be problematic with performance hits to be expected, especially if your host is Mac or Windows. As I’m using Mac, I also had to setup Docker-sync […] to improve file synchronization and utilization. That’s what ‘d-sync’ refers to in the above config.

If you are not wanting to run automated tests, then you do not need to include chrome, selenium (potentially MariaDB) in this file.

Once setup, in your terminal (inside your code directory root) run the command:

docker-compose up -d

This will launch the containers specified in docker-compose.yml.

After they have launched, if you go to http://localhost:8100 in your browser, you should see the Drupal install screen.

Drupal setup screen


Follow the instructions as guided, when it asks for DB connection details, if you are using the MariaDB container insert the following:

Drupal database configuration


(from docker-compose.yml)

Database name:        drupal
Database username: drupal
Database password:  pword

Important node: in Host use the container id: mariadb

If you are using a DB server on your host machine, then fill out the credentials as per usual, but for Host use: 

  • host.docker.internal (Mac and Windows)
  • (Linux)

After completing the remaining installation, you should now have a working Drupal app working and ready for development. Congrats!

A couple of notes at this stage. 

If you are noticing pages are quite slow to load, one thing to check is your volume configuration. Sharing a filesystem between host and container can be a big bottleneck, not so much if your host is also Linux. For Mac it is definitely advised to use docker-sync.

The other thing I find helpful is changing between containers when debugging and general use. Running Xdebug WILL make pages load slow, but it is needed to step through code while debugging. 

When I need to debug I run the container:


And when I’m not debugging I run the container:


Running the latter container will have a dramatic improvement on page-load performance.


Previous section: Introduction

Next section: BitBucket pipelines

For more information on this topic, to ask questions, or to find out how we might be able to help you.

Please feel free to email:



Want to join our team?

Copyright © City Web Consultants Ltd. 2017. All Rights Reserved
Company number: 27234161

Want to start something?

Fantastic! We'd love to hear from you, whethere it's a pitch, an idea or just saying hello!

Feel free to get in touch.


Drop us an email?


Or give us a call?

+44 (0) 191 691 1296


Playing hard to get? We'll contact you