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 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 Slide

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

    View Slide

  4. O que é DOCKER?

    View Slide

  5. View Slide

  6. View Slide

  7. O que é DOCKER?

    View Slide

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

    View Slide

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

    View Slide

  10. Tipos de
    Virtualização

    View Slide

  11. Tipos de Virtualização
    • Full Virtualization

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  16. Docker NÃO é VM

    View Slide

  17. OS Level Virtualization

    View Slide

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

  19. 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 Slide

  20. 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 Slide

  21. Como Funciona?
    * no Linux

    View Slide

  22. PROCESSOS
    +
    KERNEL NAMESPACES
    +
    CGROUPS
    +
    ROOTFS

    View Slide

  23. PROCESSOS

    View Slide

  24. PROCESSOS
    Aqueles que matamos com kill -9

    View Slide

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

    View Slide

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

    View Slide

  27. 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 Slide

  28. KERNEL
    NAMESPACES

    View Slide

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

    View Slide

  30. Kernel Namespaces
    • IPC - Interprocess communication

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  36. CGROUPS

    View Slide

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

    View Slide

  38. CGroups
    • CPU

    View Slide

  39. CGroups
    • CPU
    • Memória

    View Slide

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

    View Slide

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

    View Slide

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

    (pen drives, cameras, etc)

    View Slide

  43. ROOTFS
    Onde o processo vai rodar

    View Slide

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

    View Slide

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

    View Slide

  46. 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 Slide

  47. Resumo
    • Processo 

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

    (como o processo vai rodar)
    • Rootfs 

    (onde o processo vai rodar)

    View Slide

  48. Fluxo básico de
    trabalho com Docker?

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  55. Tipos de contêineres
    Docker

    View Slide

  56. 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 Slide

  57. 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 Slide

  58. Contêiner? Imagem?

    View Slide

  59. 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 Slide

  60. 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 Slide

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

    View Slide

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

    View Slide

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

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View Slide

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

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View Slide

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

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View Slide

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

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View Slide

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

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View Slide

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

    --name minha-loja \

    --interactive \

    --tty \

    --publish 80:80 \

    ubuntu:18.04 \

    bash

    View Slide

  69. 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 Slide

  70. 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 Slide

  71. 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 Slide

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

    View Slide

  73. 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 Slide

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

    View Slide

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

    View Slide

  76. Não

    View Slide

  77. Não Não

    View Slide

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

    View Slide

  79. Contêineres
    • Efêmeros

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  87. The right way!

    View Slide

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

    symfony/skeleton \

    meu-projeto

    View 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 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 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 Slide

  92. 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 Slide

  93. 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 Slide

  94. 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 Slide

  95. 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 Slide

  96. 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 Slide

  97. 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 Slide

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

    View Slide

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

    View Slide

  100. 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 Slide

  101. 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 Slide

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

    View Slide

  103. 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 Slide

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


    $ composer create-project \

    symfony/skeleton \

    meu-projeto

    View Slide

  105. Customize suas
    imagens

    View Slide

  106. Suas Imagens
    Utilizar Dockerfile para construir imagens
    permite:

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  111. 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 Slide

  112. 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 Slide

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

    View Slide

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

    View Slide

  115. 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 Slide

  116. 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 Slide

  117. 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 Slide

  118. 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 Slide

  119. Paralelize o build
    das imagens

    View Slide

  120. 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 Slide

  121. Use imagens
    mínimas

    View Slide

  122. 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 Slide

  123. 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 Slide

  124. 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 Slide

  125. 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 Slide

  126. Lidando com
    instalação de pacotes

    View Slide

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

    View Slide

  128. 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 Slide

  129. 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 Slide

  130. 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 Slide

  131. 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 Slide

  132. Utilize imagens
    oficiais

    View Slide

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

    View Slide

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

    View Slide

  135. View Slide

  136. 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 Slide

  137. 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 Slide

  138. 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 Slide

  139. 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 Slide

  140. 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 Slide

  141. 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 Slide

  142. 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 Slide

  143. 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 Slide

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

    View Slide

  145. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View Slide

  146. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View Slide

  147. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View Slide

  148. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View Slide

  149. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View Slide

  150. CLI Scripts
    Usando php no cli:


    $ docker run \

    --interactive \

    --tty \

    --rm \

    --volume "$PWD":/app \

    --workdir /app \

    php:7.3-cli \

    php info.php

    View Slide

  151. Rodando o Built-in
    Server do PHP

    View Slide

  152. 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 Slide

  153. 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 Slide

  154. 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 Slide

  155. 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 Slide

  156. 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 Slide

  157. 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 Slide

  158. 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 Slide

  159. E se quiser usar o
    PHP-FPM?

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  165. 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 Slide

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

    View Slide

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

    View Slide

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

    server {

    root /app/public;

    location / {

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

    }


    View Slide

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

    server {

    root /app/public;

    location / {

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

    }


    View Slide

  170. 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 Slide

  171. 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 Slide

  172. PHP-FPM (socket file)
    …

    location ~ \.php$ {

    return 404;

    }

    error_log /proc/self/fd/2;

    access_log /proc/self/fd/1;

    }

    View Slide

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


    $ docker volume create phpsocket

    View Slide

  174. 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 Slide

  175. 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 Slide

  176. 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 Slide

  177. 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 Slide

  178. 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 Slide

  179. 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 Slide

  180. 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 Slide

  181. 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 Slide

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

    View Slide

  183. 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 Slide

  184. 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 Slide

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

    daemonize = no


    [www]

    listen = 9000

    View Slide

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

    daemonize = no


    [www]

    listen = 9000

    View Slide

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

    server {

    root /app/public;

    location / {

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

    }


    View Slide

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

    server {

    root /app/public;

    location / {

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

    }


    View Slide

  189. 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 Slide

  190. 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 Slide

  191. PHP-FPM (TCP socket)
    …

    location ~ \.php$ {

    return 404;

    }

    error_log /proc/self/fd/2;

    access_log /proc/self/fd/1;

    }

    View Slide

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


    $ docker network create phpsocket

    View Slide

  193. 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 Slide

  194. 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 Slide

  195. 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 Slide

  196. 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 Slide

  197. 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 Slide

  198. 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 Slide

  199. 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 Slide

  200. Evite rodar como
    root

    View Slide

  201. 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 Slide

  202. 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 Slide

  203. 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 Slide

  204. 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 Slide

  205. 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 Slide

  206. 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 Slide

  207. 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 Slide

  208. 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 Slide

  209. 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 Slide

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

  211. Preciso de extenções
    específicas

    View Slide

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

    View Slide

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

    View Slide

  214. 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 Slide

  215. 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 Slide

  216. 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 Slide

  217. 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 Slide

  218. 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 Slide

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

  220. 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 Slide

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

    --auto-remove $deps \

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

    View Slide

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

    --auto-remove $deps \

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

    View Slide

  223. Suas Imagens
    Para extensões PECL

    View Slide

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

    View Slide

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

    View Slide

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

  227. 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 Slide

  228. 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 Slide

  229. 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 Slide

  230. 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 Slide

  231. Suas Imagens
    ...

    && docker-php-ext-enable igbinary \

    redis memcached xdebug \

    && apt-get purge -y \

    --auto-remove $deps \

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

    View Slide

  232. Suas Imagens
    ...

    && docker-php-ext-enable igbinary \

    redis memcached xdebug \

    && apt-get purge -y \

    --auto-remove $deps \

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

    View Slide

  233. 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 Slide

  234. Você falou xdebug?

    View Slide

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

    View Slide

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

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

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

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

    View Slide

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

    xdebug.remote_enable=1


    View Slide

  241. 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 Slide

  242. 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 Slide

  243. 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 Slide

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

  245. 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 Slide

  246. 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 Slide

  247. 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 Slide

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

    View Slide

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

    }

    }

    View Slide

  250. Configurando XDebug
    Sublime Text
    • Acionar XDebug:

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


    View Slide

  251. View Slide

  252. 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 Slide

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

    View Slide

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

    View Slide

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

    }

    }

    View Slide

  256. Configurando XDebug
    Visual Code
    • Acionar menu:

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


    View Slide

  257. View Slide

  258. 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 Slide

  259. Configurando XDebug

    View Slide

  260. 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 Slide

  261. Configurando XDebug

    View Slide

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

    View Slide

  263. Configurando XDebug

    View Slide

  264. Multi-stage build

    View Slide

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

    View Slide

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

    View Slide

  267. 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 Slide

  268. 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 Slide

  269. 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 Slide

  270. 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 Slide

  271. 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 Slide

  272. 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 Slide

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

    $ docker image build -t prod .

    View Slide

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

    $ docker image build -t prod .

    View Slide

  275. Docker Compose For
    the win!

    View Slide

  276. Docker Compose
    Começar com arquivo pequeno:

    View Slide

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

  278. 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 Slide

  279. 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 Slide

  280. Mas como está
    configurado esse Nginx?

    View Slide

  281. 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 Slide

  282. 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 Slide

  283. 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 Slide

  284. 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 Slide

  285. 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 Slide

  286. 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

  290. 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 Slide

  291. 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 Slide

  292. 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 Slide

  293. 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 Slide

  294. 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 Slide

  295. Docker Compose
    Vamos adicionando mais services com o tempo

    View Slide

  296. Docker Compose
    version: "3.3"

    services:

    ...

    mysql:

    image: mysql

    ports:

    - "3306:3306"
    environment:

    MYSQL_ROOT_PASSWORD: senha

    View Slide

  297. Docker Compose
    version: "3.3"

    services:

    ...

    mongo:

    image: mongo

    ports:

    - "27017:27017"

    View Slide

  298. Docker Compose
    version: "3.3"

    services:

    ...

    memcached:

    image: memcached

    ports:

    - "11211:11211"

    View Slide

  299. Docker Compose
    version: "3.3"

    services:

    ...

    redis:

    image: redis

    ports:

    - "6379:6379"

    View Slide

  300. Docker Compose
    version: "3.3"

    services:

    ...

    rabbitmq:

    image: rabbitmq:3.6.1-management

    ports:

    - "15672:15672"

    - "5672:5672"

    View Slide

  301. Docker Compose
    version: "3.3"

    services:

    ...

    elasticsearch:

    image: elasticsearch

    ports:

    - "9200:9200"

    - "9300:9300"

    View Slide

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

    View Slide

  303. Docker Compose
    version: "3.3"

    services:

    ...

    redis:

    image: redis

    deploy:
    replicas: 7
    update_config:

    parallelism: 2

    replay: 10s

    View Slide

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

    View Slide

  305. Slides em
    speakerdeck.com/wsilva

    View Slide

  306. 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 Slide

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

    View Slide