Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Arquitetando aplicações PHP com Docker (PHPeste...

Arquitetando aplicações PHP com Docker (PHPeste2017)

Palestra apresentada dia 08 de outubro de 2017 no PHPeste 2017 em Fortaleza-CE (http://phpeste.net). Mostramos o que é o Docker, como funciona e como tirar o melhor proveito dele montando um ambiente para programar aplicações PHP, dicas do que fazer e o que não fazer.

Wellington F. Silva

October 08, 2017
Tweet

More Decks by Wellington F. Silva

Other Decks in Technology

Transcript

  1. Wellington F. Silva contato: @_wsilva nicks: wsilva, boina, tom, fisi

    funções: pai, tec. telecom, programador, instrutor, escritor
  2. Agenda • Virtualizações • O que é o Docker •

    Como Docker funciona • Como é a arquitetura • Passos e dicas para Dockerrizar uma aplicação
  3. Tipos de Virtualização • Full Virtualization • Partial Virtualization •

    Paravirtualization • OS Level Virtualization Docker
  4. SERVIDOR SERVIDOR HOST OS HOST OS CONTAINER ENGINE HYPERVISOR BINS/LIBS

    GUEST OS BINS/LIBS GUEST OS BINS/LIBS BINS/LIBS APP APP APP APP VM VM Container Container
  5. Diferentes, não excludentes SERVIDOR XEN UBUNTU LINUX DOCKER ENGINE BINS/LIBS

    MYSQL DEBIAN LINUX BINS/LIBS NGINX BINS/LIBS PHP-FPM DOCKER ENGINE WINDOWS 2016 SERVER BINS/LIBS SQL SERVER
  6. Processos • Processo Linux com ID atribuído (PID) • Podem

    ser listados (com ps) dentro do contêiner ou fora, no host
  7. Processos • Processo Linux com ID atribuído (PID) • Podem

    ser listados (com ps) dentro do contêiner ou fora, no host • Dentro do contêiner o PID=1, fora (no host) vai ter valor alto
  8. Kernel Namespaces • IPC - interprocess communication • PID -

    Processos • NET- rede • UTS - Unix timesharing system, recursos do kernel
  9. Kernel Namespaces • IPC - interprocess communication • PID -

    Processos • NET- rede • UTS - Unix timesharing system, recursos do kernel • USER - usuários
  10. Kernel Namespaces • IPC - interprocess communication • PID -

    Processos • NET- rede • UTS - Unix timesharing system, recursos do kernel • USER - usuários • MNT - filesystem e pontos de montagem
  11. CGroups • CPU • Memória • I/O em disco •

    Interface de rede • Hardwares periféricos 
 (pen drives, cameras, etc)
  12. LINUX (DOCKER HOST) WINDOWS OSX VM LINUX
 (DOCKER HOST) DOCKER

    CLIENT DOCKER CLIENT VM LINUX
 (DOCKER HOST) DOCKER CLIENT DOCKER DAEMON DOCKER DAEMON DOCKER DAEMON Contêineres Linux
  13. WINDOWS (DOCKER HOST) LINUX OSX VM WINDOWS (DOCKER HOST) DOCKER

    CLIENT DOCKER CLIENT DOCKER CLIENT DOCKER DAEMON DOCKER DAEMON DOCKER DAEMON VM WINDOWS (DOCKER HOST) Contêineres Windows
  14. Dockerizando minha app Rodando o contêiner $ docker run \


    --name minha-loja \
 --interactive \
 --tty \
 --publish 80:80 \
 ubuntu:16.04 \
 bash
  15. Dockerizando minha app Rodando o contêiner $ docker run \


    --name minha-loja \
 --interactive \
 --tty \
 --publish 80:80 \
 ubuntu:16.04 \
 bash
  16. Dockerizando minha app Rodando o contêiner $ docker run \


    --name minha-loja \
 --interactive \
 --tty \
 --publish 80:80 \
 ubuntu:16.04 \
 bash
  17. Dockerizando minha app Rodando o contêiner $ docker run \


    --name minha-loja \
 --interactive \
 --tty \
 --publish 80:80 \
 ubuntu:16.04 \
 bash
  18. Dockerizando minha app Rodando o contêiner $ docker run \


    --name minha-loja \
 --interactive \
 --tty \
 --publish 80:80 \
 ubuntu:16.04 \
 bash
  19. Dockerizando minha app Rodando o contêiner $ docker run \


    --name minha-loja \
 --interactive \
 --tty \
 --publish 80:80 \
 ubuntu:16.04 \
 bash
  20. Dockerizando minha app Rodando o contêiner Unable to find image

    'ubuntu:16.04' locally
 16.04: Pulling from library/ubuntu
 9fb6c798fa41: Pull complete
 3b61febd4aef: Pull complete
 9d99b9777eb0: Pull complete
 d010c8cf75d7: Pull complete
 7fac07fb303e: Pull complete
 Digest:sha256:d45655633486615d164808b724b29406c b88e23d9c40ac3aaaa2d69e79e3bd5d
 Status: Downloaded newer image for ubuntu:16.04
 root@8d6ae10736be:/#
  21. Dockerizando minha app Rodando o contêiner Unable to find image

    'ubuntu:16.04' locally
 16.04: Pulling from library/ubuntu
 9fb6c798fa41: Pull complete
 3b61febd4aef: Pull complete
 9d99b9777eb0: Pull complete
 d010c8cf75d7: Pull complete
 7fac07fb303e: Pull complete
 Digest:sha256:d45655633486615d164808b724b29406c b88e23d9c40ac3aaaa2d69e79e3bd5d
 Status: Downloaded newer image for ubuntu:16.04
 root@8d6ae10736be:/#
  22. Dockerizando minha app Rodando o contêiner Unable to find image

    'ubuntu:16.04' locally
 16.04: Pulling from library/ubuntu
 9fb6c798fa41: Pull complete
 3b61febd4aef: Pull complete
 9d99b9777eb0: Pull complete
 d010c8cf75d7: Pull complete
 7fac07fb303e: Pull complete
 Digest:sha256:d45655633486615d164808b724b29406c b88e23d9c40ac3aaaa2d69e79e3bd5d
 Status: Downloaded newer image for ubuntu:16.04
 root@8d6ae10736be:/#
  23. Dockerizando minha app Rodando o contêiner Unable to find image

    'ubuntu:16.04' locally
 16.04: Pulling from library/ubuntu
 9fb6c798fa41: Pull complete
 3b61febd4aef: Pull complete
 9d99b9777eb0: Pull complete
 d010c8cf75d7: Pull complete
 7fac07fb303e: Pull complete
 Digest:sha256:d45655633486615d164808b724b29406c b88e23d9c40ac3aaaa2d69e79e3bd5d
 Status: Downloaded newer image for ubuntu:16.04
 root@8d6ae10736be:/#
  24. Dockerizando minha app Instalando minha stack root@8d6ae10736be:/# apt-get update \


    && apt-get install -y \
 nginx \
 php7.0 \
 mysql-server
  25. Contêineres • Efêmeros • São processos • Propósito único •

    Imagens leves • Efêmeros • Efêmeros • Efêmeros
  26. Contêineres • Efêmeros • São processos • Propósito único •

    Imagens leves • Efêmeros • Efêmeros • Efêmeros • EFÊMEROS
  27. Fluxo básico de trabalho com Docker Client Docker Host docker

    run redis docker daemon Contêineres Imagens Registry
  28. Fluxo básico de trabalho com Docker Client Docker Host docker

    run redis docker daemon Contêineres Imagens Registry
  29. Fluxo básico de trabalho com Docker Client Docker Host docker

    run redis docker daemon Contêineres Imagens Registry
  30. Fluxo básico de trabalho com Docker Client Docker Host docker

    run redis docker daemon Contêineres Imagens Registry
  31. Fluxo básico de trabalho com Docker Client Docker Host docker

    run redis docker daemon Contêineres Imagens Registry
  32. Imagens Oficiais • Com apache:
 $ docker run \
 --detach

    \
 --publish 80:80 \
 --volume "$PWD":/var/www/html \
 php:7.1-apache
  33. Imagens Oficiais • Com apache:
 $ docker run \
 --detach

    \
 --publish 80:80 \
 --volume "$PWD":/var/www/html \
 php:7.1-apache
  34. Imagens Oficiais • Com apache:
 $ docker run \
 --detach

    \
 --publish 80:80 \
 --volume "$PWD":/var/www/html \
 php:7.1-apache
  35. Imagens Oficiais • Com apache:
 $ docker run \
 --detach

    \
 --publish 80:80 \
 --volume "$PWD":/var/www/html \
 php:7.1-apache
  36. Imagens Oficiais • Com apache:
 $ docker run \
 --detach

    \
 --publish 80:80 \
 --volume "$PWD":/var/www/html \
 php:7.1-apache
  37. Imagens Oficiais • Usando php no cli:
 $ docker run

    \
 --interactive \
 --tty \
 --rm \
 --volume "$PWD":/app \
 --workdir /app \
 php:7.1-cli \
 php script.php
  38. Imagens Oficiais • Usando php no cli:
 $ docker run

    \
 --interactive \
 --tty \
 --rm \
 --volume "$PWD":/app \
 --workdir /app \
 php:7.1-cli \
 php script.php
  39. Imagens Oficiais • Usando php no cli:
 $ docker run

    \
 --interactive \
 --tty \
 --rm \
 --volume "$PWD":/app \
 --workdir /app \
 php:7.1-cli \
 php script.php
  40. Imagens Oficiais • Usando php no cli:
 $ docker run

    \
 --interactive \
 --tty \
 --rm \
 --volume "$PWD":/app \
 --workdir /app \
 php:7.1-cli \
 php script.php
  41. Imagens Oficiais • Usando php no cli:
 $ docker run

    \
 --interactive \
 --tty \
 --rm \
 --volume "$PWD":/app \
 --workdir /app \
 php:7.1-cli \
 php script.php
  42. Imagens Oficiais • Usando php no cli:
 $ docker run

    \
 --interactive \
 --tty \
 --rm \
 --volume "$PWD":/app \
 --workdir /app \
 php:7.1-cli \
 php script.php
  43. Imagens Oficiais • Usando php no cli:
 $ docker run

    \
 --interactive \
 --tty \
 --rm \
 --volume "$PWD":/app \
 --workdir /app \
 php:7.1-cli \
 php script.php
  44. Imagens Oficiais • Usando o built in server:
 $ docker

    run \
 --interactive \
 --tty \
 --rm \
 --volume "$PWD":/app \
 --workdir /app \
 --publish 8080:8080 \
 php:7.1-cli \
 php -S 0.0.0.0:8080
  45. Imagens Oficiais • Usando php-fpm:
 $ docker run \
 --detach

    \
 --volume "$PWD":/app \
 php:7.1-fpm
  46. Imagens Oficiais • Usando php-fpm:
 $ docker run \
 --detach

    \
 --volume "$PWD":/app \
 php:7.1-fpm
  47. Imagens Oficiais • Usando php-fpm:
 $ docker run \
 --detach

    \
 --volume "$PWD":/app \
 php:7.1-fpm
  48. Imagens Oficiais • Usando php-fpm:
 $ docker run \
 --detach

    \
 --volume "$PWD":/app \
 php:7.1-fpm
  49. Imagens Oficiais • https://store.docker.com/images/php • https://store.docker.com/images/composer • https://store.docker.com/images/nginx • https://store.docker.com/images/mysql

    • https://store.docker.com/images/memcached • https://store.docker.com/images/redis • https://store.docker.com/images/rabbitmq
  50. Imagens Oficiais • https://store.docker.com/images/php • https://store.docker.com/images/composer • https://store.docker.com/images/nginx • https://store.docker.com/images/mysql

    • https://store.docker.com/images/memcached • https://store.docker.com/images/redis • https://store.docker.com/images/rabbitmq • https://store.docker.com/images/wordpress
  51. Imagens Oficiais • https://store.docker.com/images/php • https://store.docker.com/images/composer • https://store.docker.com/images/nginx • https://store.docker.com/images/mysql

    • https://store.docker.com/images/memcached • https://store.docker.com/images/redis • https://store.docker.com/images/rabbitmq • https://store.docker.com/images/wordpress • https://store.docker.com/images/drupal
  52. Suas Imagens Utilizar Dockerfile para construir imagens permite: • Controle

    de versões • Testes • Reutilização de camadas
  53. Suas Imagens Utilizar Dockerfile para construir imagens permite: • Controle

    de versões • Testes • Reutilização de camadas • Debug durante construção
  54. Suas Imagens Utilizar Dockerfile para construir imagens permite: • Controle

    de versões • Testes • Reutilização de camadas • Debug durante construção • Conectar a pipelines de entrega
  55. Suas Imagens Utilizar Dockerfile para construir imagens permite: • Controle

    de versões • Testes • Reutilização de camadas • Debug durante construção • Conectar a pipelines de entrega • Build automatizado
  56. Suas Imagens Para extensões do core • instalamos as dependências

    • usamos os scripts de ajuda (docker-php-ext- configure e docker-php-ext-install)
  57. Suas Imagens Ex.: FROM php:7.1-fpm RUN deps="libbz2-dev \
 libmysqlclient-dev libsasl2-dev

    \
 curl git libfreetype6-dev libicu-dev \
 libjpeg-dev libmcrypt-dev \
 libpng12-dev \
 libpq-dev libxml2-dev" \ ...
  58. Suas Imagens Ex.: FROM php:7.1-fpm RUN deps="libbz2-dev \
 libmysqlclient-dev libsasl2-dev

    \
 curl git libfreetype6-dev libicu-dev \
 libjpeg-dev libmcrypt-dev \
 libpng12-dev \
 libpq-dev libxml2-dev" \ ...
  59. Suas Imagens ... && apt-get update \
 && DEBIAN_FRONTEND=noninteractive \


    && apt-get install -y $deps \
 && docker-php-ext-install -j$(nproc) \
 bcmath bz2 calendar iconv intl \
 mbstring mcrypt mysqli opcache \
 pdo_mysql pdo_pgsql pgsql soap zip \
 && docker-php-ext-configure gd \
 --with-freetype-dir=/usr/include/ \ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install gd \ ...
  60. Suas Imagens ... && apt-get update \
 && DEBIAN_FRONTEND=noninteractive \


    && apt-get install -y $deps \
 && docker-php-ext-install -j$(nproc) \
 bcmath bz2 calendar iconv intl \
 mbstring mcrypt mysqli opcache \
 pdo_mysql pdo_pgsql pgsql soap zip \
 && docker-php-ext-configure gd \
 --with-freetype-dir=/usr/include/ \ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install gd \ ...
  61. Suas Imagens ... && apt-get update \
 && DEBIAN_FRONTEND=noninteractive \


    && apt-get install -y $deps \
 && docker-php-ext-install -j$(nproc) \
 bcmath bz2 calendar iconv intl \
 mbstring mcrypt mysqli opcache \
 pdo_mysql pdo_pgsql pgsql soap zip \
 && docker-php-ext-configure gd \
 --with-freetype-dir=/usr/include/ \ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install gd \ ...
  62. Suas Imagens ... && apt-get update \
 && DEBIAN_FRONTEND=noninteractive \


    && apt-get install -y $deps \
 && docker-php-ext-install -j$(nproc) \
 bcmath bz2 calendar iconv intl \
 mbstring mcrypt mysqli opcache \
 pdo_mysql pdo_pgsql pgsql soap zip \
 && docker-php-ext-configure gd \
 --with-freetype-dir=/usr/include/ \ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install gd \ ...
  63. Suas Imagens Para extensões PECL • instalamos as dependências •

    instalamos o pacote via PECL • habilitamos com o script de ajuda (docker-php- ext-enable)
  64. Suas Imagens Ex.: FROM php:7.1-fpm RUN deps="libmemcached-dev \
 libmemcachedutil2 zlib1g-dev"

    \
 && apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
 && apt-get install -y $deps \ && pecl install igbinary redis \
 memcached xdebug \
 ...
  65. Suas Imagens Ex.: FROM php:7.1-fpm RUN deps="libmemcached-dev \
 libmemcachedutil2 zlib1g-dev"

    \
 && apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
 && apt-get install -y $deps \ && pecl install igbinary redis \
 memcached xdebug \
 ...
  66. Suas Imagens Ex.: FROM php:7.1-fpm RUN deps="libmemcached-dev \
 libmemcachedutil2 zlib1g-dev"

    \
 && apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
 && apt-get install -y $deps \ && pecl install igbinary redis \
 memcached xdebug \
 ...
  67. Suas Imagens Ex.: FROM php:7.1-fpm RUN deps="libmemcached-dev \
 libmemcachedutil2 zlib1g-dev"

    \
 && apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
 && apt-get install -y $deps \ && pecl install igbinary redis \
 memcached xdebug \
 ...
  68. Suas Imagens ...
 && docker-php-ext-enable igbinary \
 redis memcached xdebug

    \
 && apt-get purge -y \
 --auto-remove $deps \
 && rm -r /var/lib/apt/lists/*
  69. Suas Imagens ...
 && docker-php-ext-enable igbinary \
 redis memcached xdebug

    \
 && apt-get purge -y \
 --auto-remove $deps \
 && rm -r /var/lib/apt/lists/*
  70. Suas Imagens Demais extensões é melhor fazer manualmente: • wget

    ou curl pacote • phpize • ./configure • make j$(nproc) • make install E depois utilizar o docker-php-ext-enable para habilitar a extensão.
  71. Configurando XDebug Gotchas: • O XDebug precisa conectar na porta

    9000 do host (contêiner => host) • Se mapearmos a porta 9000 do php-fpm para o host o XDebug não vai conseguir conectar em nossa IDE
  72. Configurando XDebug Gotchas: • O XDebug precisa conectar na porta

    9000 do host (contêiner => host) • Se mapearmos a porta 9000 do php-fpm para o host o XDebug não vai conseguir conectar em nossa IDE • Devemos configurar o path remoto em nosso IDE
  73. Configurando XDebug Para habilitar devemos colocar as seguintes configs no

    xdebug.ini zend_extension=xdebug.so
 xdebug.remote_enable=1

  74. Configurando XDebug Para habilitar devemos colocar as seguintes configs no

    xdebug.ini zend_extension=xdebug.so
 xdebug.remote_enable=1
 xdebug.remote_handler=dbgp

  75. Configurando XDebug Para habilitar devemos colocar as seguintes configs no

    xdebug.ini zend_extension=xdebug.so
 xdebug.remote_enable=1
 xdebug.remote_handler=dbgp
 xdebug.remote_port=9000
  76. Configurando XDebug Para habilitar devemos colocar as seguintes configs no

    xdebug.ini zend_extension=xdebug.so
 xdebug.remote_enable=1
 xdebug.remote_handler=dbgp
 xdebug.remote_port=9000
 xdebug.remote_autostart=1
  77. Configurando XDebug Para habilitar devemos colocar as seguintes configs no

    xdebug.ini zend_extension=xdebug.so
 xdebug.remote_enable=1
 xdebug.remote_handler=dbgp
 xdebug.remote_port=9000
 xdebug.remote_autostart=1
 xdebug.remote_connect_back=0
  78. Configurando XDebug Para habilitar devemos colocar as seguintes configs no

    xdebug.ini zend_extension=xdebug.so
 xdebug.remote_enable=1
 xdebug.remote_handler=dbgp
 xdebug.remote_port=9000
 xdebug.remote_autostart=1
 xdebug.remote_connect_back=0
 xdebug.idekey=docker
  79. Configurando XDebug Para habilitar devemos colocar as seguintes configs no

    xdebug.ini zend_extension=xdebug.so
 xdebug.remote_enable=1
 xdebug.remote_handler=dbgp
 xdebug.remote_port=9000
 xdebug.remote_autostart=1
 xdebug.remote_connect_back=0
 xdebug.idekey=docker
 xdebug.remote_host=docker.for.mac.localhost
  80. Configurando XDebug Para habilitar devemos colocar as seguintes configs no

    xdebug.ini zend_extension=xdebug.so
 xdebug.remote_enable=1
 xdebug.remote_handler=dbgp
 xdebug.remote_port=9000
 xdebug.remote_autostart=1
 xdebug.remote_connect_back=0
 xdebug.idekey=docker
 xdebug.remote_host=docker.for.win.localhost
  81. Configurando XDebug Sublime Text • Instalar o package XDebug Client

    • Gravar pasta como projeto • Abrir arquivo gerado (nome.sublime-project) • Adicionar xdebug settings conforme modelo:

  82. Configurando XDebug "folders": [ ... ], "settings": { "xdebug": {

    "url": "http://localhost:8080/", "path_mapping": { "/app" : ".", }
 }
 }
  83. Configurando XDebug Visual Code • Instalar extensão php-debug • Acionar

    menu Debug => Open configurations • Adicionar as seguintes linhas abaixo da definição da porta 9000
  84. Configurando XDebug "configurations": [ { "name": "Listen for "type": "php",

    "request": "launch", "port": 9000, "serverSourceRoot": "/app", "localSourceRoot": "${workspaceRoot}" },
  85. Configurando XDebug "configurations": [ { "name": "Listen for "type": "php",

    "request": "launch", "port": 9000, "serverSourceRoot": "/app", "localSourceRoot": "${workspaceRoot}" },
  86. Configurando XDebug "folders": [ { "path": "." } ], "settings":

    { "xdebug": { "url": "http://localhost:8080/",
 }
 }
  87. Configurando XDebug PHP Storm • Em Preferences => Languages&Frameworks =>

    PHP => Servers, criar novo server • Definir o host, a porta e o debugger (XDebug) • Ativar path mapping • Mapear a pasta raiz do projeto para a pasta dentro do contêiner (/app)
  88. Configurando XDebug PHP Storm • Em Run => Edit configurations

    criar novo PHP Remote Debug • Usar o server criado anteriormente e definir o ide key como Docker
  89. Configurando XDebug PHP Storm • Ir em Run => Debug

    Docker • Abrir página no navegador e debugar
  90. Docker Compose nginx: image: nginx:latest ports: - "8080:80" volumes: -

    .:/app - ./site.conf:/etc/nginx/conf.d/default.conf links: - php php: image: php:7.1-fpm volumes: - .:/app
  91. Docker Compose nginx: image: nginx:latest ports: - "8080:80" volumes: -

    .:/app - ./site.conf:/etc/nginx/conf.d/default.conf links: - php php: image: php:7.1-fpm volumes: - .:/app
  92. Docker Compose nginx: image: nginx:latest ports: - "8080:80" volumes: -

    .:/app - ./site.conf:/etc/nginx/conf.d/default.conf links: - php php: image: php:7.1-fpm volumes: - .:/app
  93. Docker Compose server { index index.php index.html; server_name localhost; error_log

    /proc/self/fd/2; access_log /proc/self/fd/1; root /app; location ~ \.php$ { ... } }
  94. Docker Compose server { index index.php index.html; server_name localhost; error_log

    /proc/self/fd/2; access_log /proc/self/fd/1; root /app; location ~ \.php$ { ... } }
  95. Docker Compose server { index index.php index.html; server_name localhost; error_log

    /proc/self/fd/2; access_log /proc/self/fd/1; root /app; location ~ \.php$ { ... } }
  96. Docker Compose server { index index.php index.html; server_name localhost; error_log

    /proc/self/fd/2; access_log /proc/self/fd/1; root /app; location ~ \.php$ { ... } }
  97. Docker Compose try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+) $; fastcgi_pass php:9000;

    fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info;
  98. Docker Compose try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+) $; fastcgi_pass php:9000;

    fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info;
  99. Docker Compose Dicas • Definindo uma rede não é necessário

    o link • Versões mais atuais do compose file cria uma rede default
  100. Docker Compose version: "3.3"
 services:
 nginx:
 image: nginx:latest
 ports:
 -

    "8080:80"
 volumes:
 - .:/app
 - ./site.conf:/etc/nginx/conf.d/ default.conf
 php:
 image: php:7.1-fpm
 volumes:
 - .:/app
  101. Docker Compose version: "3.3"
 services:
 nginx:
 image: nginx:latest
 ports:
 -

    "8080:80"
 volumes:
 - .:/app
 - ./site.conf:/etc/nginx/conf.d/ default.conf
 php:
 image: php:7.1-fpm
 volumes:
 - .:/app
  102. Docker Compose version: "3.3"
 services:
 nginx:
 image: nginx:latest
 ports:
 -

    "8080:80"
 volumes:
 - .:/app
 - ./site.conf:/etc/nginx/conf.d/ default.conf
 php:
 image: php:7.1-fpm
 volumes:
 - .:/app
  103. Docker Compose version: "3.3"
 services:
 nginx:
 image: nginx:latest
 ports:
 -

    "8080:80"
 volumes:
 - .:/app
 - ./site.conf:/etc/nginx/conf.d/ default.conf
 php:
 image: php:7.1-fpm
 volumes:
 - .:/app
  104. Docker Compose $ docker-compose up -d
 Creating network "phpeste_default" with

    the default driver
 Creating phpeste_php_1 ...
 Creating phpeste_nginx_1 ...
 Creating phpeste_php_1 
 Creating phpeste_nginx_1 ... done
  105. Docker Compose version: "3.3"
 services:
 ...
 mysql:
 image: mysql
 ports:


    - "3306:3306" environment:
 MYSQL_ROOT_PASSWORD: senha
  106. Docker Compose version: "3.3"
 services:
 ...
 redis:
 image: redis
 deploy:

    replicas: 7 update_config:
 parallelism: 2
 replay: 10s
  107. Docker Compose Num cluster Swarm usamos o mesmo docker- compose.yml:

    $ docker stack deploy \ --compose-file docker-compose.yml \ phpeste
  108. Grato 
 Próximos Passos: • Curso: 
 http://bit.ly/curso-docker • Telegram:

    
 http://t.me/dockerbr • Slacks:
 http://bit.ly/docker-slack
 http://dockr.ly/community • Meetup:
 http://bit.ly/meetup- docker-sp