docker-whale-logoA virtualização sempre foi uma parte importante do desenvolvimento, proporcionando aos desenvolvedores uma maneira fácil de simular um ambiente próximo ao de produção em sua própria máquina, para que o software já seja desenvolvido para o ambiente onde rodará. 

Porém, com o avanço da performance de todas as máquinas, inclusive servidores, junto com a globalização da Internet, precisamos simular máquinas cada vez mais poderosas em um único computador, e chega uma hora que isso fica extremamente difícil.

Nesse cenário, nasceu a ideia do container, que, em vez de criar uma nova máquina dentro do seu computador, usa o seu kernel e cria um processo dentro do Linux, que simula uma máquina. Com isso, você consegue simular mais máquinas consumindo menos do seu próprio computador.

Instalando as ferramentas úteis

Para rodar o Drupal com uma estrutura “útil”, precisaremos de duas ferramentas: Logicamente, o Docker, que é a engine que controla os containeres. Existem outras, mas o Docker além de ser a mais fácil é também a que possui a comunidade maior e mais ativa, tornando a procura por suporte e ajuda muito mais fácil. 

Nas distros mais comuns de Linux você instala o Docker rodando o comando: 
sudo dnf install docker/sudo yum install docker ou sudo apt-get install docker 

Caso você não use Linux ou a sua distro use um gerenciador de pacote diferente, o site do Getting Started do Docker é:

Mac: 
http://docs.docker.com/mac/started/

Windows: 
http://docs.docker.com/windows/started

Linux: 
http://docs.docker.com/linux/started

 

Além do próprio Docker, utilizaremos o Docker-compose, que é uma ferramenta que nasceu na comunidade e se tornou oficial. O Docker-compose facilita a criação e uso de diversos containeres para a sua aplicação. 
As instruções para instalação do Docker Compose você encontra no link abaixo: 
https://docs.docker.com/compose/install/

 

Dockerfile

Depois de instalados os pacotes “úteis”, é hora de começar a brincar. Primeiramente nós trataremos do Dockerfile. Com o Dockerfile, você cria uma imagem que será transformada em container, consegue definir uma imagem base para a sua imagem, comandos para serem rodados enquanto a sua imagem é “compilada”, variáveis de ambiente, arquivos que estarão contidos na sua imagem e etc. Tudo que for definido neste arquivo será default para a sua imagem para qualquer pessoa que a use.

FROM php:5.6-apache  
MAINTAINER Renato Biancalana da Silva <renato.silva@justdigital.com.br>

RUN apt-get update && apt-get install -y \  
    mysql-client \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng12-dev \
    php-pear \
    curl \
    zlib1g-dev \
    libncurses5-dev

RUN docker-php-ext-install mysqli  
RUN docker-php-ext-install pdo pdo_mysql  
RUN docker-php-ext-install mbstring  
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/  
RUN docker-php-ext-install gd

RUN curl -L http://pecl.php.net/get/memcache-3.0.8.tgz >> /usr/src/php/ext/memcache.tgz && \  
tar -xf /usr/src/php/ext/memcache.tgz -C /usr/src/php/ext/ && \  
rm /usr/src/php/ext/memcache.tgz && \  
docker-php-ext-install memcache-3.0.8

RUN curl -L https://pecl.php.net/get/uploadprogress-1.0.3.1.tgz >> /usr/src/php/ext/uploadprogress.tgz && \  
tar -xf /usr/src/php/ext/uploadprogress.tgz -C /usr/src/php/ext/ && \  
rm /usr/src/php/ext/uploadprogress.tgz && \  
docker-php-ext-install uploadprogress-1.0.3.1

RUN mkdir /usr/bin/composer  
COPY composer.phar /usr/bin/composer/    

RUN a2enmod rewrite

RUN service apache2 restart

EXPOSE 80  

Neste arquivo acima, defini que a imagem base para a minha imagem será a imagem php:5.6-apache, com o comando FROM. Essa imagem já existe na minha máquina e, caso ela não exista, será baixada do Docker Registry. 

Depois de definida a imagem base, defini que o mantenedor da imagem será eu, Renato Biancalana da Silva. Fiz isso com o comando MAINTAINER
Com o comando RUN eu defini comandos para serem rodados, um de cada vez, conforme a minha imagem é compilada. 
A referência do Dockerfile, aonde você pode encontrar mais comandos e a função de cada um deles, você encontra no link abaixo. 
https://docs.docker.com/reference/builder/

Docker Compose

Com o Docker Compose você define os containeres que a sua aplicação usará. Além de defini-los você consegue linka-los, mapear e expor portas para cada um deles, mapear pastas, variáveis de ambiente, entre outras coisas.

web:  
  build: .
  ports:
    - "8080:80"
    - "22022:22"
  links: 
    - mysql:mysql
    - memcached:memcached
  volumes:
    - ./drupal:/var/www/html:rw

mysql:  
  image: mysql
  expose:
    - "3306"
  environment:
    MYSQL_DATABASE: drupal_7
    MYSQL_ROOT_PASSWORD: root

memcached:  
  image: memcached

No arquivo acima o docker-compose.yml foi colocado na mesma pasta do meu Dockerfile. Partindo disso eu defini três containeres para a minha aplicação, que são webmysql e memcached.

O container web eu defini que será compilado a partir de um Dockerfile, fazendo isso com o comando build, e passando como valor para o atributo build o caminho aonde se encontra o meu Dockerfile. Com o atributo portseu consigo mapear uma porta do meu computador para apontar para uma porta do container, com o padrão porta_host:portacontainer. Com o atributolinks eu consigo linkar o meu container a outros containeres descritos no meu docker-compose. O formato é nome_container:endereçolink. Com este atributo o docker-compose vai criar, dentro do /etc/hosts do container uma entrada com o ip do container linkado e o endereço de acordo com o especificado por você. 
Finalizando o container web temos o atributo volumes, aonde você mapeia uma pasta do seu computador para ser uma pasta no container e sua permissão, no formato path_host:path_container:permissão. Quando você faz qualquer alteração nesta pasta ela é imediatamente replicada no seu container.

No container mysql eu defini que ele será criado a partir de uma imagem já compilada e existente no meu computador, a imagem mysql, usando o atributo image. Claro ela não exista no seu computador o docker-compose tentará baixa-la do Docker Registry. Além disso a diferença entre os atributos deste container e do container web é que neste eu usei o atributo expose, queapenas expõe uma porta do container, mas sem mapea-la para nenhuma porta do meu computador. Usei também o atributo environment, aonde eudefino variáveis de ambiente para o meu container.

Para conhecer outros atributos do Compose e a função de cada um, a referência pode ser encontrada no link abaixo: 
https://docs.docker.com/compose/yml/

Rodando os containeres e configurando o Drupal

Para subir um container com o docker-compose você deve utilizar o comando docker-compose up, passando o parâmetro -d para que os containeres rodem como daemon, ou seja, em background. 

Rodado o comando, o docker-compose baixará e/ou compilará as imagens necessárias para que a sua aplicação, por completo, rode. 
Caso você precise pode parar os containeres com o comando docker-compose stop, bem como reiniciá-los com o comando docker-compose start.

Depois disso, você precisa acessar o Drupal a partir dos containeres criados pelo nosso tutorial. É simples, pois a porta 80 do container está mapeada para a porta 8080 do host, então podemos acessar a partir do endereço http://localhost:8080.

Para apontar para o banco de dados, podemos utilizar o mapeamento de links que foi feito com o docker-compose, colocando como endereço do banco o host mysql.

$databases = array (
  'default' =>
  array (
    'default' =>
    array (
      'database' => 'drupal_7',
      'username' => 'root',
      'password' => 'root',
      'host' => 'mysql',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),
  ),
);

O mesmo vale para o container memcached, que não teve uma porta mapeada mas já possui em sua imagem a instrução para que a porta 11211 seja aberta.

# Memcache Configs
$conf['cache_backends'][] = 'sites/all/modules/contrib/memcache/memcache.inc';
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';

$conf['memcache_servers'] = array(
  'memcached:11211' => 'default',
);

$conf['memcache_bins'] = array(
  'cache' => 'default',
);

Este é o básico para se rodar uma aplicação Drupal com mysql e memcached dentro do Docker. Acredito que consegui abordar neste post toda a base para que você possa deixar sua criatividade fluir e evoluir mais ainda a sua aplicação, com mais containeres para loadbalancer e etc.

Publicado originaltmente em: http://techdev.reesilva.com/drupal-no-docker/