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

Rodando Symfony em Docker containers (SymfonyLive Brazil 2019)

Rodando Symfony em Docker containers (SymfonyLive Brazil 2019)

Palestra apresentada dia 17 de maio de 2019 no SymfonyLive Brazil em São Paulo-SP (https://brasil2019.live.symfony.com/speakers). Mostramos o que é o Docker, como funciona e como tirar o melhor proveito dele montando um ambiente para programar aplicações Symfony, dicas do que fazer e o que não fazer.

Wellington F. Silva

May 17, 2019
Tweet

More Decks by Wellington F. Silva

Other Decks in Technology

Transcript

  1. Rodando
    Symfony em
    contêineres
    Docker
    Dicas e melhores práticas

    View full-size slide

  2. Wellington F. Silva
    contato:
    @_wsilva
    nicks:
    wsilva, boina, tom, fisi*
    funções:
    pai, tec. telecom,
    programador, sysadmin,
    docker community leader,
    instrutor, escritor, zend
    certified engineer e docker
    certified associate
    * deprecation in favor of Well

    View full-size slide

  3. Agenda
    • O que é Docker
    • Como funciona
    • Fluxo de trabalho comum
    • Como usar com Symfony
    • Dicas

    View full-size slide

  4. O que é DOCKER?

    View full-size slide

  5. O que é DOCKER?

    View full-size slide

  6. “Ferramenta para
    virtualização no nível do
    Sistema Operacional.”

    View full-size slide

  7. –Wellington F. Silva
    “Ferramenta para
    virtualização no nível do
    Sistema Operacional.”

    View full-size slide

  8. Tipos de
    Virtualização

    View full-size slide

  9. Tipos de Virtualização
    • Full Virtualization

    View full-size slide

  10. Tipos de Virtualização
    • Full Virtualization
    • Partial Virtualization

    View full-size slide

  11. Tipos de Virtualização
    • Full Virtualization
    • Partial Virtualization
    • Paravirtualization

    View full-size slide

  12. Tipos de Virtualização
    • Full Virtualization
    • Partial Virtualization
    • Paravirtualization
    • OS Level Virtualization

    View full-size slide

  13. Tipos de Virtualização
    • Full Virtualization
    • Partial Virtualization
    • Paravirtualization
    • OS Level Virtualization
    Docker

    View full-size slide

  14. Docker NÃO é VM

    View full-size slide

  15. OS Level Virtualization

    View full-size slide

  16. OS Level Virtualization
    U
    nix
    / C
    hroot BSD
    FreeBSD
    Jails
    / Solaris
    Zones
    O
    penVZ
    Parallels
    C
    groups
    Process
    C
    ontainers
    AIX
    / W
    pars
    LXC
    D
    ocker, rkt, cloud
    foundry, 

    C
    ontainerD
    1982 2000 2005 2006 2007 2008 >= 2013

    View full-size slide

  17. SERVIDOR
    SERVIDOR
    HOST OS
    HOST OS
    CONTAINER ENGINE
    HYPERVISOR
    BINS/LIBS
    GUEST OS APP
    GUEST OS
    BINS/LIBS BINS/LIBS APP
    APP APP
    VM VM
    Container
    Container
    Comparando

    View full-size slide

  18. 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

    View full-size slide

  19. Como Funciona?
    * no Linux

    View full-size slide

  20. PROCESSOS
    +
    KERNEL NAMESPACES
    +
    CGROUPS
    +
    ROOTFS

    View full-size slide

  21. PROCESSOS
    Aqueles que matamos com kill -9

    View full-size slide

  22. Processos
    • Processo Linux tem ID atribuído (PID)

    View full-size slide

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

    View full-size slide

  24. Processos
    • Processo Linux tem ID atribuído (PID)
    • Podem ser listados (com comado ps) dentro do
    contêiner ou fora, no host
    • Dentro do contêiner o PID=1, fora (no host) vai
    ter valor alto

    View full-size slide

  25. KERNEL
    NAMESPACES

    View full-size slide

  26. KERNEL
    NAMESPACES
    Tudo aquilo que o processo pode "ver"

    View full-size slide

  27. Kernel Namespaces
    • IPC - Interprocess communication

    View full-size slide

  28. Kernel Namespaces
    • IPC - Interprocess communication
    • PID - Processos

    View full-size slide

  29. Kernel Namespaces
    • IPC - Interprocess communication
    • PID - Processos
    • NET- Rede

    View full-size slide

  30. Kernel Namespaces
    • IPC - Interprocess communication
    • PID - Processos
    • NET- Rede
    • UTS - Unix timesharing system

    View full-size slide

  31. Kernel Namespaces
    • IPC - interprocess communication
    • PID - Processos
    • NET- rede
    • UTS - Unix timesharing system
    • USER - Usuários e grupos

    View full-size slide

  32. Kernel Namespaces
    • IPC - interprocess communication
    • PID - Processos
    • NET- rede
    • UTS - Unix timesharing system
    • USER - Usuários e grupos
    • MNT - Pontos de montagem

    View full-size slide

  33. CGROUPS
    Tudo aquilo que o processo pode "usar"

    View full-size slide

  34. CGroups
    • CPU

    View full-size slide

  35. CGroups
    • CPU
    • Memória

    View full-size slide

  36. CGroups
    • CPU
    • Memória
    • I/O em disco

    View full-size slide

  37. CGroups
    • CPU
    • Memória
    • I/O em disco
    • Interface de rede

    View full-size slide

  38. CGroups
    • CPU
    • Memória
    • I/O em disco
    • Interface de rede
    • Hardwares periféricos 

    (pen drives, cameras, etc)

    View full-size slide

  39. ROOTFS
    Onde o processo vai rodar

    View full-size slide

  40. Rootfs
    • Filesystem é uma hierarquia de diretórios

    View full-size slide

  41. Rootfs
    • Filesystem é uma hierarquia de diretórios
    • Rootfs é o filesystem base onde os demais
    sistemas de arquivos são montados

    View full-size slide

  42. Rootfs
    • Filesystem é uma hierarquia de diretórios
    • Rootfs é o filesystem base onde os demais
    sistemas de arquivos são montados
    • TLDR; é o / (barra) de uma distribuição Linux

    View full-size slide

  43. Resumo
    • Processo 

    (é o que roda a aplicação)
    • CGroups e Namespaces 

    (como o processo vai rodar)
    • Rootfs 

    (onde o processo vai rodar)

    View full-size slide

  44. Fluxo básico de
    trabalho com Docker?

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  51. Tipos de contêineres
    Docker

    View full-size slide

  52. 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

    View full-size slide

  53. 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

    View full-size slide

  54. Contêiner? Imagem?

    View full-size slide

  55. Imagens
    DEBIAN
    ID 9FB9899B593C
    INSTALL NGINX
    ID 4ZS73I39RU7Y
    ADD HTML FILES
    ID 0816EA01673A
    EXPOSE 80
    ID A24C3183E910
    ALPINE
    ID QF7T76UQGN97
    INSTALL REDIS
    ID H932FE3ZF8NQ
    EXPOSE 6379
    ID 7G4FA3T9T8PP

    View full-size slide

  56. Imagens
    DEBIAN
    ID 9FB9899B593C
    INSTALL NGINX
    ID 4ZS73I39RU7Y
    ADD HTML FILES
    ID 0816EA01673A
    EXPOSE 80
    ID A24C3183E910
    RUN NGINX
    ALPINE
    ID QF7T76UQGN97
    INSTALL REDIS
    ID H932FE3ZF8NQ
    EXPOSE 6379
    ID 7G4FA3T9T8PP
    RUN REDIS

    View full-size slide

  57. Imagens
    DEBIAN
    ID 9FB9899B593C
    INSTALL NGINX
    ID 4ZS73I39RU7Y
    ADD HTML FILES
    ID 0816EA01673A
    EXPOSE 80
    ID A24C3183E910
    RUN NGINX RUN NGINX RUN NGINX

    View full-size slide

  58. Bóra "Dockerizar"
    minha aplicação
    Symfony?

    View full-size slide

  59. Dockerizando minha app
    Rodando o contêiner
    $ docker run \

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View full-size slide

  60. Dockerizando minha app
    Rodando o contêiner
    $ docker run \

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View full-size slide

  61. Dockerizando minha app
    Rodando o contêiner
    $ docker run \

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View full-size slide

  62. Dockerizando minha app
    Rodando o contêiner
    $ docker run \

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View full-size slide

  63. Dockerizando minha app
    Rodando o contêiner
    $ docker run \

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View full-size slide

  64. Dockerizando minha app
    Rodando o contêiner
    $ docker run \

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View full-size slide

  65. Dockerizando minha app
    Rodando o contêiner
    Unable to find image 'ubuntu:18.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:18.04

    root@8d6ae10736be:/#

    View full-size slide

  66. Dockerizando minha app
    Rodando o contêiner
    Unable to find image 'ubuntu:18.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:18.04

    root@8d6ae10736be:/#

    View full-size slide

  67. Dockerizando minha app
    Rodando o contêiner
    Unable to find image 'ubuntu:18.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:18.04

    root@8d6ae10736be:/#

    View full-size slide

  68. Dockerizando minha app
    Instalando minha stack
    root@8d6ae10736be:/#

    View full-size slide

  69. Dockerizando minha app
    Instalando minha stack
    root@8d6ae10736be:/# apt-get update \

    && apt-get install -y \

    nginx \

    php7.3 \

    mysql-server \

    redis-server \

    rabbitmq-server

    View full-size slide

  70. Dockerizando minha app
    Desligando minha stack
    $ docker stop minha-loja

    View full-size slide

  71. Dockerizando minha app
    Levantando minha stack
    $ docker start minha-loja

    View full-size slide

  72. Não Não e NÃO!!!

    View full-size slide

  73. Contêineres
    • Efêmeros

    View full-size slide

  74. Contêineres
    • Efêmeros
    • São processos

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  80. Contêineres
    • Efêmeros
    • São processos
    • Propósito único
    • Imagens leves
    • Efêmeros
    • Efêmeros
    • Efêmeros
    • EFÊMEROS

    View full-size slide

  81. The right way!

    View full-size slide

  82. Iniciando um projeto
    Com o composer instalado basta rodar o
    seguinte comando.
    $ composer create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  83. E com Docker?
    $ docker run --tty --interactive 

    --rm --volume "$PWD":/app \

    --volume $SSH_AUTH_SOCK:/ssh-auth.sock \

    --env SSH_AUTH_SOCK=/ssh-auth.sock \

    --user $(id -u):$(id -g) \

    composer \

    create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  84. E com Docker?
    $ docker run --tty --interactive 

    --rm --volume "$PWD":/app \

    --volume $SSH_AUTH_SOCK:/ssh-auth.sock \

    --env SSH_AUTH_SOCK=/ssh-auth.sock \

    --user $(id -u):$(id -g) \

    composer \

    create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  85. E com Docker?
    $ docker run --tty --interactive 

    --rm --volume "$PWD":/app \

    --volume $SSH_AUTH_SOCK:/ssh-auth.sock \

    --env SSH_AUTH_SOCK=/ssh-auth.sock \

    --user $(id -u):$(id -g) \

    composer \

    create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  86. E com Docker?
    $ docker run --tty --interactive 

    --rm --volume "$PWD":/app \

    --volume $SSH_AUTH_SOCK:/ssh-auth.sock \

    --env SSH_AUTH_SOCK=/ssh-auth.sock \

    --user $(id -u):$(id -g) \

    composer \

    create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  87. E com Docker?
    $ docker run --tty --interactive 

    --rm --volume "$PWD":/app \

    --volume $SSH_AUTH_SOCK:/ssh-auth.sock \

    --env SSH_AUTH_SOCK=/ssh-auth.sock \

    --user $(id -u):$(id -g) \

    composer \

    create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  88. E com Docker?
    $ docker run --tty --interactive 

    --rm --volume "$PWD":/app \

    --volume $SSH_AUTH_SOCK:/ssh-auth.sock \

    --env SSH_AUTH_SOCK=/ssh-auth.sock \

    --user $(id -u):$(id -g) \

    composer \

    create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  89. E com Docker?
    $ docker run --tty --interactive 

    --rm --volume "$PWD":/app \

    --volume $SSH_AUTH_SOCK:/ssh-auth.sock \

    --env SSH_AUTH_SOCK=/ssh-auth.sock \

    --user $(id -u):$(id -g) \

    composer \

    create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  90. E com Docker?
    $ docker run --tty --interactive 

    --rm --volume "$PWD":/app \

    --volume $SSH_AUTH_SOCK:/ssh-auth.sock \

    --env SSH_AUTH_SOCK=/ssh-auth.sock \

    --user $(id -u):$(id -g) \

    composer \

    create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  91. E com Docker?
    $ docker run --tty --interactive 

    --rm --volume "$PWD":/app \

    --volume $SSH_AUTH_SOCK:/ssh-auth.sock \

    --env SSH_AUTH_SOCK=/ssh-auth.sock \

    --user $(id -u):$(id -g) \

    composer \

    create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  92. E com Docker?
    • Não precisamos do composer instalado

    View full-size slide

  93. E com Docker?
    • Não precisamos do composer instalado
    • Podemos trocar a versão só mudando a tag da
    imagem

    View full-size slide

  94. E com Docker?
    • Não precisamos do composer instalado
    • Podemos trocar a versão só mudando a tag da
    imagem
    • Versões/Tags disponíveis*: 1.8.5, 1.8, 1.7.3,
    1.7, 1, 1.8.4, 1.8.3, 1.8.2, 1.8.0, 1.6, 1.6.5, 1.5,
    1.5.6, 1.7.2, 1.7.1, 1.7.0, 1.4, 1.4.3, 1.6.4,
    1.6.3, 1.6.2, 1.6.1, 1.5.5, 1.5.2, 1.5.1, 1.1,
    1.1.3, 1.2, 1.2.4, 1.3, 1.3.3, 1.5.0, 1.4.2, 1.4.1,
    1.3.2, 1.3.1, 1.3.0, 1.2.3, 1.2.2

    * em maio de 2019

    View full-size slide

  95. E com Docker?
    Para ver as tags disponíveis use um pouco de bash e jq:


    i=0

    while [ $? == 0 ]

    do 

    i=$((i+1))

    curl https://registry.hub.docker.com/v2/
    repositories/library/composer/tags/?page=$i
    2>/dev/null |jq '."results"[]["name"]'

    done

    View full-size slide

  96. E com Docker?
    • Podemos criar um alias e usar como comando
    * em maio de 2019

    View full-size slide

  97. E com Docker?
    Criando alias:


    $ alias composer='docker run --tty \

    --interactive --rm \

    --volume "$PWD":/app \

    --volume $SSH_AUTH_SOCK:/ssh-auth.sock \

    --env SSH_AUTH_SOCK=/ssh-auth.sock \

    --user $(id -u):$(id -g) \

    composer'

    View full-size slide

  98. E com Docker?
    Com o alias criado o comando para iniciar um
    novo projeto é o mesmo:


    $ composer create-project \

    symfony/skeleton \

    meu-projeto

    View full-size slide

  99. Customize suas
    imagens

    View full-size slide

  100. Suas Imagens
    Utilizar Dockerfile para construir imagens
    permite:

    View full-size slide

  101. Suas Imagens
    Utilizar Dockerfile para construir imagens
    permite:
    • Controle de versões

    View full-size slide

  102. Suas Imagens
    Utilizar Dockerfile para construir imagens
    permite:
    • Controle de versões
    • Testes

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  105. 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

    View full-size slide

  106. 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

    View full-size slide

  107. Suas Imagens
    Boas práticas:
    • Simplificar, fácil para reconstruir

    View full-size slide

  108. Suas Imagens
    Boas práticas:
    • Simplificar, fácil para reconstruir
    • Evitar instalar pacotes que não serão utilizados

    View full-size slide

  109. Suas Imagens
    Boas práticas:
    • Simplificar, fácil para reconstruir
    • Evitar instalar pacotes que não serão utilizados
    • 1 processo por contêiner

    View full-size slide

  110. Suas Imagens
    Boas práticas:
    • Simplificar, fácil para reconstruir
    • Evitar instalar pacotes que não serão utilizados
    • 1 processo por contêiner
    • Quebrar instruções muito grandes em linhas
    escapando a quebra de linha

    View full-size slide

  111. Suas Imagens
    Boas práticas:
    • Simplificar, fácil para reconstruir
    • Evitar instalar pacotes que não serão utilizados
    • 1 processo por contêiner
    • Quebrar instruções muito grandes em linhas
    escapando a quebra de linha
    • Minimizar quantidade de camadas

    View full-size slide

  112. Suas Imagens
    Boas práticas:
    • Simplificar, fácil para reconstruir
    • Evitar instalar pacotes que não serão utilizados
    • 1 processo por contêiner
    • Quebrar instruções muito grandes em linhas
    escapando a quebra de linha
    • Minimizar quantidade de camadas
    • Manter Dockerfile legível

    View full-size slide

  113. Paralelize o build
    das imagens

    View full-size slide

  114. Builds paralelos
    A partir da versão 18.09 podemos usar Buildkit
    para construir imagens:


    $ export DOCKER_BUILDKIT=1

    $ docker image build -t teste .

    View full-size slide

  115. Use imagens
    mínimas

    View full-size slide

  116. Imagens mínimas
    Baixo footprint, menos vulnerabilidades e menos
    ataques.


    $ docker image ls \

    --format \

    '{{.Repository}} - {{.Size}}' \ 

    | egrep 'alpine|debian|ubuntu|fedora'


    debian - 101MB

    ubuntu - 102MB

    alpine - 5.53MB

    fedora - 275MB

    View full-size slide

  117. Imagens mínimas
    Baixo footprint, menos vulnerabilidades e menos
    ataques.


    $ docker image ls \

    --format \

    '{{.Repository}} - {{.Size}}' \ 

    | egrep 'alpine|debian|ubuntu|fedora'


    debian - 101MB

    ubuntu - 102MB

    alpine - 5.53MB

    fedora - 275MB

    View full-size slide

  118. Imagens mínimas
    Baixo footprint, menos vulnerabilidades e menos
    ataques.


    $ docker image ls \

    --format \

    '{{.Repository}} - {{.Size}}' \ 

    | egrep 'alpine|debian|ubuntu|fedora'


    debian - 101MB

    ubuntu - 102MB

    alpine - 5.53MB

    fedora - 275MB

    View full-size slide

  119. Imagens mínimas
    Baixo footprint, menos vulnerabilidades e menos
    ataques.


    $ docker image ls \

    --format \

    '{{.Repository}} - {{.Size}}' \ 

    | egrep 'alpine|debian|ubuntu|fedora'


    debian - 101MB

    ubuntu - 102MB

    alpine - 5.53MB

    fedora - 275MB

    View full-size slide

  120. Lidando com
    instalação de pacotes

    View full-size slide

  121. Pacotes
    FROM alpine
    RUN apk add --update php-fpm
    RUN rm -rf /var/cache/apk/*
    CMD ["php-fpm7"]

    View full-size slide

  122. Pacotes
    FROM alpine
    RUN apk add --update php-fpm
    RUN rm -rf /var/cache/apk/*
    CMD ["php-fpm7"]

    Remover arquivos indesejados na mesma
    camada onde são baixados / criados.

    View full-size slide

  123. Pacotes
    FROM alpine
    RUN apk add --update php-fpm
    RUN rm -rf /var/cache/apk/*
    CMD ["php-fpm7"]

    Remover arquivos indesejados na mesma camada
    onde são baixados / criados.

    FROM alpine
    RUN apk add --update php-fpm && \

    rm -rf /var/cache/apk/*
    CMD ["php-fpm7"]

    View full-size slide

  124. Pacotes
    FROM ALPINE
    5.53MB
    RUN APK ADD --UPDATE PHP-FPM
    10.6MB
    RUN RM -RF /VAR/CACHE/APK/*
    0B
    CMD ["PHP-FPM7"]
    0B
    Tamanho total 10.5MB

    View full-size slide

  125. Pacotes
    FROM ALPINE
    5.53MB
    RUN APK ADD --UPDATE PHP-FPM &&

    RUN RM -RF /VAR/CACHE/APK/*
    9.31MB
    CMD ["PHP-FPM7"]
    0B
    Tamanho total 9.31MB

    View full-size slide

  126. Utilize imagens
    oficiais

    View full-size slide

  127. Imagens Oficiais
    • São imagens mantidas pela comunidade
    testadas e aprovadas pela Docker

    View full-size slide

  128. Imagens Oficiais
    • São imagens mantidas pela comunidade
    testadas e aprovadas pela Docker
    • Possuem scan de vulnerabilidade

    View full-size slide

  129. Imagens Oficiais
    Rodando com Apache:

    $ docker run \

    --detach \

    --publish 80:80 \

    --volume "$PWD/meu-projeto":/var/www/
    html \

    --volume "$PWD/httpd.conf":/etc/
    apache2/sites-enabled/000-default.conf \

    php:7.3-apache

    View full-size slide

  130. Imagens Oficiais
    Rodando com Apache:

    $ docker run \

    --detach \

    --publish 80:80 \

    --volume "$PWD/meu-projeto":/var/www/
    html \

    --volume "$PWD/httpd.conf":/etc/
    apache2/sites-enabled/000-default.conf \

    php:7.3-apache

    View full-size slide

  131. Imagens Oficiais
    Rodando com Apache:

    $ docker run \

    --detach \

    --publish 80:80 \

    --volume "$PWD/meu-projeto":/var/www/
    html \

    --volume "$PWD/httpd.conf":/etc/
    apache2/sites-enabled/000-default.conf \

    php:7.3-apache

    View full-size slide

  132. Imagens Oficiais
    Rodando com Apache:

    $ docker run \

    --detach \

    --publish 80:80 \

    --volume "$PWD/meu-projeto":/var/www/
    html \

    --volume "$PWD/httpd.conf":/etc/
    apache2/sites-enabled/000-default.conf \

    php:7.3-apache

    View full-size slide

  133. Imagens Oficiais
    Rodando com Apache:

    $ docker run \

    --detach \

    --publish 80:80 \

    --volume "$PWD/meu-projeto":/var/www/
    html \

    --volume "$PWD/httpd.conf":/etc/
    apache2/sites-enabled/000-default.conf \

    php:7.3-apache

    View full-size slide

  134. Imagens Oficiais
    Rodando com Apache:

    $ docker run \

    --detach \

    --publish 80:80 \

    --volume "$PWD/meu-projeto":/var/www/
    html \

    --volume "$PWD/httpd.conf":/etc/
    apache2/sites-enabled/000-default.conf \

    php:7.3-apache

    View full-size slide

  135. Imagens Oficiais
    Conteúdo do arquivo apache.conf:

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/public
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log
    combined

    View full-size slide

  136. Imagens Oficiais
    Conteúdo do arquivo apache.conf:

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/public
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log
    combined

    View full-size slide

  137. Mas só quero rodar
    alguns scripts na cli…

    View full-size slide

  138. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View full-size slide

  139. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View full-size slide

  140. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View full-size slide

  141. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View full-size slide

  142. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View full-size slide

  143. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View full-size slide

  144. Rodando o Built-in
    Server do PHP

    View full-size slide

  145. Built-in Server
    Usando o PHP built in server:


    $ docker run \

    --interactive --tty --rm \

    --volume "$PWD/meu-projeto":/app \

    --workdir /app/public \

    --publish 81:81 \

    php:7.3-cli \

    php -S 0.0.0.0:81

    View full-size slide

  146. Built-in Server
    Usando o PHP built in server:


    $ docker run \

    --interactive --tty --rm \

    --volume "$PWD/meu-projeto":/app \

    --workdir /app/public \

    --publish 81:81 \

    php:7.3-cli \

    php -S 0.0.0.0:81

    View full-size slide

  147. Built-in Server
    Usando o PHP built in server:


    $ docker run \

    --interactive --tty --rm \

    --volume "$PWD/meu-projeto":/app \

    --workdir /app/public \

    --publish 81:81 \

    php:7.3-cli \

    php -S 0.0.0.0:81

    View full-size slide

  148. Built-in Server
    Usando o server do Symfony


    $ cd meu-projeto 

    $ composer require server --dev

    $ cd -

    $ docker run --interactive --tty --rm \

    --volume "$PWD/meu-projeto":/app \

    --workdir /app/public \

    --publish 8000:8000 \

    php:7.3-cli \

    ./bin/console server:run 0.0.0.0:8000


    View full-size slide

  149. Built-in Server
    Usando o server do Symfony


    $ cd meu-projeto 

    $ composer require server --dev

    $ cd -

    $ docker run --interactive --tty --rm \

    --volume "$PWD/meu-projeto":/app \

    --workdir /app/public \

    --publish 8000:8000 \

    php:7.3-cli \

    ./bin/console server:run 0.0.0.0:8000


    View full-size slide

  150. Built-in Server
    Usando o server do Symfony


    $ cd meu-projeto 

    $ composer require server --dev

    $ cd -

    $ docker run --interactive --tty --rm \

    --volume "$PWD/meu-projeto":/app \

    --workdir /app/public \

    --publish 8000:8000 \

    php:7.3-cli \

    ./bin/console server:run 0.0.0.0:8000


    View full-size slide

  151. Built-in Server
    Usando o server do Symfony


    $ cd meu-projeto 

    $ composer require server --dev

    $ cd -

    $ docker run --interactive --tty --rm \

    --volume "$PWD/meu-projeto":/app \

    --workdir /app/public \

    --publish 8000:8000 \

    php:7.3-cli \

    ./bin/console server:run 0.0.0.0:8000


    View full-size slide

  152. E se quiser usar o
    PHP-FPM?

    View full-size slide

  153. PHP-FPM
    • Podemos usar o web server que quisermos

    View full-size slide

  154. PHP-FPM
    • Podemos usar o web server que quisermos
    • Nginx
    • Apache
    • Caddy

    View full-size slide

  155. PHP-FPM
    • Podemos usar o web server que quisermos
    • Nginx
    • Apache
    • Caddy
    • Comunicação via socket

    View full-size slide

  156. PHP-FPM
    • Podemos usar o web server que quisermos
    • Nginx
    • Apache
    • Caddy
    • Comunicação via socket
    • TCP Socket
    • Socket file

    View full-size slide

  157. PHP-FPM (socket file)
    Com socket file, temos que montar o mesmo
    arquivo no web server e no php-fpm.

    View full-size slide

  158. PHP-FPM (socket file)
    Com socket file, temos que montar o mesmo
    arquivo no web server e no php-fpm.
    Exemplo de configuração fpm:

    View full-size slide

  159. PHP-FPM (socket file)
    [global]
    daemonize = no
    [www]
    listen = /var/run/php7-fpm.sock
    listen.mode = 0666

    View full-size slide

  160. PHP-FPM (socket file)
    [global]
    daemonize = no
    [www]
    listen = /var/run/php7-fpm.sock
    listen.mode = 0666

    View full-size slide

  161. PHP-FPM (socket file)
    Exemplo de configuração nginx:

    server {

    root /app/public;

    location / {

    try_files $uri /index.php$is_args$args;

    }


    View full-size slide

  162. PHP-FPM (socket file)
    Exemplo de configuração nginx:

    server {

    root /app/public;

    location / {

    try_files $uri /index.php$is_args$args;

    }


    View full-size slide

  163. PHP-FPM (socket file)
    …

    location ~ ^/index\.php(/|$) {

    fastcgi_pass unix:/var/run/php7-fpm.sock;

    fastcgi_split_path_info ^(.+\.php)(/.*)$;

    include fastcgi_params;

    fastcgi_param SCRIPT_FILENAME
    $realpath_root$fastcgi_script_name;

    fastcgi_param DOCUMENT_ROOT
    $realpath_root;

    }


    View full-size slide

  164. PHP-FPM (socket file)
    …

    location ~ ^/index\.php(/|$) {

    fastcgi_pass unix:/var/run/php7-fpm.sock;

    fastcgi_split_path_info ^(.+\.php)(/.*)$;

    include fastcgi_params;

    fastcgi_param SCRIPT_FILENAME
    $realpath_root$fastcgi_script_name;

    fastcgi_param DOCUMENT_ROOT
    $realpath_root;

    }


    View full-size slide

  165. PHP-FPM (socket file)
    …

    location ~ \.php$ {

    return 404;

    }

    error_log /proc/self/fd/2;

    access_log /proc/self/fd/1;

    }

    View full-size slide

  166. PHP-FPM (socket file)
    Criando volume comum para o socket file:


    $ docker volume create phpsocket

    View full-size slide

  167. PHP-FPM (socket file)
    Rodando o contêiner do php-fpm:

    $ docker run -d \

    --volume "$PWD/meu-projeto":/app \

    --volume phpsocket:/var/run \

    --volume "$PWD/sock-fpm.conf":/usr/
    local/etc/php-fpm.d/zz-docker.conf \

    php:7.3-fpm

    View full-size slide

  168. PHP-FPM (socket file)
    Rodando o contêiner do php-fpm:

    $ docker run -d \

    --volume "$PWD/meu-projeto":/app \

    --volume phpsocket:/var/run \

    --volume "$PWD/sock-fpm.conf":/usr/
    local/etc/php-fpm.d/zz-docker.conf \

    php:7.3-fpm

    View full-size slide

  169. PHP-FPM (socket file)
    Rodando o contêiner do php-fpm:

    $ docker run -d \

    --volume "$PWD/meu-projeto":/app \

    --volume phpsocket:/var/run \

    --volume "$PWD/sock-fpm.conf":/usr/
    local/etc/php-fpm.d/zz-docker.conf \

    php:7.3-fpm

    View full-size slide

  170. PHP-FPM (socket file)
    Rodando o contêiner do php-fpm:

    $ docker run -d \

    --volume "$PWD/meu-projeto":/app \

    --volume phpsocket:/var/run \

    --volume "$PWD/sock-fpm.conf":/usr/
    local/etc/php-fpm.d/zz-docker.conf \

    php:7.3-fpm

    View full-size slide

  171. PHP-FPM (socket file)
    Rodando o contêiner do Nginx:

    $ docker run -d -p 82:80 \

    --volume "$PWD/meu-projeto":/app \

    --volume phpsocket:/var/run \

    --volume "$PWD/sock-nginx.conf":/etc/
    nginx/conf.d/default.conf \

    nginx

    View full-size slide

  172. PHP-FPM (socket file)
    Rodando o contêiner do Nginx:

    $ docker run -d -p 82:80 \

    --volume "$PWD/meu-projeto":/app \

    --volume phpsocket:/var/run \

    --volume "$PWD/sock-nginx.conf":/etc/
    nginx/conf.d/default.conf \

    nginx

    View full-size slide

  173. PHP-FPM (socket file)
    Rodando o contêiner do Nginx:

    $ docker run -d -p 82:80 \

    --volume "$PWD/meu-projeto":/app \

    --volume phpsocket:/var/run \

    --volume "$PWD/sock-nginx.conf":/etc/
    nginx/conf.d/default.conf \

    nginx

    View full-size slide

  174. PHP-FPM (socket file)
    Rodando o contêiner do Nginx:

    $ docker run -d -p 82:80 \

    --volume "$PWD/meu-projeto":/app \

    --volume phpsocket:/var/run \

    --volume "$PWD/sock-nginx.conf":/etc/
    nginx/conf.d/default.conf \

    nginx

    View full-size slide

  175. PHP-FPM (TCP socket)
    Com tcp socket não precisamos ter o arquivo de
    socket montado em ambos contêineres.

    View full-size slide

  176. PHP-FPM (TCP socket)
    Com tcp socket não precisamos ter o arquivo de
    socket montado em ambos contêineres.

    Mas precisamos nomear o contêiner do PHP-FPM
    e colocá-lo na mesma rede que o do Nginx

    View full-size slide

  177. PHP-FPM (TCP socket)
    Com tcp socket não precisamos ter o arquivo de
    socket montado em ambos contêineres.

    Mas precisamos nomear o contêiner do PHP-FPM
    e colocá-lo na mesma rede que o do Nginx

    Exemplo de configuração fpm:


    View full-size slide

  178. PHP-FPM (TCP socket)
    [global]

    daemonize = no


    [www]

    listen = 9000

    View full-size slide

  179. PHP-FPM (TCP socket)
    [global]

    daemonize = no


    [www]

    listen = 9000

    View full-size slide

  180. PHP-FPM (TCP socket)
    Exemplo de configuração Nginx:

    server {

    root /app/public;

    location / {

    try_files $uri /index.php$is_args$args;

    }


    View full-size slide

  181. PHP-FPM (TCP socket)
    Exemplo de configuração Nginx:

    server {

    root /app/public;

    location / {

    try_files $uri /index.php$is_args$args;

    }


    View full-size slide

  182. PHP-FPM (TCP socket)
    …

    location ~ ^/index\.php(/|$) {

    fastcgi_pass phpfpm:9000;

    fastcgi_split_path_info ^(.+\.php)(/.*)
    $;

    include fastcgi_params;

    fastcgi_param SCRIPT_FILENAME
    $realpath_root$fastcgi_script_name;

    fastcgi_param DOCUMENT_ROOT
    $realpath_root;

    }


    View full-size slide

  183. PHP-FPM (TCP socket)
    …

    location ~ ^/index\.php(/|$) {

    fastcgi_pass phpfpm:9000;

    fastcgi_split_path_info ^(.+\.php)(/.*)
    $;

    include fastcgi_params;

    fastcgi_param SCRIPT_FILENAME
    $realpath_root$fastcgi_script_name;

    fastcgi_param DOCUMENT_ROOT
    $realpath_root;

    }


    View full-size slide

  184. PHP-FPM (TCP socket)
    …

    location ~ \.php$ {

    return 404;

    }

    error_log /proc/self/fd/2;

    access_log /proc/self/fd/1;

    }

    View full-size slide

  185. PHP-FPM (TCP socket)
    Criando network comum para ambos
    contêineres:


    $ docker network create phpsocket

    View full-size slide

  186. PHP-FPM (TCP socket)
    Rodando o contêiner do php-fpm:

    $ docker run -d \

    --name phpfpm \

    --network phpsocket \

    --volume "$PWD/meu-projeto":/app \

    --volume "$PWD/tcp-fpm.conf":/usr/
    local/etc/php-fpm.d/zz-docker.conf \

    php:7.3-fpm

    View full-size slide

  187. PHP-FPM (TCP socket)
    Rodando o contêiner do php-fpm:

    $ docker run -d \

    --name phpfpm \

    --network phpsocket \

    --volume "$PWD/meu-projeto":/app \

    --volume "$PWD/tcp-fpm.conf":/usr/
    local/etc/php-fpm.d/zz-docker.conf \

    php:7.3-fpm

    View full-size slide

  188. PHP-FPM (TCP socket)
    Rodando o contêiner do php-fpm:

    $ docker run -d \

    --name phpfpm \

    --network phpsocket \

    --volume "$PWD/meu-projeto":/app \

    --volume "$PWD/tcp-fpm.conf":/usr/
    local/etc/php-fpm.d/zz-docker.conf \

    php:7.3-fpm

    View full-size slide

  189. PHP-FPM (TCP socket)
    Rodando o contêiner do php-fpm:

    $ docker run -d \

    --name phpfpm \

    --network phpsocket \

    --volume "$PWD/meu-projeto":/app \

    --volume "$PWD/tcp-fpm.conf":/usr/
    local/etc/php-fpm.d/zz-docker.conf \

    php:7.3-fpm

    View full-size slide

  190. PHP-FPM (TCP socket)
    Rodando o contêiner do Nginx:

    $ docker run -d -p 83:80 \

    --network phpsocket \

    --volume "$PWD/meu-projeto":/app \

    --volume "$PWD/tcp-nginx.conf":/etc/
    nginx/conf.d/default.conf \

    nginx

    View full-size slide

  191. PHP-FPM (TCP socket)
    Rodando o contêiner do Nginx:

    $ docker run -d -p 83:80 \

    --network phpsocket \

    --volume "$PWD/meu-projeto":/app \

    --volume "$PWD/tcp-nginx.conf":/etc/
    nginx/conf.d/default.conf \

    nginx

    View full-size slide

  192. PHP-FPM (TCP socket)
    Rodando o contêiner do Nginx:

    $ docker run -d -p 83:80 \

    --network phpsocket \

    --volume "$PWD/meu-projeto":/app \

    --volume "$PWD/tcp-nginx.conf":/etc/
    nginx/conf.d/default.conf \

    nginx

    View full-size slide

  193. Evite rodar como
    root

    View full-size slide

  194. Rootless
    Podemos adicionar um usuário:

    FROM alpine
    RUN addgroup -g 82 -S www-data \
    && adduser -u 82 -D -S -G www-data \
    www-data
    RUN apk add --update php-fpm \
    && rm -rf /var/cache/apk/*
    ADD rootless.conf /etc/php7/php-fpm.d/www.conf
    USER www-data
    CMD ["php-fpm7"]

    View full-size slide

  195. Rootless
    Podemos adicionar um usuário.

    FROM alpine
    RUN addgroup -g 82 -S www-data \
    && adduser -u 82 -D -S -G www-data \
    www-data
    RUN apk add --update php-fpm \
    && rm -rf /var/cache/apk/*
    ADD rootless.conf /etc/php7/php-fpm.d/www.conf
    USER www-data
    CMD ["php-fpm7"]

    View full-size slide

  196. Rootless
    Ou podemos rodar como nobody.
    FROM alpine
    RUN apk add --update php-fpm \
    && rm -rf /var/cache/apk/*
    ADD rootless.conf /etc/php7/php-fpm.d/
    www.conf
    USER nobody
    CMD ["php-fpm7"]

    View full-size slide

  197. Rootless
    Ou podemos rodar como nobody.
    FROM alpine
    RUN apk add --update php-fpm \
    && rm -rf /var/cache/apk/*
    ADD rootless.conf /etc/php7/php-fpm.d/
    www.conf
    USER nobody
    CMD ["php-fpm7"]

    View full-size slide

  198. Rootless
    Atenção a problemas com permissão e ownership
    por causa dos usuários sem privilégios.
    Sugestão de arquivo de configuração
    (rootless.conf):

    View full-size slide

  199. Rootless
    [global]
    daemonize = no
    error_log = /proc/self/fd/2
    [www]
    listen = 9000
    access.log = /proc/self/fd/1
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    catch_workers_output = yes

    View full-size slide

  200. Rootless
    [global]
    daemonize = no
    error_log = /proc/self/fd/2
    [www]
    listen = 9000
    access.log = /proc/self/fd/1
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    catch_workers_output = yes

    View full-size slide

  201. Rootless
    [global]
    daemonize = no
    error_log = /proc/self/fd/2
    [www]
    listen = 9000
    access.log = /proc/self/fd/1
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    catch_workers_output = yes

    View full-size slide

  202. Rootless
    [global]
    daemonize = no
    error_log = /proc/self/fd/2
    [www]
    listen = 9000
    access.log = /proc/self/fd/1
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    catch_workers_output = yes

    View full-size slide

  203. Rootless
    [global]
    daemonize = no
    error_log = /proc/self/fd/2
    [www]
    listen = 9000
    access.log = /proc/self/fd/1
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    catch_workers_output = yes

    View full-size slide

  204. Preciso de extenções
    específicas

    View full-size slide

  205. Adicionando extensões
    Para extensões do core

    View full-size slide

  206. Adicionando extensões
    Para extensões do core
    • instalamos as dependências

    View full-size slide

  207. Adicionando extensões
    Para extensões do core
    • instalamos as dependências
    • usamos os scripts de ajuda (docker-php-ext-
    configure e docker-php-ext-install)

    View full-size slide

  208. Suas Imagens
    Ex.:
    FROM php:7.3-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" \
    ...

    View full-size slide

  209. Suas Imagens
    Ex.:
    FROM php:7.3-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" \
    ...

    View full-size slide

  210. 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 \
    ...

    View full-size slide

  211. 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 \
    ...

    View full-size slide

  212. 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 \
    ...

    View full-size slide

  213. 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 \
    ...

    View full-size slide

  214. Suas Imagens
    ...
    && apt-get purge -y \

    --auto-remove $deps \

    && rm -r /var/lib/apt/lists/*

    View full-size slide

  215. Suas Imagens
    ...
    && apt-get purge -y \

    --auto-remove $deps \

    && rm -r /var/lib/apt/lists/*

    View full-size slide

  216. Suas Imagens
    Para extensões PECL

    View full-size slide

  217. Suas Imagens
    Para extensões PECL
    • instalamos as dependências

    View full-size slide

  218. Suas Imagens
    Para extensões PECL
    • instalamos as dependências
    • instalamos o pacote via PECL

    View full-size slide

  219. 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)

    View full-size slide

  220. Suas Imagens
    Ex.:
    FROM php:7.3-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 \

    ...

    View full-size slide

  221. Suas Imagens
    Ex.:
    FROM php:7.3-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 \

    ...

    View full-size slide

  222. Suas Imagens
    Ex.:
    FROM php:7.3-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 \

    ...

    View full-size slide

  223. Suas Imagens
    Ex.:
    FROM php:7.3-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 \

    ...

    View full-size slide

  224. Suas Imagens
    ...

    && docker-php-ext-enable igbinary \

    redis memcached xdebug \

    && apt-get purge -y \

    --auto-remove $deps \

    && rm -r /var/lib/apt/lists/*

    View full-size slide

  225. Suas Imagens
    ...

    && docker-php-ext-enable igbinary \

    redis memcached xdebug \

    && apt-get purge -y \

    --auto-remove $deps \

    && rm -r /var/lib/apt/lists/*

    View full-size slide

  226. 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.

    View full-size slide

  227. Você falou xdebug?

    View full-size slide

  228. Configurando XDebug
    Gotchas:
    • O XDebug precisa conectar na porta 9000 do
    host (contêiner => host)

    View full-size slide

  229. Configurando XDebug
    Gotchas:
    • O XDebug precisa conectar na porta 9000 do
    host (contêiner => host)
    • Se estiver utilizando TCP Socket a porta 9000
    (padrão) do php-fpm já vai estar sendo usada

    View full-size slide

  230. Configurando XDebug
    Gotchas:
    • O XDebug precisa conectar na porta 9000 do
    host (contêiner => host)
    • Se estiver utilizando TCP Socket a porta 9000
    (padrão) do php-fpm já vai estar sendo usada
    • Podemos mudar para socket file ou utilizar
    outra porta para o fpm (ie. 9009)

    View full-size slide

  231. Configurando XDebug
    Gotchas:
    • O XDebug precisa conectar na porta 9000 do
    host (contêiner => host)
    • Se estiver utilizando TCP Socket a porta 9000
    (padrão) do php-fpm já vai estar sendo usada
    • Podemos mudar para socket file ou utilizar
    outra porta para o fpm (ie. 9009)
    • Devemos configurar o path remoto em nosso
    IDE

    View full-size slide

  232. Configurando XDebug
    Para habilitar devemos colocar as seguintes
    configs no xdebug.ini
    zend_extension=xdebug.so

    View full-size slide

  233. Configurando XDebug
    Para habilitar devemos colocar as seguintes
    configs no xdebug.ini
    zend_extension=xdebug.so

    xdebug.remote_enable=1


    View full-size slide

  234. Configurando XDebug
    Para habilitar devemos colocar as seguintes
    configs no xdebug.ini
    zend_extension=xdebug.so

    xdebug.remote_enable=1

    xdebug.remote_handler=dbgp


    View full-size slide

  235. 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

    View full-size slide

  236. 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

    View full-size slide

  237. 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

    View full-size slide

  238. 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

    View full-size slide

  239. 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=host.docker.internal

    View full-size slide

  240. Configurando XDebug
    Sublime Text
    • Instalar o package XDebug Client
    • Gravar pasta como projeto
    • Abrir arquivo gerado (nome.sublime-project)
    • Adicionar xdebug settings conforme modelo:


    View full-size slide

  241. Configurando XDebug
    "folders":
    [
    {
    "path": "."
    }
    ]

    View full-size slide

  242. Configurando XDebug
    "folders":
    [
    ...
    ],
    "settings": {
    "xdebug": {
    "url": "http://localhost:8080/",
    "path_mapping": {
    "/app" : ".",
    }

    }

    }

    View full-size slide

  243. Configurando XDebug
    Sublime Text
    • Acionar XDebug:

    Tools=>XDebug=>Start Debuging (Launch
    Browser)


    View full-size slide

  244. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  247. Configurando XDebug
    "folders":
    [
    {
    "path": "."
    }
    ],
    "settings": {
    "xdebug": {
    "url": "http://localhost:8080/",

    }

    }

    View full-size slide

  248. Configurando XDebug
    Visual Code
    • Acionar menu:

    Debug=>Start Debuging (F5)
    • Chamar url no navegador


    View full-size slide

  249. 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)

    View full-size slide

  250. Configurando XDebug

    View full-size slide

  251. 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

    View full-size slide

  252. Configurando XDebug

    View full-size slide

  253. Configurando XDebug
    PHP Storm
    • Ir em Run => Debug Docker
    • Abrir página no navegador e debugar

    View full-size slide

  254. Configurando XDebug

    View full-size slide

  255. Multi-stage build

    View full-size slide

  256. Multi-Stage Build
    • A partir da versão 17.05

    View full-size slide

  257. Multi-Stage Build
    • A partir da versão 17.05
    • Permite construir imagem com base em
    estágios

    View full-size slide

  258. Multi-Stage Build
    • A partir da versão 17.05
    • Permite construir imagem com base em
    estágios
    • Podemos reutilizar arquivos entre estágios

    View full-size slide

  259. Multi-Stage Build
    • A partir da versão 17.05
    • Permite construir imagem com base em
    estágios
    • Podemos reutilizar arquivos entre estágios
    • Podemos escolher parar o build em um estágio
    específico

    View full-size slide

  260. Multi-Stage Build
    FROM php:7-alpine as dev

    COPY --from=composer /usr/bin/composer /usr/bin/
    composer

    ADD . /app/

    WORKDIR /app

    RUN composer install --dev


    FROM php:7-alpine as prod

    COPY --from=composer /usr/bin/composer /usr/bin/
    composer

    ADD . /app/

    WORKDIR /app

    RUN composer install --no-ansi --no-dev --no-
    interaction --no-progress --no-scripts --optimize-
    autoloader

    View full-size slide

  261. Multi-Stage Build
    FROM php:7-alpine as dev

    COPY --from=composer /usr/bin/composer /usr/bin/
    composer

    ADD . /app/

    WORKDIR /app

    RUN composer install --dev


    FROM php:7-alpine as prod

    COPY --from=composer /usr/bin/composer /usr/bin/
    composer

    ADD . /app/

    WORKDIR /app

    RUN composer install --no-ansi --no-dev --no-
    interaction --no-progress --no-scripts --optimize-
    autoloader

    View full-size slide

  262. Multi-Stage Build
    FROM php:7-alpine as dev

    COPY --from=composer /usr/bin/composer /usr/bin/
    composer

    ADD . /app/

    WORKDIR /app

    RUN composer install --dev


    FROM php:7-alpine as prod

    COPY --from=composer /usr/bin/composer /usr/bin/
    composer

    ADD . /app/

    WORKDIR /app

    RUN composer install --no-ansi --no-dev --no-
    interaction --no-progress --no-scripts --optimize-
    autoloader

    View full-size slide

  263. Multi-Stage Build
    FROM php:7-alpine as dev

    COPY --from=composer /usr/bin/composer /usr/bin/
    composer

    ADD . /app/

    WORKDIR /app

    RUN composer install --dev


    FROM php:7-alpine as prod

    COPY --from=composer /usr/bin/composer /usr/bin/
    composer

    ADD . /app/

    WORKDIR /app

    RUN composer install --no-ansi --no-dev --no-
    interaction --no-progress --no-scripts --optimize-
    autoloader

    View full-size slide

  264. Multi-Stage Build
    Mesmo Dockerfile podemos gerar 2 imagens
    $ docker image build -t dev --target dev .

    $ docker image build -t prod .

    View full-size slide

  265. Multi-Stage Build
    Mesmo Dockerfile podemos gerar 2 imagens
    $ docker image build -t dev --target dev .

    $ docker image build -t prod .

    View full-size slide

  266. Docker Compose For
    the win!

    View full-size slide

  267. Docker Compose
    Começar com arquivo pequeno:

    View full-size slide

  268. 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.3-fpm

    volumes:

    - .:/app

    View full-size slide

  269. 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.3-fpm

    volumes:

    - .:/app

    View full-size slide

  270. 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.3-fpm

    volumes:

    - .:/app

    View full-size slide

  271. Mas como está
    configurado esse Nginx?

    View full-size slide

  272. 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$ {
    ...
    }
    }

    View full-size slide

  273. 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$ {
    ...
    }
    }

    View full-size slide

  274. 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$ {
    ...
    }
    }

    View full-size slide

  275. 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$ {
    ...
    }
    }

    View full-size slide

  276. 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;

    View full-size slide

  277. 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;

    View full-size slide

  278. Docker Compose
    Rodar o seguinte comando e testar no
    navegador:
    $ docker-compose up -d

    View full-size slide

  279. Docker Compose
    Dicas
    • Definindo uma rede não é necessário o link

    View full-size slide

  280. Docker Compose
    Dicas
    • Definindo uma rede não é necessário o link
    • Versões mais atuais do compose file cria uma
    rede default

    View full-size slide

  281. 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.3-fpm

    volumes:

    - .:/app

    View full-size slide

  282. 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.3-fpm

    volumes:

    - .:/app

    View full-size slide

  283. 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.3-fpm

    volumes:

    - .:/app

    View full-size slide

  284. 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.3-fpm

    volumes:

    - .:/app

    View full-size slide

  285. Docker Compose
    $ docker-compose up -d

    Creating network "meu-projeto_default"
    with the default driver

    Creating meu-projeto_php_1 ...

    Creating meu-projeto_nginx_1 ...

    Creating meu-projeto_php_1 

    Creating meu-projeto_nginx_1 ... done

    View full-size slide

  286. Docker Compose
    Vamos adicionando mais services com o tempo

    View full-size slide

  287. Docker Compose
    version: "3.3"

    services:

    ...

    mysql:

    image: mysql

    ports:

    - "3306:3306"
    environment:

    MYSQL_ROOT_PASSWORD: senha

    View full-size slide

  288. Docker Compose
    version: "3.3"

    services:

    ...

    mongo:

    image: mongo

    ports:

    - "27017:27017"

    View full-size slide

  289. Docker Compose
    version: "3.3"

    services:

    ...

    memcached:

    image: memcached

    ports:

    - "11211:11211"

    View full-size slide

  290. Docker Compose
    version: "3.3"

    services:

    ...

    redis:

    image: redis

    ports:

    - "6379:6379"

    View full-size slide

  291. Docker Compose
    version: "3.3"

    services:

    ...

    rabbitmq:

    image: rabbitmq:3.6.1-management

    ports:

    - "15672:15672"

    - "5672:5672"

    View full-size slide

  292. Docker Compose
    version: "3.3"

    services:

    ...

    elasticsearch:

    image: elasticsearch

    ports:

    - "9200:9200"

    - "9300:9300"

    View full-size slide

  293. Docker Compose
    Outra Dica
    • Com o compose podemos preparar a mesma
    stack para produção:

    View full-size slide

  294. Docker Compose
    version: "3.3"

    services:

    ...

    redis:

    image: redis

    deploy:
    replicas: 7
    update_config:

    parallelism: 2

    replay: 10s

    View full-size slide

  295. Docker Compose
    Num cluster Swarm usamos o mesmo docker-
    compose.yml:
    $ docker stack deploy \
    --compose-file docker-compose.yml \
    meu-projeto

    View full-size slide

  296. Slides em
    speakerdeck.com/wsilva

    View full-size slide

  297. Grato
    • Telegrams: 

    https://t.me/SymfonyBrasil

    https://t.me/dockerbr
    • Slacks:

    http://bit.ly/docker-slack

    http://dockr.ly/community

    https://bit.ly/
    vemproslackphpsp
    • Meetup:

    http://bit.ly/meetup-
    docker-sp

    https://www.meetup.com/
    pt-BR/php-sp/

    View full-size slide

  298. https://joind.in/talk/070f7

    View full-size slide