如何在Drupal和Drush中使用Docker?

23

我想使用 drush 工具,它需要在 drupal 容器中运行。同时也有一个drush docker 仓库。但我不知道如何在 drupal 容器中使用它。这是我第一个使用 docker 和 drupal 的项目,所以可能完全搞错了。

如何在此 drupal docker 镜像中使用 drush 工具? https://hub.docker.com/_/drupal/ 是否可以通过 docker-compose 来管理?也许可以扩展 drupal 容器吗?

这是我的 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"

我不明白你的问题,请提供更多关于你想要做什么的信息。 - dnephin
2
我想使用drush(https://github.com/drush-ops/drush)。它需要在Drupal容器中运行。还有一个drush docker仓库(https://hub.docker.com/r/drush/drush/)。但是我不知道如何在Drupal容器内部使其可用。这是我的第一个docker和drupal项目,所以也许我完全搞错了。 - citizen404
我和@citizen404处于同样的情况。 - That Brazilian Guy
9个回答

11

我花了太多时间让它正常工作。以下是我的研究结果。

像OP一样,我从未将drush镜像工作在本地docker网络上,因此对我来说,通过composer捆绑drush与drupal镜像更简单(请参见下面的Dockerfile)。

这在某种程度上可以工作,如果您进入容器,可以运行drush status,但它无法连接到mysql服务器,原因有两个:

  1. 需要安装mysql-client软件包以远程连接到数据库(由于我们正在本地docker网络上运行)。

  2. 必须在docker-compose文件(或docker run命令)中明确设置mysql主机名。


以下是我的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/*

重要的软件包是curl(显然)和mysql-client

以下是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:

明确设置主机名为什么有效

上述第二个问题特别麻烦,因为Drush使用settings.php中的配置来连接mysql。但是数据库数组中的“host”键被Drupal和Drush显然以不同的方式解释。以下是从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',
    ),
  ),
);

'host' => 'mysql' 后面的注释行是从另一个SO答案中获取的先前尝试,并说明了问题,drush使用命令行服务器API,与drupal使用的不同。备用主机名是运行容器的哈希ID,可以通过运行sql(例如来自phpmyadmin)找到:

SHOW VARIABLES WHERE Variable_name = 'hostname'(来自这里

每次更新容器时,此值都会更改,因此为了使其持久化,主机名在docker-compose.yml中明确声明,如上所述。


编辑:我创建了一个小项目,用于基于此托管drupal + drush + phpmyadmin开发环境:https://github.com/glaux/drupal8docker


1
为什么在Dockerfile中的第一件事就是删除/bin/sh?它只是一个微小的二进制文件,这似乎很奇怪。 - Jack_Hu
@Jack_Hu 老实说,我一点也不清楚。那段代码是我很久以前找到的一个例子,我从来没有仔细考虑过它。 - glaux
谢谢!我已经尝试了一段时间来解决这个问题。 - Jry
@Jack_Hu /bin/sh 不是简单地被删除。它被替换为指向 /bin/bash 的符号链接。请查看链中的第二个命令:rm /bin/sh && ln -s /bin/bash /bin/sh - Chris
@Chris - 是的,我看到了...但是。它没有使用任何bash功能,即使它使用了,将bash设置为默认shell,或明确指定/bin/bash,或者其他大量选项都是更可取的。微调系统,让您认为某些代码在标准POSIX shell中执行,而实际上它是在bash中运行,这只是一个可怕的想法。也许三四年后,当您明确在sh中运行参数时,会bash(无意冒犯)头撞在墙上,想知道为什么参数正在扩展。 - Jack_Hu
@Jack_Hu 我完全同意。只是你的第一条评论没有那么明确地表达出来... :-) - Chris

5

在使用Docker时,有许多选项可供使用drush。但请注意,在Drupal上,为了使drush能够访问数据库(如mysql),应该从mysql容器中挂载卷,例如:

 version: '2'
 services:
   drupal:
     image: drupal:8.0.4-apache
     volumes_from:
       - mysql
   mysql:
     image: mysql
     volumes:
       - /var/lib/mysql
       - /usr/bin
...

以下是最常见的方法:
1)将你的本地drush挂载到Drupal容器中:
version: '2'
services:
  drupal:
    image: drupal:8.0.4-apache
    volumes:
      # Mount local drush to your container.
      - /usr/local/bin/drush:/drush/drush

2) 创建一个仅包含数据的docker镜像,将可执行文件挂载到你的Drupal容器中。可以参考这个例子:https://github.com/RobLoach/drush-docker/issues/32#issuecomment-222321265.

3) 在Drupal容器运行后安装Drush。例如:

$ docker exec -ti <MY_DRUPAL_CONTAINER> \ 
bash -c 'php -r "readfile('https://s3.amazonaws.com/files.drush.org/drush.phar');" \
> drush  && chmod +x drush && mv drush /usr/local/bin'

4) 通过创建一个 Docker 镜像(使用 Dockerfile)在 Drupal 上安装 Drush。例如:

FROM drupal:8.0.4-apache

MAINTAINER ...

RUN php -r "readfile('https://s3.amazonaws.com/files.drush.org/drush.phar');" > drush \
&& chmod +x drush \
&& mv drush /usr/local/bin

5)使用另一个容器和drush,并通过docker-compose.yml将其挂载到Drupal容器中。例如:

version: '2'
services:
  drupal:
    image: drupal:8.0.4-apache
    volumes_from:
      - drush
  drush:
    image: drush/drush
    volumes:
      - /usr/local/bin/drush
      - /usr/local/bin/composer

1
我尝试了第五种方法,但是出现了以下错误:ERROR: for drush 无法为服务drush创建容器:b'无法在现有文件上挂载卷,文件已存在 /var/lib/docker/overlay2/37b3bf71181740b62dcd1e0ca812caf1aab398228cd2a22fc7803954d8765b70/merge d/usr/local/bin/drush' - GuyPaddock
#4 非常顺利。已经有了 Dockerfile,所以非常简单。谢谢! - Robert_T_Taylor
1
@GuyPaddock 我认为答案中的第5点是错误的;你不能将文件挂载为卷。请参见这里:"通常情况下,你可以从drush/drush镜像中挂载drush可执行文件,但由于文件不允许挂载,所以你不能这样做。" - jeff-h

4
为了让Drush有效地工作 - 最好从运行Drupal的容器内运行它。为此,在Dockerfile中添加一行代码即可实现。
# Set base Image/tag here. 
FROM drupal:8-fpm 
# Get a global installation of Drush on the web / drupal container 
RUN php -r "readfile('http://files.drush.org/drush.phar');" > drush && chmod +x drush && mv drush /usr/bin/

对于实际使用,最好使用独立的 Drush 别名 - 通过容器和宿主机(通过公钥 SSH)进行使用。例如,请查看这些别名,并将整个设置视为参考实现:https://github.com/srijanaravali/docker-blueprint/blob/master/docker-utils/drush/local.aliases.drushrc.php

您可以通过在 Dockerfile 中添加以下内容来将这些别名传输到容器中:

# Push our aliases into the container ~/.drush 
ADD /path/to/your/drush-aliases/* ~/.drush/

或者 - 如果想要与主机共同控制,您可以考虑在 docker-compose.yml 文件中将其作为卷挂载。

volumes:
  - ~/.drush/:/root/.drush/

现在您可以像这样在容器上运行Drush命令:docker exec drush @alias <command>。当然,您可以将其别名为更少键盘输入的内容。
或者,通过调用您提供的SSH别名来使用主机上的drush - drush @alias-ssh <command>

1

Drupal 8 - Docker - Drush 组合的解决方案之一是:

  1. Step: Installing the Drush in the image where you have the Apache server, let's call this docker image 'php5'.
  2. Step: make an alias in your ~/.bashrc file like this:

    alias dr5='docker-compose run php5 /root/.composer/vendor/bin/drush --root=/var/www/html/docroot';
    

在这个别名中,我使用Docker composer,但是对于简单的Docker来说是一样的,您可以在php5镜像上运行Drush命令,指定您的Drush在Docker中的位置以及您的代码库在Docker中的位置。这样,您只需像这样使用它:

dr5 cr

对于缓存重建命令,在您的本地代码目录中。


1

0
有很多方法,我强烈推荐使用DDEV 查看安装过程: https://ddev.readthedocs.io/en/latest/users/install/ddev-installation/ 在Linux安装后: mkdir my-drupal10-site
cd my-drupal10-site

ddev config --project-type=drupal10 --docroot=web --create-docroot

ddev start 

使用以下命令安装Drupal推荐项目:ddev composer create drupal/recommended-project
使用以下命令安装Drush:ddev composer require drush/drush
使用以下命令进行Drupal安装:ddev drush site:install --account-name=admin --account-pass=admin -y
使用以下命令生成登录链接:ddev drush uli
使用以下命令启动开发环境:ddev launch
通过composer命令可以轻松安装Drush。

0

我认为你有两个选择,可以单独运行drush/drush容器,并使用共享卷使其可以访问Drupal要使用的文件。

或者你可以构建一个包含drush和drupal的新镜像。请参见https://docs.docker.com/engine/userguide/containers/dockerimages/

你可以使用drush镜像和drupal镜像的Dockerfile作为指南。


0

0
我选择的做法是在我的web容器中使用composer进行安装。
首先,我安装了composer,然后在我想要的目录中需要Drush。
Dockerfile示例:
FROM php:7.1-apache

RUN a2enmod rewrite

# Install dependencies
RUN apt-get update \
    && apt-get install -y git \
    && docker-php-ext-install pdo pdo_mysql \
    && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
    && php -r "if (hash_file('SHA384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
    && php composer-setup.php \
    && php -r "unlink('composer-setup.php');" \
    && mv composer.phar /usr/local/bin/composer

RUN cd /var/www/html \
    && composer require drush/drush

如果Drush已经是您项目中composer.json的依赖项,您只需运行composer install即可安装它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接