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. https://support.atlassian.com/bitbucket-cloud/docs/create-a-git-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: https://www.drupal.org/docs/develop/using-composer/using-composer-to-install-drupal-and-manage-dependencies
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.
Install Docker onto your host system: https://docs.docker.com/get-docker/
In addition to core Docker, we also want to install Docker-compose: https://docs.docker.com/compose/install/
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" services: nginx.local: image: webdevops/php-nginx-dev:7.4 container_name: "nginx" hostname: nginx.local environment: - 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_AUTOSTART=1 - XDEBUG_REMOTE_CONNECT_BACK=0 - XDEBUG_REMOTE_PORT=9021 - XDEBUG_REMOTE_HOST=host.docker.internal - WEB_DOCUMENT_ROOT=/app/web - PHP_MAX_EXECUTION_TIME=300 - PHP_MEMORY_LIMIT=-1 - PHP_DEBUGGER=xdebug ports: - "8100:80" volumes: # - ./:/app - d-sync:/app - ./nginx/vhost.conf:/opt/docker/etc/nginx/main.conf chrome: image: selenium/node-chrome:4.0.0-alpha-7-prerelease-20200907 container_name: chrome volumes: - ./dev/shm:/dev/shm depends_on: - selenium.local environment: - SE_EVENT_BUS_HOST=selenium.local - SE_EVENT_BUS_PUBLISH_PORT=4442 - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 - START_XVFB=false ports: - "6900:5900" selenium.local: image: selenium/hub:4.0.0-alpha-7-prerelease-20200907 hostname: selenium.local container_name: selenium.local ports: - "4444:4444" mariadb: image: wodby/mariadb:10.4-3.8.6 container_name: "d9_base_mariadb" stop_grace_period: 30s environment: MYSQL_ROOT_PASSWORD: pword MYSQL_DATABASE: drupal MYSQL_USER: drupal MYSQL_PASSWORD: pword volumes: ## Docker-sync for macOS users d-sync: 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 [https://docker-sync.readthedocs.io/en/latest/getting-started/installati…] 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.
Follow the instructions as guided, when it asks for DB connection details, if you are using the MariaDB container insert the following:
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)
- 172.17.0.1 (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