Docker: mysql + nginx + php com debug (Visual Studio Code e IntelliJ Idea/Php Storm)

Este post irá ensinar a criar containers docker para desenvolvimento local com mysql, nginx (servidor http) e php com xdebug.

Para quem gosta de soluções rápidas:

  1. Baixe e instale o docker (requer Windows 10 ou Linux. Se possuir uma versão do windows menor que a 10, baixe o docker toolbox, mas não testei nessa configuração);
  2. Baixe o arquivos para o build aqui;
  3. Com o Windows Powershell ou bash, vá até a pasta onde descompactou os arquivos e execute:
    docker-compose build
    docker-compose up -d
  4. Acesse http://localhost:8080/index.php.

Pronto!

O php está configurado com as principais bibliotecas e drives de conexão com banco de dados, incluindo Sql Server, Sybase e Oracle.

Detalhamento

O dockerfile principal é do php para instalação dos módulos e do xdebug:

FROM php:7.2.3-fpm

# Deps
RUN apt-get update \
    && apt-get install --no-install-recommends -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libpng-dev \
        zlib1g-dev \
        libicu-dev \
        g++ \
        unixodbc-dev \
        libxml2-dev \
        libaio-dev \
        libmemcached-dev \
        freetds-dev \
        libssl-dev \
        openssl \
        libpq-dev \
        unzip

#XDEBUG
RUN pecl install xdebug-2.6.0 \
    && docker-php-ext-enable xdebug

# Oracle
RUN mkdir --parents /opt/oracle
COPY instantclient-basic-linux.x64-12.2.0.1.0.zip /opt/oracle
COPY instantclient-sdk-linux.x64-12.2.0.1.0.zip /opt/oracle
RUN cd /opt/oracle \
    && unzip /opt/oracle/instantclient-basic-linux.x64-12.2.0.1.0.zip -d /opt/oracle \
    && unzip /opt/oracle/instantclient-sdk-linux.x64-12.2.0.1.0.zip -d /opt/oracle \
    && ln -s /opt/oracle/instantclient_12_2/libclntsh.so.12.1 /opt/oracle/instantclient_12_2/libclntsh.so \
    && ln -s /opt/oracle/instantclient_12_2/libclntshcore.so.12.1 /opt/oracle/instantclient_12_2/libclntshcore.so \
    && ln -s /opt/oracle/instantclient_12_2/libocci.so.12.1 /opt/oracle/instantclient_12_2/libocci.so \
    && rm -rf /opt/oracle/*.zip \
    && echo /opt/oracle/instantclient_12_2 > /etc/ld.so.conf.d/oracle-instantclient.conf \
    && ldconfig


# Install PHP extensions
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && echo 'instantclient,/opt/oracle/instantclient_12_2' | pecl install oci8 \
    && docker-php-ext-configure pdo_oci --with-pdo-oci=instantclient,/opt/oracle/instantclient_12_2,12.2 \
    && docker-php-ext-configure pdo_dblib --with-libdir=/lib/x86_64-linux-gnu \
    && pecl install sqlsrv-4.1.6.1 \
    && pecl install pdo_sqlsrv-4.1.6.1 \
    && pecl install redis \
    && pecl install memcached \
    && docker-php-ext-install \
            iconv \
            mbstring \
            intl \
            gd \
            pgsql \
            mysqli \
            pdo_pgsql \
            pdo_mysql \
            pdo_oci \
            pdo_dblib \
            soap \
            sockets \
            zip \
            pcntl \
            ftp \
    && docker-php-ext-enable \
            oci8 \
            sqlsrv \
            pdo_sqlsrv \
            redis \
            memcached \
            opcache


# Install APCu and APC backward compatibility
RUN pecl install apcu \
    && pecl install apcu_bc-1.0.3 \
    && docker-php-ext-enable apcu --ini-name 10-docker-php-ext-apcu.ini \
    && docker-php-ext-enable apc --ini-name 20-docker-php-ext-apc.ini


COPY ./src /var/www/html
COPY ./xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini
WORKDIR /var/www/html

A entrada do build esta no arquivo docker-compose.yml (é o arquivo que “junta” todos os containers):

version: '3.1'

services:
  nginx:
    build:
      context: .
      dockerfile: nginx.dockerfile
    volumes:
      - ./src:/var/www/html
    ports:
      - 8080:80
      - 443:443
    links:
      - php-fpm

  php-fpm:
    build:
      context: .
      dockerfile: php.dockerfile
    volumes:
      - ./src:/var/www/html
    links:
      - mysql

  mysql:
    image: mysql
    restart: always
    ports:
        - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: mydatabase

Utilizando o debugger

Todo o seu desenvolvimento deve ocorrer na subpasta /src. Estes arquivos serão mapeados na máquina virtual que roda o php e poderão ser acessados pelo caminho http://localhost:8080/arquivo.php.

Com o Visual Studio Code

  1. Instale o módulo “PHP Debug” (de Felix Becker) no menu Extensions do lado esquerdo da tela.
  2. Vá no arquivo que deseja e insira um breakpoint;
  3. No lado esquerdo do Visual Studio Code vá em debug, escolha “Listen for Xdebug” e clique na engrenagem para configurar:
    {
        "version": "0.2.0",
        "configurations": [
            
            {
                "name": "Listen for XDebug",
                "type": "php",
                "request": "launch",
                "port": 9000,
                "pathMappings": {
                    "/var/www/html": "${workspaceRoot}/src"
                },
            },
            {
                "name": "Launch currently open script",
                "type": "php",
                "request": "launch",
                "program": "${file}",
                "cwd": "${fileDirname}",
                "port": 9000
            }
        ]
    }
  4. Clique em “Starg Debugging” (no ícone play verde);
  5. Abra o browser no endereço (a partir de http://localhost:8080) e pronto!

Com o Intellij Idea / Php Storm

      1. Vá em File -> Settings… -> Plugins e instale os seguintes plugins: PHP Docker, PHP Remote Interpreter, Docker Integration.
      2. Em Settings… -> Languages & Frameworks -> PHP, configure o CLI Interpreter
      3. Clique no botão + -> From Docker, VM, Vagrant, Remote…
      4. Configure assim:
      5. O Resultado deverá ficar assim:
      6. Revise Settings… -> Languages & Frameworks -> PHP -> Debug e tenha certeza que o IntelliJ/PhpStorm esteja escutando na porta 9000, conforme circulado em vermelho na imagem abaixo:
      7. Coloque o breakpoint no arquivo e acesse a url (ex: http://localhost:8080/index.php):

     

  1. Pronto, php com debug funcionando localmente!