• Twitter
  • GitHub
  • Flickr
  • Skype
  • Stack Overflow em Português

Blog

Como instalar o Drupal via Composer num ambiente de desenvolvimento Docker?: Conteúdo atualizado - junho 2020 Como dito no Wikipédia, “Drupal é um framework modular e um...

Como instalar o Drupal via Composer num ambiente de desenvolvimento Docker?

Conteúdo atualizado - junho 2020

Como dito no Wikipédia, “Drupal é um framework modular e um sistema de gerenciamento de conteúdo (CMS) escrito em PHP. O Drupal permite criar e organizar conteúdo, manipular a aparência, automatizar tarefas administrativas e definir permissões e papéis para usuários e colaboradores.”

Você pode usá-lo para criar uma ampla variedade de aplicativos da Web, de sites básicos a elaborados monólitos orientados à API.

Antes de começar, vou assumir que você já tem alguma experiência com Docker e deseja executar suas aplicações em containers, possibilitando o empacotamento de uma aplicação e todas as suas dependências.

É possível instalar o Drupal localmente no seu computador Linux, Mac ou Windows. E neste guia demonstraremos seu funcionamento em ambiente Linux com Docker. Você aprenderá a montar o ambiente necessário, seus requisitos e instalar o sistema Drupal 8 utilizando o Composer.

A primeira coisa que você tem a fazer é, naturalmente, instalar o Docker o segundo pré-requisito é ter o Docker Compose e o terceiro, o Composer. Vamos entender aqui que, Docker Compose é uma coisa e Composer outra. Docker Compose é o orquestrador de containers da Docker. Com ela é possível configurar todos os parâmetros necessários para executar cada container a partir de um arquivo de definição. Já o Composer é um gerenciador de pacotes em nível de aplicativo para a linguagem de programação PHP que fornece um formato padrão para gerenciar dependências do software PHP e bibliotecas necessárias.

Estrutura de Diretórios do Projeto

Primeiramente crie um diretório meu-projeto/, em seguida os subdiretórios (app/, db-data/, php-apache/) mais o arquivo docker-compose.yml.

Teremos algo como exibido na imagem:

Estrutura de Diretórios do Projeto

app/ - Conterá os arquivos do projeto, mais o diretório público (app/web) com os arquivos Drupal. Há persistência de dados, não há risco do container cair ou ser removido e os dados desaparecerem;

db-data/ - Volume para persistência de dados, não há risco do container cair ou ser removido e os dados desaparecerem;

php-apache/ - Colocaremos os arquivos Dockerfile e vhosts.conf;

docker-compose.yml - Arquivo de composição para configurar os serviços do aplicativo.

Dockerfile

Para definir um ambiente de desenvolvimento mínimo com Docker, vamos aproveitar os requisitos já configurados no Dockerfile do projeto Drupal que está no Docker Hub. Na página oficial da imagem Drupal no Docker Hub, logo no primeiro item de tags suportadas com servidor Apache - 8.x.x-apache, há o respectivo link do Dockerfile. Ao clicar, acessaremos o Dockerfile no GitHub – docker-library/drupal. Utilizaremos este Dockerfile, que deve ser salvo no diretório do projeto, em: meu-projeto/php-apache/.

Vale lembrar que alguns módulos individuais para Drupal podem ter requisitos específicos para extensões e configurações do PHP além dos que estão no Dockerfile; portanto, verifique também a documentação do módulo. Se você precisar de extensões PHP adicionais, consulte: How to install more PHP extensions

Veja que no momento que escrevo este artigo, a versão Drupal é a 8.7.9, porém o Dockerfile do projeto no Docker Hub ainda se encontra na versão 8.7.8. A instalação via Composer nos trará realmente a última versão, no caso 8.7.9.

Vamos realizar uma pequena modificação no final do arquivo ao removermos a parte responsável pelo download e descompactação do Drupal. Pois a instalação do CMS Drupal será feita via Composer, e no momento precisamos do ambiente necessário para o mesmo.

Vamos alterar o Dockerfile removendo a linha referente ao download e descompactação do arquivo Drupal.

Mesmo que a versão no Dockerfile esteja atualizada para 8.7.9, o que não é o caso no momento, remova o trecho:

# https://www.drupal.org/node/3060/release
ENV DRUPAL_VERSION 8.7.8
ENV DRUPAL_MD5 f281eb14d8aabf0c3e78dd519ca4b640
 
RUN set -eux; \
    curl -fSL "https://ftp.drupal.org/files/projects/drupal-${DRUPAL_VERSION}.tar.gz" -o drupal.tar.gz; \
    echo "${DRUPAL_MD5} *drupal.tar.gz" | md5sum -c -; \
    tar -xz --strip-components=1 -f drupal.tar.gz; \
    rm drupal.tar.gz; \
    chown -R www-data:www-data sites modules themes	

Logo, adicionamos a linha responsável pela inclusão do arquivo de configuração vhosts.conf, que será copiado do nosso diretório php-apache/vhosts.conf para o servidor.

Trecho adicionado:

#Adicionado
RUN set -eux; \
    rm -f /etc/apache2/sites-enabled/000-default.conf
COPY vhosts.conf /etc/apache2/sites-enabled/vhosts.conf

Dockerfile alterado:

# from https://www.drupal.org/docs/8/system-requirements/drupal-8-php-requirements
FROM php:7.3-apache-stretch
# TODO switch to buster once https://github.com/docker-library/php/issues/865 is resolved in a clean way (either in the PHP image or in PHP itself)

# install the PHP extensions we need
RUN set -eux; \
	\
	if command -v a2enmod; then \
		a2enmod rewrite; \
	fi; \
	\
	savedAptMark="$(apt-mark showmanual)"; \
	\
	apt-get update; \
	apt-get install -y --no-install-recommends \
		libfreetype6-dev \
		libjpeg-dev \
		libpng-dev \
		libpq-dev \
		libzip-dev \
	; \
	\
	docker-php-ext-configure gd \
		--with-freetype-dir=/usr \
		--with-jpeg-dir=/usr \
		--with-png-dir=/usr \
	; \
	\
	docker-php-ext-install -j "$(nproc)" \
		gd \
		opcache \
		pdo_mysql \
		pdo_pgsql \
		zip \
	; \
	\
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
	apt-mark auto '.*' > /dev/null; \
	apt-mark manual $savedAptMark; \
	ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \
		| awk '/=>/ { print $3 }' \
		| sort -u \
		| xargs -r dpkg-query -S \
		| cut -d: -f1 \
		| sort -u \
		| xargs -rt apt-mark manual; \
	\
	apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
	rm -rf /var/lib/apt/lists/*

# set recommended PHP.ini settings
# see https://secure.php.net/manual/en/opcache.installation.php
RUN { \
		echo 'opcache.memory_consumption=128'; \
		echo 'opcache.interned_strings_buffer=8'; \
		echo 'opcache.max_accelerated_files=4000'; \
		echo 'opcache.revalidate_freq=60'; \
		echo 'opcache.fast_shutdown=1'; \
	} > /usr/local/etc/php/conf.d/opcache-recommended.ini

WORKDIR /var/www/html

#Adicionado
RUN set -eux; \
    rm -f /etc/apache2/sites-enabled/000-default.conf
COPY vhosts.conf /etc/apache2/sites-enabled/vhosts.conf

O arquivo vhosts.conf definirá o diretório raiz da web, que armazenará os pacotes de arquivos Drupal. Então crie o arquivo vhosts.conf no diretório meu-projeto/php-apache/ com o seguinte conteúdo:

DirectoryIndex index.php index.html
 
<VirtualHost *:80>
  ServerName localhost
  DocumentRoot "/var/www/html/web/"
 
  <Directory "/var/www/html/web/">
    AllowOverride All
    Options -Indexes +FollowSymLinks
    Require all granted
  </Directory>
</VirtualHost>

Docker Compose

O Docker Compose é uma ferramenta para definir e executar aplicativos Docker de vários contêineres. Com ele, é possível usar um arquivo YAML para configurar os serviços do seu aplicativo.

Seu uso segue basicamente um processo de três etapas:

  • Defina o ambiente do seu aplicativo com um Dockerfile para que ele possa ser reproduzido em qualquer lugar.
  • Defina os serviços que compõem seu aplicativo docker-compose.yml para que eles possam ser executados juntos em um ambiente isolado.
  • Rode docker-compose up para iniciar e executar todo o aplicativo.

Implantação da Pilha do Docker

Ao criar o arquivo docker-compose.yml, definimos os serviços: drupal e mariadb.

O arquivo docker-compose.yml, deve ser salvo na raiz do projeto, em meu-projeto/ com o seguinte conteúdo:

version: '3.3'
 
services:
  drupal:
    build: ./php-apache
    ports:
      - 8080:80
    volumes:
      - ./app:/var/www/html:rw,delegated
    restart: always
 
  mariadb:
   image: mariadb:latest
   environment:
    MYSQL_RANDOM_ROOT_PASSWORD: 1
    MYSQL_DATABASE: dev
    MYSQL_USER: dev
    MYSQL_PASSWORD: dev123
   volumes:
    - ./db-data:/var/lib/mysql
   restart: always
   command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci']
   ports:
    - "3306:3306"
 
volumes:
  html:
  db-data:

O serviço drupal criará o container com a imagem a partir de um Dockerfile que se encontra no diretório meu-projeto/php-apache/. Para o banco de dados, o serviço é nomeado mariadb e não será preciso usar um Dockerfile, pois a imagem é definida diretamente no próprio docker-compose.yml com os respectivos atributos, relacionamentos, variáveis de ambiente e o volume é pareado com o diretório local meu-projeto/db-data/, com charset (utf8mb4_unicode_ci) como recomendado para uma instalação Drupal. Que nos informa sobre COLLATION utf8mb4_unicode_ci ou utf8mb4_general_ci. A diferença entre os dois agrupamentos está relacionada à comparação e classificação de caracteres. utf8mb4_general_ci é um pouco mais rápido, no entanto utf8mb4_unicode_ci é mais preciso para uma variedade maior de caracteres. Se não tiver certeza, use utf8mb4_unicode_ci.

Vamos levantar o nosso servidor para iniciar todos os serviços que estão no arquivo docker-compose.yml. Estando no mesmo diretório do projeto meu-projeto/, no terminal rode o comando que vai executar de fato o Compose:

$ docker-compose up

Após todo processo de configuração do ambiente, ao acessar localhost:8080 recebemos o aviso Not Found, pois não temos os arquivos Drupal na pasta app/web/ que foi definida em nosso arquivo meu-projeto/vhosts.conf.

Vamos então à instalação do Drupal!

Usando o Composer para Instalar o Drupal e Gerenciar Dependências

Conforme informado no site oficial do Drupal, a maneira recomendada de obter o código fonte do Drupal é usando o Composer — um gerenciador de dependências PHP. Com o Composer você executa não somente uma instalação Drupal, mas tudo que envolva projetos contribuídos pelo Drupal (módulos, temas, etc.) e todas as suas respectivas dependências.

Para criar um projeto usando o Composer, você pode usar o comando create-project. Isso é o equivalente a fazer um checkout git clone/svn seguido por um composer install. Passe um nome de pacote e o diretório no qual o projeto será criado. Você também pode fornecer uma versão como terceiro argumento, caso contrário, a versão mais recente será usada. Se o diretório não existir atualmente, ele será criado durante a instalação. O processo de criação pode ser lento, porém há uma maneira de acelerar o processo de instalação. Com o prestissimo (plugin do composer) - um plug-in do composer que baixa os pacotes em paralelo para acelerar o processo de instalação.

Basta realizar a instalação antes de rodar o comando create-project:

$ composer global require hirak/prestissimo

Para criar um projeto usando o Composer. Vá para o diretório raiz do projeto meu-projeto/ e execute o comando:

Conteúdo atualizado.

$ composer create-project drupal-composer/drupal-project:8.x-dev app --no-interaction

Isso fará o download da versão mais recente do projeto drupal-composer/drupal-project para a pasta do projeto (neste nosso exemplo, denominado 'app').

Não fique confuso com o 8.x-dev no comando. Ele instala uma versão estável do Drupal 8 e todas as suas dependências ao executar automaticamente o composer install. Sendo assim, no diretório ‘app/’, conterá os arquivos que devem estar fora da raiz da web e não acessíveis pelo daemon do servidor da web, como composer.json, a pasta vendor etc. A raiz da web com o Drupal 8 será ‘app/web’, como configurado anteriormente no arquivo vhosts.conf.

Drupal 8.8.0

Desde o lançamento do Drupal 8.8.0 — o modelo recomendado foi alterado de drupal-composer/drupal-project para o oficialmente suportado: drupal/recommended-project

O projeto drupal/recommended-project cria um novo site Drupal com uma ‘raiz de documento realocada’. Isso significa que os arquivos ‘index.php’ e o diretório ‘core’ etc. são colocados dentro de uma subpasta chamada ‘web’ em vez de serem colocados ao lado de ‘composer.json’ e do diretório ‘vendor’ na raiz do projeto. Esse layout é recomendado porque permite que você configure seu servidor da web para fornecer apenas acesso a arquivos dentro do diretório ‘web’. Manter o diretório do fornecedor fora da raiz do documento do servidor da Web é melhor para segurança.

drupal/legacy-project

Para projeto legado, use o drupal/legacy-projecto, isso apenas se houver algum motivo para não poder usar o modelo recomendado drupal/recommended-project.

O drupal/legacy-project cria um novo site Drupal que possui o mesmo layout usado no Drupal 8.7.x e versões anteriores. Os arquivos ‘index.php’, o diretório ‘core’ e assim por diante são colocados diretamente na raiz do projeto, ao lado de ‘composer.json’ e no diretório ‘vendor’. O plug-in Varden Hardening é usado para garantir a segurança dessa configuração para os servidores Web Apache e Microsoft IIS.

Devidamente explicado, agora sim para criar um projeto usando o Composer. Vá para o diretório raiz do projeto meu-projeto/ e execute o comando:

composer create-project drupal/recommended-project:8.9.0 app

Caso não especifique a versão (8.9.0), será instalado a última versão, que no atual momento se encontra na versão Drupal 9.0.0.

Até aqui:

  • Drupal será instalado no diretório ‘app/web’.
  • O Autoloader é implementado para usar o autoloader do composer gerado em ‘vendor/autoload.php’, em vez do fornecido pelo Drupal (‘web/vendor/autoload.php’).
  • A versão mais recente do drush é instalada localmente para uso em ‘vendor/bin/drush’.
  • A versão mais recente do DrupalConsole é instalada localmente para uso em ‘vendor/bin/drupal’.
  • Cria variáveis de ambiente com base no seu arquivo .env. Consulte (.env.example)

Acessando o Assistente de Instalação na Web do Drupal

Depois que o Composer terminar o download dos pacotes, você poderá navegar até o URL localhost:8080 do site e iniciar a instalação.

Conteúdo atualizado.

Ao atualizar este tutorial, deixo aqui algumas sugestões, um help para cada problema encontrado no passo a passo. Execute tudo logo de uma vez ou faça por partes.

1 - The translations directory does not exist.

mkdir -p app/web/sites/default/files/translations/

2 - The translations directory is not writable.

chmod 777 app/web/sites/default/files/translations/

Após finalizar a instalação, não se esqueça de mudar suas permissões para chmod -R 555 app/web/sites/default/files/translations/.

3 - Selecione um perfil de instalação: Padrão

4 - Sistema de arquivos - Gravável (método de download público)

chmod -R 777 app/web/sites/default/files/

5 - O arquivo Arquivo de configurações não existe:

cp app/web/sites/default/default.settings.php app/web/sites/default/settings.php

6 - O Arquivo de configurações não pode ser escrito:

chmod 777 app/web/sites/default/settings.php

Selecione a opção padrão:

Na terceira etapa da instalação, se uma tentativa automatizada de criar o diretório ‘../config/sync’ falhar, você pode criar manualmente o diretório de sincronização um nível acima do diretório da web. Então execute:

$ mkdir -p app/config/sync/

Depois de criado o diretório de sincronização, atualize a página. Será solicitado as credenciais do banco de dados, um nome para o usuário administrador e algumas informações básicas. Use os dados das variáveis de ambiente predefinidos no arquivo docker-compose.yml. Logo em seguida, em configurações avançadas, altere localhost pelo nome de serviço mariadb.

Aguarde o processo de instalação

O Drupal 8 possui downloads de tradução automatizados embutidos. Após a instalação aguarde o sistema importar e depois traduzir o sistema. Um pouco de paciência com essa mão na roda que o Drupal 8 nos fornece.

Configurando o Site

Complete com as informações do site. Mais adiante explicaremos como proceder em relação à mensagem de aviso.

Verificação de Permissão Pós-instalação

Todas as alterações necessárias em sites/default e sites/default/settings.php foram feitas. Após a execução do script de instalação, você deve remover as permissões de gravação a fim de evitar riscos de segurança.

Via terminal, dentro do diretório meu-projeto/app/, execute:

$ chmod 555 web/sites/default

Antes de alterar as permissões do arquivo settings.php, vamos realizar uma alteração com o objetivo de tirar da raiz web as credenciais de acesso ao banco de dados.

Um nível abaixo da pasta web, em meu-projeto/app/, renomeie .env.example para arquivo .env e adicione todas as credenciais:

# Uncomment and populate as needed. MYSQL_DATABASE=dev MYSQL_HOSTNAME=mariadb MYSQL_PASSWORD=dev123 MYSQL_PORT=3306 MYSQL_USER=dev

E no arquivo sites/default/settings.php, remova :

$databases['default']['default'] = array ( 'database' => 'dev', 'username' => 'dev', 'password' => 'dev123', 'prefix' => '', 'host' => 'mariadb', 'port' => '3306', 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', 'driver' => 'mysql', );

Substituindo por:

$databases['default']['default'] = [ 'database' => getenv('MYSQL_DATABASE'), 'driver' => 'mysql', 'host' => getenv('MYSQL_HOSTNAME'), 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', 'password' => getenv('MYSQL_PASSWORD'), 'port' => getenv('MYSQL_PORT'), 'prefix' => '', 'username' => getenv('MYSQL_USER'), ];

Agora sim podemos alterar as permissões, rodando no terminal:

$ chmod 444 web/sites/default/settings.php 

Parabéns! O seu ambiente agora está montado e rodando o Drupal. Mas não pare por aqui, pois há outras informações interessantes sobre os recursos disponíveis em nosso ambiente de desenvolvimento. Vamos lá!

Mais Com o Composer

Com o composer require, você pode baixar novas dependências, módulos ou temas Drupal, para sua instalação ‘app/’.

$ composer require drupal/<nomedomódulo>

Por exemplo:

$ composer require drupal/token

Ou especificando uma versão:

$ composer require 'drupal/token:^1.5'

Isso precisa ser executado na raiz da instalação do projeto, em: meu-projeto/app/. O Composer atualizará automaticamente o seu composer.json, adicionando o módulo a todos os outros requisitos da lista, como este:

{
    "require": {
        "drupal/token": "^1.5"
    }
} 

Atualizando o Núcleo do Drupal 8 Usando o Composer

Primeiro, verifique se uma atualização do núcleo do Drupal está realmente disponível. Acessando o diretório meu-projeto/app/, execute:

$ composer outdated "drupal/*"

Caso exista uma nova versão, uma mensagem informa a versão atual do core e a nova:

drupal/core 8.7.8 8.7.9 Drupal is an open source content management platform powering millions of websites and applications.

Para toda atualização é preciso realizar um backup, não só dos arquivos, mas principalmente do banco de dados. Você pode utilizar uma ferramenta de sua preferência ou o Drush - um aplicativo baseado em shell usado para controlar, manipular e administrar sites do Drupal.

O Drush, que foi instalado em nosso projeto (vendor/drush/drush/) requer o Client MySQL instalado na máquina local.

sudo apt install mysql-client-8.0 php7.4-mysql

Anteriormente, no modelo drupal-project o Drush vinha incluído, já no recommended-project, o Drush deve ser adicionado. Se o seu projeto Composer ainda não tem o Drush, execute composer require drush/drush para adicioná-lo.
Rode o comando abaixo dentro do diretório, app/:

composer require drush/drush

A partir do diretório, app/, você tem acesso ao Drush via comando: vendor/bin/drush

Para toda atualização é preciso realizar um backup, sendo necessário alterar o valor da diretiva MYSQL_HOSTNAME do arquivo app/.env.
Nesse novo procedimento, é preciso alterar o host do banco dentro do arquivo settings.php, de mariadb que é o nome do nosso serviço, para o IP do container mariadb.
Lembrando que o IP do container muda com frequência devido a outros projetos configurados na máquina local, volte com o nome mariadb depois dos testes com o Drush ou defina de vez um IP fixo para o banco de dados. Não vou me aprofundar sobre os passos a seguir pois seria algo para outro artigo, mas encurtando as coisas, ao rodar o comando docker ps é possível obter o ID (identificador) do container.

Já para pegar o IP, rode esse comando não muito bonito:

$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' CONTAINER ID AQUI

Como informado antes, podemos utilizar uma outra ferramenta para realizar o backup do banco, mas esses pequenos passos são para que possamos ter uma ideia de como utilizar o Drush em nosso projeto. Há muitas outras coisas que podem ser feitas com ajuda do Drush, essas informações você pode obter na documentação. Ou execute drush list a partir da raíz do projeto ‘app/’ para ver a lista de comandos disponíveis:

$ vendor/drush/drush/drush list

Conteúdo atualizado.

Veja na imagem o comando para limpar o cache específico do Drupal

Não vamos esquecer o comando drush para realizar uma cópia do banco de dados.

A partir da raíz do projeto ‘app/’, execute:

$ vendor/drush/drush/drush sql:dump –result-file=../db-drupal.sql

$ vendor/bin/drush sql:dump --result-file=../db-drupal.sql

Havendo necessidade de atualizar o core, então execute o seguinte comando update do Composer para realizar a atualização:

$ composer update drupal/core webflo/drupal-core-require-dev "symfony/*" --with-dependencies

Verifique a atualização disponível do Drupal

composer outdated "drupal/*"

//saída
drupal/core                   8.9.0 9.0.0 Drupal is an open source
...

Coloque o site em modo manutenção:

$ vendor/bin/drush state:set system.maintenance_mode 1

Recomendo uma lida na documentação antes de atualizar da versão 8 para a versão 9.
Numa atualização de uma versão 8 para uma 8.x, teríamos algo como:

$ composer update drupal/core-recommended --with-dependencies

Revise os arquivos quanto a alterações e restaure as personalizações em .htaccess ou robots.txt se necessário.

Comentários Finais

Espero que essas dicas possam iluminar quem deseja iniciar ou melhorar seus processos de desenvolvimento utilizado essa plataforma robusta que é o Drupal.

Na documentação do Drupal você pode encontrar outras maneiras de fazer a instalação e iniciar o seu projeto.

Quem usa o Drupal? Explore estudos de caso em destaque em: Drupal.org

Caso queira baixar o código utilizado no exemplo, clique aqui.

Até mais!

"O conhecimento une cada um consigo mesmo e todos com todos." - José de Sousa Saramago

Referências

https://www.drupal.org/docs/8
https://getcomposer.org/doc/
https://github.com/drupal-composer/drupal-project
https://docs.docker.com/engine/reference/builder/
https://docs.docker.com/compose/
https://github.com/docker-library/drupal


#drupal #CMS #docker #composer #php #symfony