问题
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"
回答1:
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:
The package mysql-client is needed to connect remotely to the database (since we are running this on a local docker network).
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 this is 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 bu 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
回答2:
As always with Docker there are many options to use drush. But notice that in order drush to have access to the database (eg mysql) there should be volumes from mysql container on Drupal such as:
version: '2'
services:
drupal:
image: drupal:8.0.4-apache
volumes_from:
- mysql
mysql:
image: mysql
volumes:
- /var/lib/mysql
- /usr/bin
...
Here are the most common.
1) Mount your local drush to the Drupal container:
version: '2'
services:
drupal:
image: drupal:8.0.4-apache
volumes:
# Mount local drush to your container.
- /usr/local/bin/drush:/drush/drush
2) Create a data only docker image for drush and volume the executable to your Drupal container. See an example at https://github.com/RobLoach/drush-docker/issues/32#issuecomment-222321265.
3) Install Drush into Drupal container after it has run. Eg:
$ 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) Install Drush on Drupal by creating a Docker image (using a Dockerfile). Example:
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) Use another container with drush and volume it to the Drupal container using the docker-compose.yml. Example:
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
回答3:
In order to make Drush work effectively - you're better off running it from within the container that is running Drupal. For that, add a one liner in your 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/
For actual usage, you're better off shipping separate Drush aliases for usage - both from the container and the host (via public key SSH). As an example, look at these aliases and consider the entire setup as a reference implementation: https://github.com/srijanaravali/docker-blueprint/blob/master/docker-utils/drush/local.aliases.drushrc.php
You can transport these aliases into the container by having something like this in your Dockerfile:
# Push our aliases into the container ~/.drush
ADD /path/to/your/drush-aliases/* ~/.drush/
or - for shared control with the host, you can consider having it mounted as a volume in your docker-compose.yml.
volumes:
- ~/.drush/:/root/.drush/
You can now run Drush commands on the container like this: docker exec drush @alias <command>
. You can bash alias that to be something less keyboard intensive, ofcourse.
Or, Use drush from your host by invoking the SSH alias you shipped instead - drush @alias-ssh <command>
回答4:
One of the solutions for Drupal 8 - Docker - Drush combo is:
- Step: Installing the Drush in the image where you have the Apache server, let's call this docker image 'php5'.
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';
In this alias i use the Docker composer but it is the same with simple Docker, you runt the Drush command on the php5 image specifying where your drush is in Docker and where your codebase is on Docker. In this way you just use it like this:
dr5 cr
For the cache rebuild command, in you local code directory.
回答5:
Try something like https://github.com/wodby/docker4drupal. For me is very useful and flexible thing to develop Drupal with Docker.
回答6:
I think you have two options, you could run the drush/drush
container separately and use a shared hold volume so it has access to the files that drupal is going to use.
Or you could build a new image that contains both drush and drupal. See https://docs.docker.com/engine/userguide/containers/dockerimages/
You can probably use the Dockerfile for the drush image and the drupal image as guidance.
回答7:
What I chose to do, is install it will composer in my web
container.
First, I install composer and then I require Drush in the directory that I want.
Dockerfile example:
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
If Drush is already a dependency within the composer.json of your project you can just composer install
it.
来源:https://stackoverflow.com/questions/35743801/how-to-use-docker-with-drupal-and-drush