Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use docker with drupal and drush?

Tags:

I'd like to use drush. It needs to run in the drupal container. There's also a drush docker repo. But I have no clue how to make it available whithin the drupal container. It's my first docker and drupal project, so maybe I'm getting things completely wrong.

How can I use drush with this drupal docker image? https://hub.docker.com/_/drupal/ Is it possible to manage it with docker-compose? Maybe extending the drupal container?

This is my docker-compose.yml:

mysql:
  image: mysql:5.5
  ports:
    - "3306:3306"
  environment:
    - MYSQL_USER=xxxxx
    - MYSQL_PASSWORD=xxxxxx
    - MYSQL_ROOT_PASSWORD=xxxxxx
    - MYSQL_DATABASE=xxxxxx

drupal:
  image: drupal:8.0.4
  links:
    - mysql
  ports:
    - "8080:80"
like image 904
citizen404 Avatar asked Mar 02 '16 09:03

citizen404


People also ask

How do I run Drush on Drupal?

For example, a site that has the Search API module installed will have a different set of commands than one that does not. Drush can be run by typing drush from within your project's root directory -- or anywhere within the Drupal site.

What is the use of Drush in Drupal?

Drush is a tool in Drupal 8, which helps perform various tasks like website installation, configuration, and update from the command line. A website may require an update due to several reasons, such as security issues. Choosing to update the modules via conventional methods proves to be time-consuming task.


1 Answers

I have spent way too much time getting this to work. Here are my findings.

Like OP I never got the drush image to work on the local docker network so it seemed simpler to me to bundle drush via composer with the drupal image (see Dockerfile below).

That works somewhat, if you exec into the container you can run drush status, but it won't connect to the mysql server. There are two reasons for this:

  1. The package mysql-client is needed to connect remotely to the database (since we are running this on a local docker network).

  2. The mysql hostname needs to be explicitly set in the docker-compose file (or docker run command).


This is my Dockerfile:

FROM drupal:8.3.7-apache

# Install packages
RUN rm /bin/sh && ln -s /bin/bash /bin/sh && \
    apt-get update && apt-get install --no-install-recommends -y \
    curl \
    wget \
    vim \
    git \
    unzip \
    mysql-client

# Install Composer
RUN curl -sS https://getcomposer.org/installer | php && \
    mv composer.phar /usr/local/bin/composer && \
    ln -s /root/.composer/vendor/bin/drush /usr/local/bin/drush

# Install Drush
RUN composer global require drush/drush && \
    composer global update

# Clean repository
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

The important packages are curl (obviously) and mysql-client.

And these are the relevant parts of the docker-compose.yml:

version: '3.3'

services:

  drupal:
    image: drupal
    build: ./docker/drupal
    env_file:
      - ./docker/environment.env
    ports:
      - "8080:80"
    depends_on:
      - mysql
    restart: always

  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    volumes:
      - ./docker/phpmyadmin/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php
    env_file:
      - ./docker/intervention/environment.env
    ports:
      - "8080:80"
    depends_on:
      - mysql
    restart: always

  mysql:
    image: mysql
    build: ./docker/mysql
    env_file:
      - ./docker/environment.env
    hostname: mysql
    ports:
      - 3306:3306
    volumes:
      - mysql-data-d8:/var/lib/mysql
    restart: always

volumes:
  mysql-data-d8:

Why explicitly setting the hostname works

The second problem above is particularly devilish since drush use the configuration from settings.php to connect to mysql. But the 'host' key in the databases array is interpreted differently by drupal and drush apparently. Here is the relevant section from settings.php:

$databases = array (
  'default' => array (
    'default' => array (
      'database' => $envs['MYSQL_DATABASE'] ?? '',
      'username' => $envs['MYSQL_USER'] ?? '',
      'password' => $envs['MYSQL_PASSWORD'] ?? '',
      'host' => 'mysql',//php_sapi_name() === 'cli' ? 'a8597b38be21' : 'mysql',
      'port' => '3306',
      'driver' => 'mysql',
      'prefix' => 'drupal_',
      'charset' => 'utf8mb4',
      'collation' => 'utf8mb4_general_ci',
      'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
    ),
  ),
);

The out commented line after 'host' => 'mysql' is a previous attempt taken from another SO answer and illustrates the problem, drush use the command line server API which is different from whatever drupal uses. The alternate hostname is the hash id of the running container, which can be found by running the sql (from phpmyadmin for example):

SHOW VARIABLES WHERE Variable_name = 'hostname' (taken form this)

This value changes every time the container is updated, so to make it persist, the hostname is explicitely stated in docker-compose.yml, se above.


Edit: I've made a small project to host a drupal + drush + phpmyadmin development environment based on this: https://github.com/glaux/drupal8docker

like image 120
glaux Avatar answered Sep 19 '22 08:09

glaux