12 Factor Melhor com Docker

12 Factor Melhor com Docker

Talk on Darkmira Tour 2016 Brasilia DF

280fecb4f048de5ecf36bec281609ea4?s=128

Wellington F. Silva

March 19, 2016
Tweet

Transcript

  1. Aplicações 12 fatores Melhor com Docker

  2. wsilva/tom/boina • Devops na GFG • @_wsilva

  3. Agenda • O que é Docker? • O que é

    12 factor app? • Os 12 fatores • Como o Docker adere a cada fator
  4. O que é Docker?

  5. O que é Docker? • Sistema de contêineres Linux

  6. O que é Docker? • Sistema de contêineres Linux •

    Muito leve e rápido
  7. O que é Docker? • Sistema de contêineres Linux •

    Muito leve e rápido • Muitas vantagens em relação à virtualização
  8. O que é Docker? • Sistema de contêineres Linux •

    Muito leve e rápido • Muitas vantagens em relação à virtualização • Build, Ship, Run anywhere
  9. O que é Docker? • Sistema de contêineres Linux •

    Muito leve e rápido • Muitas vantagens em relação à virtualização • Build, Ship, Run anywhere • Tem ferramentas para orquestração
  10. O que é Docker? • Sistema de contêineres Linux •

    Muito leve e rápido • Muitas vantagens em relação à virtualização • Build, Ship, Run anywhere • Tem ferramentas para orquestração • Tem ferramentas para clusterização
  11. O que é Docker? • Sistema de contêineres Linux •

    Muito leve e rápido • Muitas vantagens em relação à virtualização • Build, Ship, Run anywhere • Tem ferramentas para orquestração • Tem ferramentas para clusterização • Criado por Solomon Hykes
  12. O que é Docker? • Sistema de contêineres Linux •

    Muito leve e rápido • Muitas vantagens em relação à virtualização • Build, Ship, Run anywhere • Tem ferramentas para orquestração • Tem ferramentas para clusterização • Criado por Solomon Hykes • Open Source
  13. O que é Docker? • Sistema de contêineres Linux •

    Muito leve e rápido • Muitas vantagens em relação à virtualização • Build, Ship, Run anywhere • Tem ferramentas para orquestração • Tem ferramentas para clusterização • Criado por Solomon Hykes • Open Source • http://www.docker.com
  14. O que é 12 factor app?

  15. O que é 12 factor app? • Metodologia para desenvolvimento

    de apps web e SAAS (Software as a Service)
  16. O que é 12 factor app? • Metodologia para desenvolvimento

    de apps web e SAAS (Software as a Service) • Aplicável em qualquer linguagem de programação de alto nível
  17. O que é 12 factor app? • Metodologia para desenvolvimento

    de apps web e SAAS (Software as a Service) • Aplicável em qualquer linguagem de programação de alto nível • Facilita portabilidade e escalabilidade
  18. O que é 12 factor app? • Metodologia para desenvolvimento

    de apps web e SAAS (Software as a Service) • Aplicável em qualquer linguagem de programação de alto nível • Facilita portabilidade e escalabilidade • Criado por Adam Wiggins e outros colaboradores do Heroku
  19. O que é 12 factor app? • Metodologia para desenvolvimento

    de apps web e SAAS (Software as a Service) • Aplicável em qualquer linguagem de programação de alto nível • Facilita portabilidade e escalabilidade • Criado por Adam Wiggins e outros colaboradores do Heroku • Foca em problemas sistêmicos comuns
  20. O que é 12 factor app? • Metodologia para desenvolvimento

    de apps web e SAAS (Software as a Service) • Aplicável em qualquer linguagem de programação de alto nível • Facilita portabilidade e escalabilidade • Criado por Adam Wiggins e outros colaboradores do Heroku • Foca em problemas sistêmicos comuns • Inspirado no "Patterns of Enterprise Application Architecture" e no "Refactoring" de Martin Fowler
  21. O que é 12 factor app? • Metodologia para desenvolvimento

    de apps web e SAAS (Software as a Service) • Aplicável em qualquer linguagem de programação de alto nível • Facilita portabilidade e escalabilidade • Criado por Adam Wiggins e outros colaboradores do Heroku • Foca em problemas sistêmicos comuns • Inspirado no "Patterns of Enterprise Application Architecture" e no "Refactoring" de Martin Fowler • http://12factor.net
  22. "Quando o relógio bate a uma, todas as caveiras saem

    das tumbas." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  23. I - Base de Código • Repositório único por app

    (git, hg, svn, bazaar)
  24. I - Base de Código • Repositório único por app

    (git, hg, svn, bazaar) • + de um codebase é um sistema distribuído
  25. I - Base de Código • Repositório único por app

    (git, hg, svn, bazaar) • + de um codebase é um sistema distribuído • Mais apps num mesmo codebase é errado
  26. I - Base de Código • Repositório único por app

    (git, hg, svn, bazaar) • + de um codebase é um sistema distribuído • Mais apps num mesmo codebase é errado • Vários deploys (dev1, dev2, dev3, staging, qa, integration, production)
  27. I - Base de Código • Repositório único por app

    (git, hg, svn, bazaar) • + de um codebase é um sistema distribuído • Mais apps num mesmo codebase é errado • Vários deploys (dev1, dev2, dev3, staging, qa, integration, production) Docker: • Colocar Dockerfiles no repositório
  28. I - Base de Código 1 cd 12factor 2 git

    init . 3 git add web-container/Dockerfile 4 git add wer-source/* 5 git commit -m "Iniciando os trabalhos"
  29. "Quando o relógio bate as duas, todas as caveiras pintam

    as unhas." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  30. II - Dependências • Devem ser declaradas e isoladas

  31. II - Dependências • Devem ser declaradas e isoladas •

    Devem estar presentes em um arquivo manifesto (composer.json, requirements.txt, Gemfile)
  32. II - Dependências • Devem ser declaradas e isoladas •

    Devem estar presentes em um arquivo manifesto (composer.json, requirements.txt, Gemfile) • Utilizar ferramentas de empacotamento (composer, pip, maven, bundle)
  33. II - Dependências • Devem ser declaradas e isoladas •

    Devem estar presentes em um arquivo manifesto (composer.json, requirements.txt, Gemfile) • Utilizar ferramentas de empacotamento (composer, pip, maven, bundle) • Dependencias de recursos de SO devem ser vendorizadas em um novo app
  34. II - Dependências • Devem ser declaradas e isoladas •

    Devem estar presentes em um arquivo manifesto (composer.json, requirements.txt, Gemfile) • Utilizar ferramentas de empacotamento (composer, pip, maven, bundle) • Dependencias de recursos de SO devem ser vendorizadas em um novo app • Mudanças são rapidamente detectadas na construção
  35. II - Dependências • Devem ser declaradas e isoladas •

    Devem estar presentes em um arquivo manifesto (composer.json, requirements.txt, Gemfile) • Utilizar ferramentas de empacotamento (composer, pip, maven, bundle) • Dependencias de recursos de SO devem ser vendorizadas em um novo app • Mudanças são rapidamente detectadas na construção Docker • Dependências ficam explícitas no Dockerfile (FROM, ADD, COPY)
  36. II - Dependências 1 FROM nginx:1.9.9 2 RUN apt-get update

    \ 3 && apt-get install -y -q --no-install-recommends \ 4 ca-certificates \ 5 wget \ 6 && apt-get clean \ 7 && rm -r /var/lib/apt/lists/* 8 RUN echo "daemon off;" >> /etc/nginx/nginx.conf \ 9 && sed -i 's/^http {/&\n server_names_hash_bucket_size 128; /g' /etc/nginx/nginx.conf
  37. II - Dependências 1 ADD https://github.com/alanxz/rabbitmq-c/archive/v0.5.2.zip /rabbitmq-c-0.5.2.zip 2 RUN unzip

    rabbitmq-c-0.5.2.zip \ 3 && cd rabbitmq-c-0.5.2 \ 4 && autoreconf -i \ 5 && ./configure \ 6 && make \ 7 && make install \ 8 && pecl install amqp \
  38. II - Dependências 9 && echo "extension=amqp.so" > /etc/php5/mods-available/amqp. ini

    \ 10 && cd / \ 11 && rm rabbitmq-c-0.5.2.zip \ 12 && rm -rf rabbitmq-c-0.5.2
  39. "Quando o relógio bate as três, todas as caveiras imitam

    chinês." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  40. • Configurações devem ser armazenadas no ambiente III - Configurações

  41. • Configurações devem ser armazenadas no ambiente • Configuração é

    tudo que varia conforme o deploy (dev, homolog, QA, instâncias em produção) III - Configurações
  42. • Configurações devem ser armazenadas no ambiente • Configuração é

    tudo que varia conforme o deploy (dev, homolog, QA, instâncias em produção) • Informações de acesso a recursos (Servidores de Storage, Serviço de cache, Acesso a banco de dados) III - Configurações
  43. III - Configurações • Configurações devem ser armazenadas no ambiente

    • Configuração é tudo que varia conforme o deploy (dev, homolog, QA, instâncias em produção) • Informações de acesso a recursos (Servidores de Storage, Serviço de cache, Acesso a banco de dados) Docker • Ao construir e ao iniciar um container podemos definir variáveis de ambiente
  44. III - Configurações 1 export TESTING="12 factor"

  45. III - Configurações 1 docker run -d --name web \

    2 --env TESTING="12 factor" nginx 3 docker run -d --name backend \ 4 --env-file ./env-file myimage/backend 5 docker run -d --name db \ 6 --env "MYSQL_ROOT_PASSWORD=senha" \ 7 --env "MYSQL_DATABASE=mydb" mysql
  46. III - Configurações 1 <?php 2 3 $var = getenv('TESTING');

    4 echo $var; //12 factor
  47. "Quando o relógio bate as quatro, todas as caveiras tiram

    retrato." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  48. IV - Serviços de Apoio • Trate serviços de apoio

    como recursos anexados.
  49. IV - Serviços de Apoio • Trate serviços de apoio

    como recursos anexados. • São serviços consumidos via rede
  50. IV - Serviços de Apoio • Trate serviços de apoio

    como recursos anexados. • São serviços consumidos via rede • Exemplos: MySQL, Redis, Memcache, APIs, serviços de e-mail, Filas
  51. IV - Serviços de Apoio • Trate serviços de apoio

    como recursos anexados. • São serviços consumidos via rede • Exemplos: MySQL, Redis, Memcache, APIs, serviços de e-mail, Filas • Por ser anexado podemos trocar o recurso caso apresente problemas
  52. IV - Serviços de Apoio • Trate serviços de apoio

    como recursos anexados. • São serviços consumidos via rede • Exemplos: MySQL, Redis, Memcache, APIs, serviços de e-mail, Filas • Por ser anexado podemos trocar o recurso caso apresente problemas Docker: • Os serviços de apoio também podem ser outros containers
  53. IV - Serviços de Apoio 1 # docker-compose.yml 2 web:

    3 image: account/webimage 4 ports: 5 - "80:80" 6 links: 7 - "redis:redis.dev" 8 - "mysql-write:mysql02.service-provider.com" 9 - "mysql-read:192.168.1.77" 10 redis: 11 image: redis:2.8 12 hostname: redis.dev 13 ports:
  54. IV - Serviços de Apoio 12 hostname: redis.dev 13 ports:

    14 - "6379:6379" 15 entrypoint: ["redis-server"] 16 command: ["--appendonly", "yes"]
  55. "Quando o relógio bate as cinco, todas as caveiras apertam

    os cintos." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  56. V - Contruir, lançar e executar • Separemos claramente os

    estágios de construção e execução
  57. V - Contruir, lançar e executar • Separemos claramente os

    estágios de construção e execução • Construção é a montagem do artefato e provisionamento de dependências
  58. V - Contruir, lançar e executar • Separemos claramente os

    estágios de construção e execução • Construção é a montagem do artefato e provisionamento de dependências • Na construção que temos que detectar problemas (testes automatizados)
  59. V - Contruir, lançar e executar • Separemos claramente os

    estágios de construção e execução • Construção é a montagem do artefato e provisionamento de dependências • Na construção que temos que detectar problemas (testes automatizados) • Lançamento é combinação do artefato com a configuração do ambiente de deploy
  60. V - Contruir, lançar e executar • Separemos claramente os

    estágios de construção e execução • Construção é a montagem do artefato e provisionamento de dependências • Na construção que temos que detectar problemas (testes automatizados) • Lançamento é combinação do artefato com a configuração do ambiente de deploy • Cada lançamento deve ter um identificador único (release)
  61. V - Contruir, lançar e executar • Separemos claramente os

    estágios de construção e execução • Construção é a montagem do artefato e provisionamento de dependências • Na construção que temos que detectar problemas (testes automatizados) • Lançamento é combinação do artefato com a configuração do ambiente de deploy • Cada lançamento deve ter um identificador único (release) • Execução é a inicialização dos processos para fazer o app funcionar
  62. V - Contruir, lançar e executar Docker • No Docker

    temos o mote: build, ship and run anywhere
  63. V - Contruir, lançar e executar 1 docker build \

    2 -f Dockerfile-production \ 3 -t username/image \ 4 ./container/ 5 docker push username/image 6 docker run -d username/images
  64. "Quando o relógio bate as seis, todas as caveiras jogam

    xadrez." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  65. • Executar a aplicação com um ou mais processos VI

    - Processos
  66. • Executar a aplicação com um ou mais processos •

    A aplicação não deve guardar estado VI - Processos
  67. • Executar a aplicação com um ou mais processos •

    A aplicação não deve guardar estado • Dados devem ser persistidos e recuperados de serviços de apoio VI - Processos
  68. • Executar a aplicação com um ou mais processos •

    A aplicação não deve guardar estado • Dados devem ser persistidos e recuperados de serviços de apoio • Não devem ser daemon ou ter arquivo PID, deve trabalhar com o ambiente (upstart) VI - Processos
  69. • Executar a aplicação com um ou mais processos •

    A aplicação não deve guardar estado • Dados devem ser persistidos e recuperados de serviços de apoio • Não devem ser daemon ou ter arquivo PID, deve trabalhar com o ambiente (upstart) Docker • Cada contêiner tem seu processo único VI - Processos
  70. VI - Processos • Executar a aplicação com um ou

    mais processos • A aplicação não deve guardar estado • Dados devem ser persistidos e recuperados de serviços de apoio • Não devem ser daemon ou ter arquivo PID, deve trabalhar com o ambiente (upstart) Docker • Cada contêiner tem seu processo único • Pode ser adicionado processos aos contêineres
  71. VI - Processos 1 # docker-compose.yml 2 redis: 3 image:

    redis:2.8 4 ports: 5 - "6379:6379" 6 entrypoint: ["redis-server"] 7 command: ["--appendonly", "yes"]
  72. "Quando o relógio bate as sete, todas as caveiras jogam

    basquete." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  73. • Exportar os serviços através do vínculo de portas VII

    - Vínculo de portas
  74. • Exportar os serviços através do vínculo de portas •

    Cada app deve escutar e receber as requisições em sua porta VII - Vínculo de portas
  75. • Exportar os serviços através do vínculo de portas •

    Cada app deve escutar e receber as requisições em sua porta Docker • Cada container pode exportar uma porta e o vínculo é feito em uma porta do host VII - Vínculo de portas
  76. VII - Vínculo de portas • Exportar os serviços através

    do vínculo de portas • Cada app deve escutar e receber as requisições em sua porta Docker • Cada container pode exportar uma porta e o vínculo é feito em uma porta do host • Podemos escolher qual porta do host será vinculada ao container
  77. VII - Vínculo de portas 1 # docker-compose.yml 2 web:

    3 image: username/webimage 4 ports: 5 - "80" 6 - "443" 7 - "8000:8000"
  78. "Quando o relógio bate as oito, todas as caveiras comem

    biscoito." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  79. • Escalar com base no processo usado como modelo VIII

    - Concorrência
  80. • Escalar com base no processo usado como modelo •

    Processos podem ser web ou workers VIII - Concorrência
  81. • Escalar com base no processo usado como modelo •

    Processos podem ser web ou workers • Mais processos em paralelo, mais requisições são respondidas ou mais rápido terminam processamentos em lote. VIII - Concorrência
  82. VIII - Concorrência • Escalar com base no processo usado

    como modelo • Processos podem ser web ou workers • Mais processos em paralelo, mais requisições são respondidas ou mais rápido terminam processamentos em lote. Docker • Podemos escalar a quantidade de contêineres que executam uma tarefa.
  83. VIII - Concorrência 1 docker-compose scale web=5 worker=3 2 docker-compose

    scale web=1 worker=1
  84. "Quando o relógio bate as nove, todas as caveiras se

    sacodem." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  85. • Maximizar robustez IX - Descartabilidade

  86. • Maximizar robustez • Inicialização rápida e desligamento normal e

    suave (gracefull shutdown) IX - Descartabilidade
  87. • Maximizar robustez • Inicialização rápida e desligamento normal e

    suave (gracefull shutdown) • Processos do app são descartáveis IX - Descartabilidade
  88. • Maximizar robustez • Inicialização rápida e desligamento normal e

    suave (gracefull shutdown) • Processos do app são descartáveis • Facilita escalonamento rápido e elástico IX - Descartabilidade
  89. • Maximizar robustez • Inicialização rápida e desligamento normal e

    suave (gracefull shutdown) • Processos do app são descartáveis • Facilita escalonamento rápido e elástico • Evitar desligamento repentino (crash) IX - Descartabilidade
  90. IX - Descartabilidade • Maximizar robustez • Inicialização rápida e

    desligamento normal e suave (gracefull shutdown) • Processos do app são descartáveis • Facilita escalonamento rápido e elástico • Evitar desligamento repentino (crash) Docker: • Trocar uma configuração de um contêiner, subir novos e desligar os antigos
  91. IX - Descartabilidade • Maximizar robustez • Inicialização rápida e

    desligamento normal e suave (gracefull shutdown) • Processos do app são descartáveis • Facilita escalonamento rápido e elástico • Evitar desligamento repentino (crash) Docker: • Trocar uma configuração de um contêiner, subir novos e desligar os antigos • Em um Swarm quando um nó cai os containers são reorganizados nos demais
  92. IX - Descartabilidade 1 docker run -d -P \ 2

    --memory=512M \ 3 --name webserver \ 4 nginx 5 docker update --memory=1G webserver
  93. "Quando o relógio bate as dez, todas as caveiras comem

    pastéis." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  94. • Manter os ambientes mais similares (desenvolvimento, homologação, produção) X

    - Paridade Dev/Prod
  95. • Manter os ambientes mais similares (desenvolvimento, homologação, produção) •

    Minimizar a lacuna de tempo (deploy em horas ou minutos) X - Paridade Dev/Prod
  96. • Manter os ambientes mais similares (desenvolvimento, homologação, produção) •

    Minimizar a lacuna de tempo (deploy em horas ou minutos) • Minimizar a lacuna de pessoal (devs codam, ops fazem deploy) X - Paridade Dev/Prod
  97. X - Paridade Dev/Prod • Manter os ambientes mais similares

    (desenvolvimento, homologação, produção) • Minimizar a lacuna de tempo (deploy em horas ou minutos) • Minimizar a lacuna de pessoal (devs codam, ops fazem deploy) • Minimizar a lacuna de ferramentas (Dev com OSX, Nginx 1.2.1, PHP 7.0.3 e MySQL 5.6 - Prod com Nginx 1.9, PHP 5.5.33 e Percona 5.6)
  98. X - Paridade Dev/Prod • Manter os ambientes mais similares

    (desenvolvimento, homologação, produção) • Minimizar a lacuna de tempo (deploy em horas ou minutos) • Minimizar a lacuna de pessoal (devs codam, ops fazem deploy) • Minimizar a lacuna de ferramentas (Dev com OSX, Nginx 1.2.1, PHP 7.0.3 e MySQL 5.6 - Prod com Nginx 1.9, PHP 5.5.33 e Percona 5.6) Docker: • Os contêineres que rodam em dev tem as mesmas versões das instâncias em produção
  99. 1 percona: 2 image: percona:5.6 3 ports: 4 - "3306:3306"

    5 environment: 6 - "MYSQL_ROOT_PASSWORD=senha" 7 - "MYSQL_DATABASE=db" X - Paridade Dev/Prod
  100. X - Paridade Dev/Prod 8 rabbit: 9 image: rabbitmq:3-management 10

    ports: 11 - "5672:5672" 12 - "15672:15672" 13 environment: 14 - "TERM=linux" 15 - "RABBITMQ_NODENAME=rabbit" 16 - "RABBITMQ_DEFAULT_PASS=senha" 17 - "RABBITMQ_DEFAULT_USER=admin"
  101. X - Paridade Dev/Prod 18 redis: 19 image: redis:2.8 20

    ports: 21 - "6379:6379" 22 entrypoint: ["redis-server"] 23 command: ["--appendonly", "yes"] 24 memcached: 25 image: memcached:1.4 26 ports: 27 - "11211:11211"
  102. "Quando o relógio bate as onze, todas as caveiras sobem

    no bonde." Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  103. • Logs como fluxo de eventos ordenados no tempo XI

    - Logs
  104. • Logs como fluxo de eventos ordenados no tempo •

    O app escreve os eventos no fluxo stdout XI - Logs
  105. • Logs como fluxo de eventos ordenados no tempo •

    O app escreve os eventos no fluxo stdout • Em dev os logs são consultados acessando os arquivos XI - Logs
  106. • Logs como fluxo de eventos ordenados no tempo •

    O app escreve os eventos no fluxo stdout • Em dev os logs são consultados acessando os arquivos • Em homolog e produção são capturados em roteadores tipo fluent, logplex, logstash XI - Logs
  107. • Logs como fluxo de eventos ordenados no tempo •

    O app escreve os eventos no fluxo stdout • Em dev os logs são consultados acessando os arquivos • Em homolog e produção são capturados em roteadores tipo fluent, logplex, logstash • Busca e apresentação de logs com ferramentas tipo ELK (Elastic Search, Logstash e Kibana) XI - Logs
  108. XI - Logs Docker • Containers tem drivers de log

  109. XI - Logs Docker • Containers tem drivers de log

    • Suporte a json-file, syslog, journald, gelf, fluentd, awslogs e splunk
  110. XI - Logs 1 docker run \ 2 --log-driver=fluentd \

    3 --log-opt fluentd-address=localhost:24224 \ 4 --log-opt tag=docker.{{.Name}}
  111. "Quando o relógio bate as doze, todas as caveiras fazem

    pose" Tumbalacatumba tumba tá, tumbalacatumba tumba tá
  112. • Tarefas administrativas são como processos pontuais XII - Processos

    Administrativos
  113. • Tarefas administrativas são como processos pontuais • Mesmo codebase

    XII - Processos Administrativos
  114. • Tarefas administrativas são como processos pontuais • Mesmo codebase

    • Executar em ambiente idêntico XII - Processos Administrativos
  115. • Tarefas administrativas são como processos pontuais • Mesmo codebase

    • Executar em ambiente idêntico • Migrações de banco XII - Processos Administrativos
  116. • Tarefas administrativas são como processos pontuais • Mesmo codebase

    • Executar em ambiente idêntico • Migrações de banco • Scripts de rotinas XII - Processos Administrativos
  117. • Tarefas administrativas são como processos pontuais • Mesmo codebase

    • Executar em ambiente idêntico • Migrações de banco • Scripts de rotinas Docker • Técnica de conteinerização de comandos XII - Processos Administrativos
  118. XII - Processos Administrativos • Tarefas administrativas são como processos

    pontuais • Mesmo codebase • Executar em ambiente idêntico • Migrações de banco • Scripts de rotinas Docker • Técnica de conteinerização de comandos • Adicionar processo ao contêiner com docker exec
  119. XII - Processos Administrativos 1 # subindo o server 2

    docker run --name db -d -P \ 3 --env "MYSQL_ROOT_PASSWORD=senha" \ 4 --env "MYSQL_DATABASE=banco" \ 5 percona
  120. XII - Processos Administrativos 6 # rodando o client 7

    docker run -it \ 8 --link db:db \ 9 --rm percona \ 10 sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" - 11 P"$MYSQL_PORT_3306_TCP_PORT" -uroot - p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'
  121. Q&A

  122. https://joind.in/talk/91f92 https://speakerdeck.com/wsilva Slides & Feedback