├── README.md ├── composes ├── docker-compose-01.yaml ├── docker-compose-02.yaml ├── docker-compose-03.yaml ├── docker-compose-04-original-aula.yaml ├── docker-compose-04.yaml └── docker-compose-05.yaml └── traefik ├── loja-https.yaml ├── loja.yaml ├── store.yaml ├── traefik_deploy-https.yaml └── traefik_deploy.yaml /README.md: -------------------------------------------------------------------------------- 1 | # Descomplicando o Docker - LinuxTips 2 | 3 | ## Dicas sobre a Certificação DCA 4 | *Study Guide:* 5 | https://docker.cdn.prismic.io/docker/3f8ef3b3-87f1-47c7-b820-0e0a8bb308d4_DCA_study_guide_+v1.1+pdf.pdf 6 | *DevOps Academy:* https://github.com/DevOps-Academy-Org/dca-prep-guide 7 | https://medium.com/@cristianvitortrucco/docker-dca-8be5bb09eb44 8 | https://prismic-io.s3.amazonaws.com/docker%2Fa2d454ff-b2eb-4e9f-af0e-533759119eee_dca+study+guide+v1.0.1.pdf 9 | 10 | Simulação: https://djitz.com/certification/docker-certified-associate-dca-certification-test-resources/ 11 | 12 | Repositório com links organizados para os estudo: https://github.com/Evalle/DCA 13 | 14 | UCP: https://docs.docker.com/ee/ucp/ 15 | 16 | 17 | 18 | 19 | - Certificação tem validade por 2 anos 20 | - A prova tem 55 questões de múltipla escolha 21 | - Tempo de 90 minutos para finalizar a prova 22 | - A prova é online 23 | - *Só da pra fazer em pc _Windows_ ou _Mac_, infelizmente a plataforma não é compatível com o melhor SO do mundo: _Linux_* 24 | - A prova é em inglês 25 | - O treinamento da LinuxTips não cobriu UCP, DTR, Docker EE entre outros, portanto, estudar isso por fora 26 | - A prova do Docker não tem Retake, logo estude pra passar de primeira 27 | 28 | ## Iniciando com Docker 29 | ### Instalação do Docker 30 | 31 | 32 | ### Melhores práticas para o Dockerfile 33 | 34 | 35 | ### Entenda recursos do kernel como namespace e cgroups 36 |
37 | 38 | 39 | ### Comandos básicos 40 | ``` sh 41 | docker container run -d IMAGENAME 42 | docker container attach CONTAINERID 43 | docker container exec -ti CONTAINERID 44 | 45 | docker container stop CONTAINERID 46 | docker container rm CONTAINERID 47 | docker container start CONTAINERID 48 | docker container restart CONTAINERID 49 | docker container pause CONTAINERID 50 | docker container unpause CONTAINERID 51 | 52 | docker container inspect CONTAINERID 53 | docker container logs -f CONTAINERID 54 | 55 | docker image inspect IMAGEMID 56 | docker image history IMAGEMID 57 | ``` 58 | 59 | ### Uso de Recursos 60 | 61 | * Informações de CPU, MEM, IO rede, IO de bloco 62 | ``` sh 63 | docker container stat CONTAINERID 64 | ``` 65 | 66 | * TOP igual ao do Linux, mostra os processo 67 | ``` sh 68 | docker container top CONTAINERID 69 | ``` 70 | 71 | * Limitando Memória e CPU 72 | _A CPU é especificada em percent, logo o range de valor vai de 0.01 até 1.00 73 | O valor acima "0.25" está limitando o uso do container em até 25% de CPU._ 74 | ``` sh 75 | docker container run -d -m 128M IMAGENAME 76 | docker container run -d --cpu 0.25 -m 256M IMAGENAME 77 | 78 | docker container update --cpus 0.5 CONTAINERID 79 | docker container update --cpus 1 --memory 64M CONTAINERID 80 | ``` 81 | 82 | ## Dockerfile 83 | *Exemplo* 84 | ``` yaml 85 | FROM debian 86 | 87 | LABEL app="Certificado" 88 | ENV TREINAMENTO="Docker" 89 | 90 | RUN apt-get update && apt-get install -y stress && apt-get clean 91 | 92 | CMD stress --cpu 1 --vm-bytes 64M --vm 1 93 | ``` 94 | 95 | *Build* 96 | ``` sh 97 | docker image build -t IMAGENAME: . 98 | ``` 99 | 100 | ## Volumes 101 | ### Tipo BIND 102 | * Montar um diretório específico no container 103 | ``` sh 104 | docker container run -ti --mount type=bind,src=/diretorio/local,dst=/meuVolume IMAGENAME 105 | docker container run -ti --mount type=bind,src=/diretorio/local,dst=/meuVolume,ro IMAGENAME 106 | ``` 107 | 108 | > Se você colocar um Volume no dockerfile e não especifícá-lo no "docker run", o Docker irá criar um volume com um nome aleatório. Isso é ruim para a gestão de volumes que o administrador deverá ser responsável. 109 | 110 | ### Tipo VOLUME 111 | ``` sh 112 | docker volume create MEUVOLUME 113 | docker volume ls 114 | docker volume inspect MEUVOLUME 115 | docker volume rm MEUVOLUME 116 | docker volume prune 117 | ``` 118 | 119 | > Os dados do volume serão armazenados no diretório */var/lib/docker/volumes/meuVolume/_data* 120 | 121 | * Montar o volume no container 122 | ``` sh 123 | docker container run -ti --mount type=volume,src=MEUVOLUME,dst=/meuVolume IMAGENAME 124 | ``` 125 | 126 | ## Dockerfile 127 | ### Exemplo de Dockerfile 128 | ``` yaml 129 | FROM debian 130 | 131 | RUN apt-get update && apt-get install -y apache2 && apt-get clean 132 | 133 | ENV APACHE_LOCK_DIR="/var/lock" 134 | ENV APACHE_PID_FILE="/var/run/apache2.pid" 135 | ENV APACHE_RUN_USER="www-data" 136 | ENV APACHE_RUN_GROUP="www-data" 137 | ENV APACHE_LOG_DIR="/var/log/apache2" 138 | 139 | LABEL description="Webserver" 140 | 141 | VOLUME /var/www/html 142 | EXPOSE 80 143 | 144 | ENTRYPOINT ["/usr/sbin/apachectl"] 145 | CMD ["-D", "FOREGROUND"] 146 | ``` 147 | 148 | > ENTRYPOINT: Principal processo do container, é um INIT do container.
149 | > CMD: O CMD apenas passa parâmetros para o processo principal. No exemplo o ENTRYPOINT é o *apachectl*, então passamos o parâmetro para iniciar o apache em FOREGROUND. 150 | 151 | ### Constuindo a image a partir do Dockerfile 152 | ``` sh 153 | docker image build -t meu-apache:1.0 154 | docker image build -t meu-apache:1.0 -no-cache 155 | ``` 156 | 157 | ### Outras instruções do Dockerfile 158 | |COMANDO |DESCRIÇÃO | 159 | |---------------|-----------------------| 160 | |COPY |Copia arquivo para dentro do container durante o build| 161 | |ADD |Copiar arquivo para dentro do container durante o build, porém pode especificar uma URL para download e também arquivos compactados serão descompactados no container| 162 | |RUN |Executa comandos dentro do container| 163 | |ENV |Cria uma variável de ambiente| 164 | |USER |Especifica um usuário dentro do container para executar os processos| 165 | |WORKDIR |Diretório padrão do container| 166 | |CMD |Executa um comando, diferente do RUN que executa o comando no momento em que está "buildando" a imagem, o CMD executa no início da execução do container| 167 | |LABEL |Adiciona metadados a imagem como versão, descrição e fabricante| 168 | |COPY |Copia novos arquivos e diretórios e os adicionam ao filesystem do container| 169 | |ENTRYPOINT |Permite você configurar um container para rodar um executável, e quando esse executável for finalizado, o container também será| 170 | |ENV |Informa variáveis de ambiente ao container| 171 | |EXPOSE |Informa qual porta o container estará ouvindo| 172 | |FROM |Indica qual imagem será utilizada como base, ela precisa ser a primeira linha do Dockerfile| 173 | |MAINTAINER |Autor da imagem| 174 | |RUN |Executa qualquer comando em uma nova camada no topo da imagem e "commita" as alterações. Essas alterações você poderá utilizar nas próximas instruções de seu Dockerfile| 175 | |USER |Determina qual o usuário será utilizado na imagem. Por default é o root| 176 | |VOLUME |Permite a criação de um ponto de montagem no container| 177 | |WORKDIR |Responsável por mudar do diretório / (raiz) para o especificado nele| 178 | 179 | 180 | ### Argumentos (ARG) 181 | 182 | ``` yaml 183 | FROM ubuntu 184 | ARG CONT_IMG_VER 185 | ENV CONT_IMG_VER v1.0.0 186 | RUN echo $CONT_IMG_VER 187 | ``` 188 | 189 | Nesse exemplo o container quando executado irá printar a string v1.0.0. 190 | Essa string pode ser alterada durante o build da imagem como mostrado abaixo: 191 | ``` 192 | docker build --build-arg CONT_IMG_VER=2.0.0 -f Dockerfile . 193 | ``` 194 | 195 | Agora quando o container dessa imagem for executado, será mostrada a string v2.0.0. 196 | 197 | ### HEALTHCHECK 198 | 199 | ``` yaml 200 | HEALTCHECK --interval 5m --timeout=3s \ 201 | CMD curl --retry-max-time 2 -f http://localhost/ || exit 1 202 | ``` 203 | 204 | Adicionando a linha acima em uma imagem com o Apache, o healtcheck checará a cada 5 minutos se a URL localhost está respondendo, caso ela falhe "||" então o container será encerrado com o código 1. 205 | > Atenção: o comando utilizado para o healthcheck deve existir na imagem. 206 | 207 | ## Imagens 208 | ``` sh 209 | docker image pull http 210 | docker image ls 211 | docker image insepect IMAGENAME 212 | docker image prune --all --filter until=240h 213 | docker image prune -a 214 | docker image tag IMAGEID NOMEDAIMAGEM:VERSAOIMAGEM 215 | ``` 216 | 217 | ### EDITANDO UMA IMAGEM "COMMIT" 218 | 219 | ``` sh 220 | docker container run -it ubuntu 221 | ``` 222 | 223 | Altere a image conforme sua necessidade, saia do container com *Ctrl + P + Q* para que o mesmo continue em execução e commite as alterações na imagem: 224 | 225 | ``` sh 226 | docker commit -m "Descrição da alteração" CONTAINERID 227 | docker image tag : 228 | ``` 229 | 230 | > Prefira sempre realizar alterações via Dockerfile, pois com o Dockerfile é possível recriar a imagem novamente em caso de perda, e todas as alterações ficarão registradas. 231 | 232 | 233 | ## MultiStage 234 | A utilização do multistage é utilizado para reduzir o tamanho da imagem final. 235 | Por exemplo, para uma aplicação GO, precisaríamos utilizar a imagem GOLANG para realizar o build da imagem, essa imagem possui em torno de 800MB, logo minha imagem final teria os 800MB mais o tamanho da minha aplicação GO. 236 | Para contornar isso, poderíamos utilizar a imagem GOLANG apenas para gerar o executável da aplicação GO e depois copia-lo para uma imagem menor como a imagem ALPINE. 237 | OBS: A utilização do MULTISTAGE depende muito de como funciona sua aplicação, pois é necessário copiar os arquivos para a outra imagem, com exemplo o APACHE seria bem difícil de fazer. 238 | Apenas como comparação, utilizando o multistage a imagem final ficou com 7MB e sem o multistage a imagem final ficou com 800MB. 239 | 240 | Aplicação e Go que será usada na imagem 241 | ``` go 242 | package main 243 | import "fmt" 244 | 245 | func main() { 246 | fmt.Println("Giropops Strigus Girus") 247 | } 248 | ``` 249 | 250 | Imagem sem o MultiStage -> 700MB 251 | ``` yaml 252 | FROM golang 253 | 254 | WORKDIR /app 255 | ADD . /app 256 | RUN go build -o meugo 257 | 258 | ENTRYPOINT ./meugo 259 | ``` 260 | 261 | Imagem usando o MultiStage -> 7MB 262 | ``` yaml 263 | FROM golang AS buildando 264 | 265 | WORKDIR /app 266 | ADD . /app 267 | RUN go build -o meugo 268 | 269 | FROM alpine 270 | WORKDIR /app 271 | COPY --from=buildando /app/meugo /app 272 | 273 | ENTRYPOINT ./meugo 274 | ``` 275 | 276 | ## Dicas 277 | - Remova do contêiner tudo que não será usado, lembrando que deve limpar na camada de escrita. 278 | - Reduza o número de camadas da imagem. 279 | - Utilize o MultiStage sempre que possível. 280 | - Utilize o .Dockerignore. 281 | - Adicione o non-root user, Utilize outro usuário para executar sua aplicação. 282 | - As vezes o cache é problemático, pois se houve uma atualização na versão da aplicação que está em repositório APT, ela pode não ser atualizada por estar em cache, esse é um exemplo de problema ao usar o cache, porém ele é muito útil. 283 | - Contêineres são imutáveis e efêmeros, sendo assim ele nasceu pra morrer, não confunda este com uma VM. 284 | - As variáveis declaradas na instrução ENV do dockerfile pode ser utilizada dentro do próprio dockerfile. 285 | - SHELL ["powershell", "-command"] essa instrução muda o shell do container. 286 | - ARGS Argumento que posso utilizar durante o build da imagem. 287 | - HEALTHCHECK, uma forma de verificar se o container está íntegro. 288 | 289 | 290 | ## Container Registry (CR) 291 | ### Login 292 | Login no Docker Hub 293 | ``` sh 294 | docker login 295 | ``` 296 | 297 | Login em um CR que não seja o Docker Hub 298 | ``` sh 299 | docker login URL-CR 300 | ``` 301 | 302 | ### Upload de imagem 303 | ``` sh 304 | docker push IMAGENAME:IMAGEVERSION 305 | ``` 306 | 307 | ### Um container para um CR 308 | ``` sh 309 | docker container run -d -p 5000:5000 --restart=always --name registry registry:2 310 | ``` 311 | 312 | As imagens do CR ficam armazenadas em: 313 | ```/var/lib/registry/docker/registry/v2/repositories/meu_apache``` 314 | 315 | ### Verificando imagens de um CR 316 | ``` sh 317 | curl localhost:5000/v2/_catalog 318 | curl localhost:5000/v2/meu_apache/tags/list 319 | ``` 320 | 321 | ## Docker-machine 322 | *docker-machine* é utilizado criar uma VM remota para rodar o docker, pode ser utilizado para criar a VM na AWS, Digital Ocean, Virtual Box, Hyper-V entre outros. 323 | 324 | Utilize o docker-machine para gerenciar um host remoto com o Docker 325 | 326 | ### Instalação 327 | ``` sh 328 | curl -L https://github.com/docker/machine/releases/download/v0.16.1 329 | /docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine 330 | chmod +x /tmp/docker-machine 331 | sudo cp /tmp/docker-machine /usr/local/bin/docker-machine 332 | ``` 333 | 334 | ### Criando um host para docker no VirtualBox e Hyper-V 335 | ``` sh 336 | docker-machine create --driver virtualbox NOMEDAVM 337 | docker-machine create --driver hyperv --hyperv-virtual-switch "DockerMachineNetwork" NOMEDAVM 338 | ``` 339 | 340 | ### Comandos úteis do docker-machine 341 | ``` sh 342 | docker-machine ls 343 | docker-machine start NOMEDAVM 344 | docker-machine stop NOMEDAVM 345 | docker-machine ip NOMEDAVM 346 | docker-machine ssh NOMEDAVM 347 | docker-machine inspect NOMEDAVM 348 | docker-machine status NOMEDAVM 349 | docker-machine rm NOMEDAVM 350 | ``` 351 | 352 | ### Conectando o Docker client local em um Host remoto docker. 353 | ``` sh 354 | eval $(docker-machine env NOMEDAVM) 355 | ``` 356 | Feito isso, os comando *docker* serão executados no host remoto e não no local. Utilize para gerenciar hosts remotos com o docker da sua estação de trabalho. 357 | 358 | Para voltar o cliente para o host local 359 | ``` sh 360 | eval $(docker-machine env -u) 361 | ``` 362 | 363 | ## SWARM 364 | Swarm é um orquestrador de container oficial do Docker, é como um Kubernetes. 365 | 366 | Gerenciamento de Container (Orquestrador) 367 | - Worker: responsável apenas por carregar os container 368 | - Manager: sabe todos os detalhes do cluster 369 | 370 | Para um cluster saudável, precisamos ter no mínimo 51% de manager online. 371 | pensando assim se temos 5 nós, devemos ter 3 managers, pois se houver apenas 2 managers e um deles cair, terei 50% nos manager online, com isso meu cluster vai pro saco. 372 | 373 | Por que não usar todos os nós como managers então? 374 | qdo temos um cluster swarm e um manager apresenta problema, ocorre um processo chamado de eleição para decidir qual dos managers será o principal novamente, logo quanto mais managers exisitir maior o tempo para um nó ser eleito e maior o tempo de downtime do ambiente. 375 | 376 | ### Antes precisa da seguinte liberação de portas TCP/UDP 377 | 378 | - 2377 TCP Utilizada para o gerenciamento do Cluster 379 | - 7946 TCP/UDP Comunicação entre os Nós do Cluster 380 | - 4789 UDP Porta de comunicação entre a rede Overlay 381 | 382 | ### Iniciar um cluster 383 | ``` sh 384 | docker swarm init --advertise-addr IpDaInterfaceDeRede 385 | 386 | # (command output) 387 | #Swarm initialized: current node (taxeaef969y2bm5attuxtxxug) is now a manager. 388 | # 389 | #To add a worker to this swarm, run the following command: 390 | # 391 | # docker swarm join --token SWMTKN-1-2b77msrwdciljb8vivzusy01sgf9x2kghkqdzucyostquj3o5e-b9swdjndhbqw9yj9vy5h6ec7s 172.29.241.39:2377 392 | # 393 | #To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. 394 | ``` 395 | 396 | ### Listar nós de um cluster 397 | ``` sh 398 | docker node ls 399 | ``` 400 | 401 | ### Adicionar um novo worker ao Cluster Swarm 402 | 1. No nó "manager" execute o comando abaixo para conseguir o token e o comando para adicionar o worker 403 | ``` sh 404 | docker swarm join-token worker 405 | ``` 406 | 407 | 2. Execute o comando o token informado 408 | ``` sh 409 | docker swarm join --token SWMTKN-1-2b77msrwdciljb8vivzusy01sgf9x2kghkqdzucyostquj3o5e-b9swdjndhbqw9yj9vy5h6ec7s 172.29.241.39:2377 410 | ``` 411 | 412 | ### Adicionar um novo manager ao Cluster Swarm 413 | 1. No nó "manager" execute o comando abaixo para conseguir o token e o comando para adicionar o manager 414 | ``` sh 415 | docker swarm join-token manager 416 | ``` 417 | 418 | 2. Execute o comando o token informado 419 | ``` sh 420 | docker swarm join --token SWMTKN-1-2b77msrwdciljb8vivzusy01sgf9x2kghkqdzucyostquj3o5e-di7qyk01kdyig3ajww6nadr6m 172.29.241.39:2377 421 | ``` 422 | 423 | ### Promover / Despromover um nó à Manager 424 | ``` sh 425 | docker node promote HOSTNAME 426 | docker node demote HOSTNAME 427 | ``` 428 | 429 | ### Remover um nó do cluster apartir do manager 430 | ``` sh 431 | docker swarm demote HOSTNAME 432 | docker swarm rm -f HOSTNAME 433 | ``` 434 | 435 | ### Remover pelo próprio nó 436 | ``` sh 437 | docker swarm leave 438 | docker swarm leave -f 439 | ``` 440 | 441 | > Recomenda-se alterar os tokens periodicamente por segurança. 442 | ``` sh 443 | docker swarm join-token --rotate manager 444 | docker swarm join-token --rotate worker 445 | ``` 446 | 447 | ### Docker SWARM Node 448 | Opção "Availability" 449 | ``` sh 450 | docker node update --availability [ drain | pause | active ] NOMEDAVM 451 | ``` 452 | |OPÇÃO |DESCRIÇÃO | 453 | |---------|-------------------------------------------------------------------------------------------------------------------| 454 | |*Drain* |O nó não receberá nenhum novo container e os container atuais do nó são desligados | 455 | |*Pause* |Nenhum novo container é adicionado ao container,
porém os atuais containers do nó continuam rodando normalmente | 456 | |*Active* |O nó recebe os containers normalmente | 457 | 458 | ``` sh 459 | docker node inspect NOMEDAVM 460 | ``` 461 | 462 | ### Docker SWARM Service 463 | 464 | - Swarm é a resiliência dos nós enquanto o Service é uma forma de ter resiliência nos containers. 465 | - A comunicação interna dos container não são realizadas por IP e sim por nome de serviço, ou seja, o nome do serviço responde como um VIP ou DNS. 466 | - SERVICE é um conjunto de container respondendo para o mesmo serviço, como se fosse um único servidor. 467 | - Quando se cria um service, informa a quantidade de replicas (tasks) desejadas, isso é a quantidade de container que será criado. 468 | - O Service faz o balanceamento de carga no estilo Round Robin. 469 | - Quando uma porta é publicada para um container, mesmo que houver apenas uma réplica do container no cluster, esta porta estará publicada em todos os nós do cluster e todos eles redirecionaram para o container, ou seja, todos os nós sabem onde os container estão sendo executados, logo é possível se conectar ao serviço utilizando qualquer IP de um dos nós do cluster. 470 | 471 | #### Exemplo de uso: 472 | ``` sh 473 | docker service create --name --replicas 3 -p 8080:80 nginx 474 | 475 | docker service create --name --hostname -- limit-cpu 0.25 --limit-memory 64M --replicas 3 -p 8080:80 nginx 476 | 477 | docker service create --name --env VARIAVEL=VALOR --replicas 3 -p 8080:80 nginx 478 | 479 | docker service create --dns 8.8.8.8 --name --replicas 3 -p 8080:80 nginx 480 | 481 | docker service create --network rededev --name --replicas 3 -p 8080:80 nginx 482 | ``` 483 | 484 | #### Inspecionar 485 | ``` sh 486 | docker service inspect 487 | docker service inspect --pretty 488 | ``` 489 | 490 | #### Verificar onde os container estão sendo executados 491 | ``` sh 492 | docker service ps 493 | ``` 494 | 495 | #### Verificar o logs de todos os containers: 496 | ``` sh 497 | docker service logs -f 498 | ``` 499 | 500 | #### Escalar containers 501 | ``` sh 502 | docker service scale giropops=9 503 | ``` 504 | 505 | #### Remover o serviço 506 | ``` sh 507 | docker service rm 508 | ``` 509 | 510 | #### Cuidado com volumes 511 | 512 | O *volume* criado em um Nó do cluster não é compartilhado com os outros nós. 513 | Desta forma o serviço do nginx criado no comando abaixo teria problemas de sincronismo de dados. 514 | ``` sh 515 | docker volume create webindex 516 | docker service create --name webserver --replicas 3 --publish 8080:80 --mount type=volume,src=webindex,dst=/usr/share/nginx/html nginx 517 | ``` 518 | 519 | Este volume será criado em todos os nós porém não haverá replicação dos dados, ou seja, alterando o index.html de um dos nós, a alteração estará apenas naquele nó do cluster 520 | 521 | Para  utilizar o volume em todos os nós é necessário utilizar plugins como o *Flocker, GlusterFS, Ceph ou NFS*. 522 | Já indo para o mundo de Cloud, a AWS e Azure com Cloud Store fornecem soluções melhores para esse compartilhamento. 523 | 524 | Algumas fontes de consulta: 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | ## Secrets 534 | Quando está usando um cluster Swarm, é possível utilizar o recurso de secret do docker. 535 | 536 | ### Criar Secret 537 | - Por Arquivo 538 | ``` sh 539 | echo -n "MySecret" > ~/secretFile.txt 540 | docker secret create SecretName SecretFile 541 | ``` 542 | 543 | - Direto pelo comando echo 544 | ``` sh 545 | echo -n "MySecret" | docker secret create SecretName - 546 | ``` 547 | 548 | - As Secret ficam dentro de cada container no arquivo listado abaixo como texto puro, assim pode utilizá-la como achar melhor 549 | - /run/secrets/SecretName 550 | 551 | > Importante colocar a opção "-n" no echo para evitar a quebra de linha. 552 | 553 | ### Verificando e inspecionando secrets disponíveis 554 | ``` sh 555 | docker secret ls 556 | docker secret inspect Secretname 557 | ``` 558 | 559 | ### Removendo uma secret 560 | ``` sh 561 | docker secret rm SecretName 562 | ``` 563 | 564 | ### Subindo um serviço com uma secret 565 | ``` sh 566 | docker service create --name webserver -p 8080:80 --replicas 10 --secret SecretName nginx 567 | ``` 568 | 569 | ### Definindo permissões para o arquivo de secret dentro do container e usando source e target para definir o nome do secret dentro do container 570 | ``` sh 571 | docker service create --name nginx2 -p 8080:80 --secret src=SecretName,target=meu-secret,uid=200,gid=200,mode=0400 nginx 572 | ``` 573 | 574 | ### Adicionando uma secret a serviço já existente 575 | ``` sh 576 | docker service update --secret-add SecretName ServiceName 577 | ``` 578 | 579 | ### Removendo uma secret de um serviço existente 580 | ``` sh 581 | docker service update --secret-rm SecretName ServiceName 582 | ``` 583 | 584 | ### Dica do especialista Jeferson Noronha 585 | >Ele realiza um mix entre o vault do Ansible que é encriptado com o Secret do Docker, assim não expoẽ a senha ou a informação em nenhum lugar. 586 | 587 | ## Compose, Stack e Services 588 | [Instalando o docker-compose] 589 | [Overview do docker-compose] 590 | 591 | _Compose é um ferramenta para definir aplicações Docker multi-container. Com o Compose, você usar um arquio YAML para configurar seus serviços. Então, com um simples comando, você cria e inicia todos os serviços dos seu arquivo de configuração._ 592 | 593 | Services = conjunto de _container_ 594 | Stack = conjunto de _services_ 595 | 596 | A diferença é que quando eu crio um service por linha de comando, eu posso ter vários container para um mesmo serviço, um exemplo, criar um service com 5 réplicas de nginx. 597 | Já quando eu uso o docker-compose e o stack, eu posso definir em um único arquivos, vários serviços e suas réplicas, e apenas usando o _docker stack_ eu consigo subir todos os serviços de uma única vez. 598 | 599 | ### docker-compose file [Primeiro Exemplo] 600 | ``` yaml 601 | version: "3.5" 602 | services: 603 | web: 604 | image: nginx 605 | deploy: 606 | replicas: 5 607 | resources: 608 | limits: 609 | cpus: "0.1" 610 | memory: 50M 611 | restart_policy: 612 | condition: on-failure 613 | ports: 614 | - "8080:80" 615 | networks: 616 | - webserver 617 | networks: 618 | webserver: 619 | ``` 620 | 621 | ### Deploy de um docker-compose em um cluster swarm 622 | ``` sh 623 | docker stack deploy -c docker-compose.yaml STACKNAME 624 | ``` 625 | 626 | ### Análise da STACK 627 | ``` 628 | docker network ls 629 | docker network inspect STACKNAME_NETWORKNAME 630 | docker service ls 631 | docker service inspect STACKNAME_SERVICENAME 632 | docker stack ls 633 | docker stack ps STACKNAME 634 | docker stack services STACKNAME 635 | ``` 636 | 637 | ### Scale 638 | ``` sh 639 | docker service scale STACKNAME_SERVICENAME=10 640 | ``` 641 | 642 | ### Remover a STACK 643 | ``` sh 644 | docker stack rm STACKNAME 645 | ``` 646 | 647 | ### docker-compose file [Segundo Exemplo] 648 | ``` yaml 649 | version: '3' 650 | services: 651 | db: 652 | image: mysql:5.7 653 | volumes: 654 | - db_data:/var/lib/mysql 655 | environment: 656 | MYSQL_ROOT_PASSWORD: somewordpress 657 | MYSQL_DATABASE: wordpress 658 | MYSQL_USER: wordpress 659 | MYSQL_PASSWORD: wordpress 660 | 661 | wordpress: 662 | depends_on: 663 | - db 664 | image: wordpress:latest 665 | ports: 666 | - "8080:80" 667 | environment: 668 | WORDPRESS_DB_HOST: db:3306 669 | WORDPRESS_DB_USER: wordpress 670 | WORDPRESS_DB_PASSWORD: wordpress 671 | 672 | volumes: 673 | db_data: 674 | ``` 675 | 676 | ### docker-compose file [Terceiro Exemplo] 677 | ``` yaml 678 | version: "3.5" 679 | services: 680 | web: 681 | image: nginx 682 | deploy: 683 | placement: 684 | constraints: 685 | - node.labels.dc == UK 686 | replicas: 5 687 | resources: 688 | limits: 689 | cpus: "0.1" 690 | memory: 50M 691 | restart_policy: 692 | condition: on-failure 693 | ports: 694 | - "8080:80" 695 | networks: 696 | - webserver 697 | 698 | visualizer: 699 | image: dockersamples/visualizer:stable 700 | ports: 701 | - "8888:8080" 702 | volumes: 703 | - "/var/run/docker.sock:/var/run/docker.sock" 704 | deploy: 705 | placement: 706 | constraints: [node.role == manager] 707 | networks: 708 | - webserver 709 | 710 | networks: 711 | webserver: 712 | ``` 713 | 714 | > Neste terceiro exemplo, usamos o *_placement: constraints_*, onde indicamos que os containers do serviço *WEB* só podem subir em nodes onde há uma label chamada *DC* e que o seu valor seja *UK*, assim como o serviço *VISUALIZER* irá verificar pela role *MANAGER*. 715 | 716 | * Visualizer:* Subirá apenas nos nodes magagers. 717 | * Web:* Subirá apenas em nodes onde exista uma TAG dc=UK. 718 | 719 | ### Adicionando uma TAG aos nodes 720 | ``` sh 721 | docker node update --label-add dc=UK elliot-01 722 | ``` 723 | 724 | ### docker-compose file [Quarto Exemplo] 725 | 726 | 727 | ``` yaml 728 | version: "3.7" 729 | services: 730 | 731 | redis: 732 | image: redis:alpine 733 | networks: 734 | - frontend 735 | deploy: 736 | replicas: 2 737 | update_config: 738 | parallelism: 2 739 | delay: 10s 740 | order: start-first 741 | rollback_config: 742 | parallelism: 1 743 | delay: 10s 744 | failure_action: continue 745 | monitor: 60s 746 | order: stop-first 747 | restart_policy: 748 | condition: on-failure 749 | db: 750 | image: postgres:9.4 751 | environment: 752 | POSTGRES_USER: "postgres" 753 | POSTGRES_PASSWORD: "postgres" 754 | volumes: 755 | - db-data:/var/lib/postgresql/data 756 | networks: 757 | - backend 758 | deploy: 759 | placement: 760 | constraints: [node.role == manager] 761 | vote: 762 | image: dockersamples/examplevotingapp_vote:before 763 | ports: 764 | - 5000:80 765 | networks: 766 | - frontend 767 | depends_on: 768 | - redis 769 | deploy: 770 | replicas: 2 771 | update_config: 772 | parallelism: 2 773 | restart_policy: 774 | condition: on-failure 775 | result: 776 | image: dockersamples/examplevotingapp_result:before 777 | ports: 778 | - 5001:80 779 | networks: 780 | - backend 781 | depends_on: 782 | - db 783 | deploy: 784 | replicas: 1 785 | update_config: 786 | parallelism: 1 787 | delay: 10s 788 | restart_policy: 789 | condition: on-failure 790 | 791 | worker: 792 | image: dockersamples/examplevotingapp_worker 793 | networks: 794 | - frontend 795 | - backend 796 | depends_on: 797 | - db 798 | - redis 799 | deploy: 800 | mode: replicated 801 | replicas: 1 802 | labels: [APP=VOTING] 803 | restart_policy: 804 | condition: on-failure 805 | delay: 10s 806 | max_attempts: 3 807 | window: 120s 808 | placement: 809 | constraints: [node.role == manager] 810 | 811 | visualizer: 812 | image: dockersamples/visualizer:stable 813 | ports: 814 | - "8080:8080" 815 | stop_grace_period: 1m30s 816 | volumes: 817 | - "/var/run/docker.sock:/var/run/docker.sock" 818 | deploy: 819 | placement: 820 | constraints: [node.role == manager] 821 | 822 | networks: 823 | frontend: 824 | backend: 825 | 826 | volumes: 827 | db-data: 828 | ``` 829 | 830 | #### O que temos de novo no docker-compose acima: 831 | ``` yaml 832 | ... 833 | deploy: 834 | mode: replicated | global 835 | replicas: 2 836 | update_config: 837 | parallelism: 2 838 | delay: 10s 839 | order: start-first 840 | ``` 841 | 842 | |CHAVE|DESCRIÇÃO| 843 | |-----|---------| 844 | |deploy: replicas|Quantidade de containers que a stack irá subir| 845 | |deploy: mode: replicated|Será criado em toda a stack a quantidade de container específicado na opção *replicas*| 846 | |mode: global|Haverá um container por NODE do Swarm, caso um novo node seja adicionado ao cluster, um novo container também será criado neste node. Opção muito utilizada para containers de monitoramento do host| 847 | |updateconfig: parallelism:|Em caso de um update, esta opção indicará quantos containers por vez serão afetados. Neste caso temos duas replicas e elas seriam afetadas ao mesmo tempo, causando indisponibilidade, o melhor seria deixar paralleslism como 1, assim apenas um container por vez seria atualizado.| 848 | | update_config: delay|Considerando o parallelism, o delay indica o tempo entre executar o update no próximo grupo de container| 849 | |update_config: order|valores que podemos usar é *start-first* e *stop_first*. Assim você decide se quer primeiro parar o que está rolando e iniciar os novos containers ou se quer primeiro iniciar os novos container e depois para os antigos| 850 | 851 | 852 | ``` yaml 853 | ... 854 | deploy: 855 | rollback_config: 856 | parallelism: 1 857 | delay: 10s 858 | failure_action: continue 859 | monitor: 60s 860 | order: stop-first 861 | ``` 862 | 863 | |CHAVE|DESCRIÇÃO| 864 | |-----|---------| 865 | |rollback_config|Possui as mesmas opções do *update_config*, porém é claro, para fazer o rollback| 866 | |failure_action: pause|Em caso de falha no rollback de algum container, o sistema irá pause o processo de rollback para que seja analisado o problema| 867 | |failure_action: continue|Em caso de falha no rollback de algum container, o sistema irá continuar executando o processo de rollback, de qualquer forma deve ser analisado o motivo da falha| 868 | |monitor|Tempo que o sistema irá monitorar pra saber se o rollback foi realizado com sucesso| 869 | 870 | ### docker-compose file [Quinto Exemplo] 871 | 872 | ``` yaml 873 | version: "3.7" 874 | services: 875 | prometheus: 876 | image: linuxtips/prometheus_alpine 877 | volumes: 878 | - ./conf/prometheus/:/etc/prometheus/ 879 | - prometheus_data:/var/lib/prometheus 880 | networks: 881 | - backend 882 | ports: 883 | - 9090:9090 884 | node-exporter: 885 | image: linuxtips/node-exporter_alpine 886 | hostname: '{{.Node.ID}}' 887 | volumes: 888 | - /proc:/usr/proc 889 | - /sys:/usr/sys 890 | -/:/rootfs 891 | deploy: 892 | mode: global 893 | networks: 894 | - backend 895 | ports: 896 | - 9100:9093 897 | alertmanager: 898 | image: linuxtips/alertmanager_alpine 899 | volumes: 900 | - ./conf/alertmanager/:/etc/alertmanager/ 901 | networks: 902 | - backend 903 | ports: 904 | - 9093:9093 905 | cadvisor: 906 | image: google/cadvisor 907 | hostname: '{{.Node.ID}}' 908 | volumes: 909 | - /:/rootfs:ro 910 | - /var/run:/var/run:rw 911 | - /sys:/sys:ro 912 | - /var/lib/docker/:/var/lib/docker:ro 913 | - /var/run/docker.sock:/var/run/docker.sock:ro 914 | networks: 915 | - backend 916 | deploy: 917 | mode: global 918 | ports: 919 | - 8080:8080 920 | grafana: 921 | image: nopp/grafana_alpine 922 | depends_on: 923 | - prometheus 924 | volumes: 925 | - ./conf/grafana/grafana.db:/grafana/data/grafana.db 926 | env_file: 927 | - grafana.config 928 | networks: 929 | - backend 930 | - frontend 931 | ports: 932 | - 3000:3000 933 | networks: 934 | backend: 935 | frontend: 936 | volumes: 937 | prometheus_data: 938 | grafana_data: 939 | ``` 940 | 941 | ``` 942 | docker stack deploy -c docker-compose.yml giropops 943 | docker service ls 944 | docker stack ls 945 | 946 | Prometheus: 947 | http://SEU_IP:9090 948 | 949 | AlertManager: 950 | http://SEU_IP:9093 951 | 952 | Grafana: 953 | http://SEU_IP:3000 954 | 955 | Node_Exporter: 956 | http://SEU_IP:9100 957 | 958 | Rocket.Chat: 959 | http://SEU_IP:3080 960 | 961 | cAdivisor: 962 | http://SEU_IP:8080 963 | 964 | 965 | docker stack rm giropops 966 | ``` 967 | 968 | Lembrando, para conhecer mais sobre o giropops-monitoring acesse o repositório no GitHub e assista a série de vídeos em que o Jefferson da LinuxTips conta como montou essa solução: 969 | GitHub: https://github.com/badtuxx/giropops-monitoring 970 | Vídeos: https://www.youtube.com/playlist?list=PLf-O3X2-mxDls9uH8gyCQTnyXNMe10iml 971 | 972 | 973 | ## Traefik 974 | 975 | https://containo.us/traefik/ 976 | https://docs.traefik.io/ 977 | https://docs.containo.us/ 978 | https://community.containo.us/ 979 | 980 | - Maneira simples e rápida para fazer um Proxy Reverso 981 | - Traefik em alta disponiblidade precisa usar o Enterprise Edition 982 | 983 | Ambiente para teste: 984 | 3 host na AWS: 985 | 986 | Instalar o Docker nos 3 hosts 987 | ``` sh 988 | curl -FsSl https://get.docker.com | bash 989 | ``` 990 | 991 | Iniciar o cluster swarm em um dos hosts 992 | ``` sh 993 | docker swarm init 994 | ``` 995 | 996 | Adicionar os dois outros hosts no swarm 997 | ``` sh 998 | docker swarm joing --token TOKEN IP:PORTA 999 | ``` 1000 | 1001 | Criar uma rede no docker para expor publicamente os serviços do Cluster Swarm 1002 | ``` sh 1003 | docker network create --driver=overlay traefik-public 1004 | ``` 1005 | 1006 | Criar um arquivo "traefik_deploy.yaml" 1007 | ``` yaml 1008 | version: '3' 1009 | 1010 | services: 1011 | reverse-proxy: 1012 | image: traefik:v2.0.2 1013 | command: 1014 | - "--providers.docker.endpoint=unix:///var/run/docker.sock" 1015 | - "--providers.docker.swarmMode=true" 1016 | - "--providers.docker.exposedbydefault=false" 1017 | - "--providers.docker.network=traefik-public" 1018 | - "--entrypoints.web.address=:80" 1019 | ports: 1020 | - 80:80 1021 | volumes: 1022 | - /var/run/docker.sock:/var/run/docker.sock:ro 1023 | networks: 1024 | - traefik-public 1025 | deploy: 1026 | placement: 1027 | constraints: 1028 | - node.role == manager 1029 | 1030 | networks: 1031 | traefik-public: 1032 | external: true 1033 | ``` 1034 | 1035 | Deploy no Cluster Swarm 1036 | ``` sh 1037 | docker stack deploy traefik -c traefik_deploy.yaml 1038 | docker servicel logs traefik_reverse-proxy 1039 | ``` 1040 | 1041 | Yaml da aplicação 1042 | ``` yaml 1043 | version: '3' 1044 | services: 1045 | loja: 1046 | image: linuxtips/nginx-prometheus-exporter:1.0.0 1047 | networks: 1048 | - traefik-public 1049 | deploy: 1050 | labels: 1051 | - "traefik.enable=true" 1052 | - "traefik.http.routers.loja.rule=Host('loja.biqueiranerd.com.br')" 1053 | - "traefik.http.routers.loja.entrypoints=web" 1054 | - "traefik.http.services.loja.loadbalancer.server.port=80" 1055 | networks: 1056 | traefik-public: 1057 | external: true 1058 | ``` 1059 | 1060 | Deploy da Aplicação (app.yaml) 1061 | ``` sh 1062 | docker stack deploy loja -c app.yaml 1063 | ``` 1064 | -------------------------------------------------------------------------------- /composes/docker-compose-01.yaml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | services: 3 | web: 4 | image: nginx 5 | deploy: 6 | replicas: 5 7 | resources: 8 | limits: 9 | cpus: "0.1" 10 | memory: 50M 11 | restart_policy: 12 | condition: on-failure 13 | ports: 14 | - "8080:80" 15 | networks: 16 | - webserver 17 | networks: 18 | webserver: -------------------------------------------------------------------------------- /composes/docker-compose-02.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | db: 4 | image: mysql:5.7 5 | volumes: 6 | - db_data:/var/lib/mysql 7 | environment: 8 | MYSQL_ROOT_PASSWORD: somewordpress 9 | MYSQL_DATABASE: wordpress 10 | MYSQL_USER: wordpress 11 | MYSQL_PASSWORD: wordpress 12 | 13 | wordpress: 14 | depends_on: 15 | - db 16 | image: wordpress:latest 17 | ports: 18 | - "8080:80" 19 | environment: 20 | WORDPRESS_DB_HOST: db:3306 21 | WORDPRESS_DB_USER: wordpress 22 | WORDPRESS_DB_PASSWORD: wordpress 23 | 24 | volumes: 25 | db_data: 26 | -------------------------------------------------------------------------------- /composes/docker-compose-03.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | web: 4 | image: nginx 5 | deploy: 6 | placement: 7 | constraints: 8 | - node.labels.dc == UK 9 | replicas: 5 10 | resources: 11 | limits: 12 | cpus: "0.1" 13 | memory: 50M 14 | restart_policy: 15 | condition: on-failure 16 | ports: 17 | - "8080:80" 18 | networks: 19 | - webserver 20 | 21 | visualizer: 22 | image: dockersamples/visualizer:stable 23 | ports: 24 | - "8888:8080" 25 | volumes: 26 | - "/var/run/docker.sock:/var/run/docker.sock" 27 | deploy: 28 | placement: 29 | constraints: [node.role == manager] 30 | networks: 31 | - webserver 32 | 33 | networks: 34 | webserver: -------------------------------------------------------------------------------- /composes/docker-compose-04-original-aula.yaml: -------------------------------------------------------------------------------- 1 | 2 | version: "3" 3 | services: 4 | redis: 5 | image: redis:alpine 6 | ports: 7 | - "6379" 8 | networks: 9 | - frontend 10 | deploy: 11 | replicas: 2 12 | update_config: 13 | parallelism: 2 14 | delay: 10s 15 | restart_policy: 16 | condition: on-failure 17 | db: 18 | image: postgres:9.4 19 | volumes: 20 | - db-data:/var/lib/postgresql/data 21 | networks: 22 | - backend 23 | deploy: 24 | placement: 25 | constraints: [node.role == manager] 26 | vote: 27 | image: dockersamples/examplevotingapp_vote:before 28 | ports: 29 | - 5000:80 30 | networks: 31 | - frontend 32 | depends_on: 33 | - redis 34 | deploy: 35 | replicas: 2 36 | update_config: 37 | parallelism: 2 38 | restart_policy: 39 | condition: on-failure 40 | result: 41 | image: dockersamples/examplevotingapp_result:before 42 | ports: 43 | - 5001:80 44 | networks: 45 | - backend 46 | depends_on: 47 | - db 48 | deploy: 49 | replicas: 1 50 | update_config: 51 | parallelism: 2 52 | delay: 10s 53 | restart_policy: 54 | condition: on-failure 55 | worker: 56 | image: dockersamples/examplevotingapp_worker 57 | networks: 58 | - frontend 59 | - backend 60 | deploy: 61 | mode: replicated 62 | replicas: 1 63 | labels: [APP=VOTING] 64 | restart_policy: 65 | condition: on-failure 66 | delay: 10s 67 | max_attempts: 3 68 | window: 120s 69 | placement: 70 | constraints: [node.role == manager] 71 | visualizer: 72 | image: dockersamples/visualizer:stable 73 | ports: 74 | - "8080:8080" 75 | stop_grace_period: 1m30s 76 | volumes: 77 | - "/var/run/docker.sock:/var/run/docker.sock" 78 | deploy: 79 | placement: 80 | constraints: [node.role == manager] 81 | networks: 82 | frontend: 83 | backend: 84 | volumes: 85 | db-data: -------------------------------------------------------------------------------- /composes/docker-compose-04.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | services: 3 | 4 | redis: 5 | image: redis:alpine 6 | networks: 7 | - frontend 8 | deploy: 9 | replicas: 2 10 | update_config: 11 | parallelism: 2 12 | delay: 10s 13 | order: start-first 14 | rollback_config: 15 | parallelism: 1 16 | delay: 10s 17 | failure_action: continue 18 | monitor: 60s 19 | order: stop-first 20 | restart_policy: 21 | condition: on-failure 22 | db: 23 | image: postgres:9.4 24 | environment: 25 | POSTGRES_USER: "postgres" 26 | POSTGRES_PASSWORD: "postgres" 27 | volumes: 28 | - db-data:/var/lib/postgresql/data 29 | networks: 30 | - backend 31 | deploy: 32 | placement: 33 | constraints: [node.role == manager] 34 | vote: 35 | image: dockersamples/examplevotingapp_vote:before 36 | ports: 37 | - 5000:80 38 | networks: 39 | - frontend 40 | depends_on: 41 | - redis 42 | deploy: 43 | replicas: 2 44 | update_config: 45 | parallelism: 2 46 | restart_policy: 47 | condition: on-failure 48 | result: 49 | image: dockersamples/examplevotingapp_result:before 50 | ports: 51 | - 5001:80 52 | networks: 53 | - backend 54 | depends_on: 55 | - db 56 | deploy: 57 | replicas: 1 58 | update_config: 59 | parallelism: 1 60 | delay: 10s 61 | restart_policy: 62 | condition: on-failure 63 | 64 | worker: 65 | image: dockersamples/examplevotingapp_worker 66 | networks: 67 | - frontend 68 | - backend 69 | depends_on: 70 | - db 71 | - redis 72 | deploy: 73 | mode: replicated 74 | replicas: 1 75 | labels: [APP=VOTING] 76 | restart_policy: 77 | condition: on-failure 78 | delay: 10s 79 | max_attempts: 3 80 | window: 120s 81 | placement: 82 | constraints: [node.role == manager] 83 | 84 | visualizer: 85 | image: dockersamples/visualizer:stable 86 | ports: 87 | - "8080:8080" 88 | stop_grace_period: 1m30s 89 | volumes: 90 | - "/var/run/docker.sock:/var/run/docker.sock" 91 | deploy: 92 | placement: 93 | constraints: [node.role == manager] 94 | 95 | networks: 96 | frontend: 97 | backend: 98 | 99 | volumes: 100 | db-data: 101 | -------------------------------------------------------------------------------- /composes/docker-compose-05.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | services: 3 | prometheus: 4 | image: linuxtips/prometheus_alpine 5 | volumes: 6 | - ./conf/prometheus/:/etc/prometheus/ 7 | - prometheus_data:/var/lib/prometheus 8 | networks: 9 | - backend 10 | ports: 11 | - 9090:9090 12 | node-exporter: 13 | image: linuxtips/node-exporter_alpine 14 | hostname: '{{.Node.ID}}' 15 | volumes: 16 | - /proc:/usr/proc 17 | - /sys:/usr/sys 18 | -/:/rootfs 19 | deploy: 20 | mode: global 21 | networks: 22 | - backend 23 | ports: 24 | - 9100:9093 25 | alertmanager: 26 | image: linuxtips/alertmanager_alpine 27 | volumes: 28 | - ./conf/alertmanager/:/etc/alertmanager/ 29 | networks: 30 | - backend 31 | ports: 32 | - 9093:9093 33 | cadvisor: 34 | image: google/cadvisor 35 | hostname: '{{.Node.ID}}' 36 | volumes: 37 | - /:/rootfs:ro 38 | - /var/run:/var/run:rw 39 | - /sys:/sys:ro 40 | - /var/lib/docker/:/var/lib/docker:ro 41 | - /var/run/docker.sock:/var/run/docker.sock:ro 42 | networks: 43 | - backend 44 | deploy: 45 | mode: global 46 | ports: 47 | - 8080:8080 48 | grafana: 49 | image: nopp/grafana_alpine 50 | depends_on: 51 | - prometheus 52 | volumes: 53 | - ./conf/grafana/grafana.db:/grafana/data/grafana.db 54 | env_file: 55 | - grafana.config 56 | networks: 57 | - backend 58 | - frontend 59 | ports: 60 | - 3000:3000 61 | networks: 62 | backend: 63 | frontend: 64 | volumes: 65 | prometheus_data: 66 | grafana_data: -------------------------------------------------------------------------------- /traefik/loja-https.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | loja: 4 | image: linuxtips/nginx-prometheus-exporter:1.0.0 5 | networks: 6 | - traefik-public 7 | deploy: 8 | labels: 9 | - "traefik.enable=true" 10 | - "traefik.http.routers.loja.rule=Host(`loja.biqueiranerd.com.br`)" 11 | - "traefik.http.routers.loja.entrypoints=websecure" 12 | - "traefik.http.routers.loja.tls.certresolver=letsencryptresolver" 13 | - "traefik.http.services.loja.loadbalancer.server.port=80" 14 | networks: 15 | traefik-public: 16 | external: true -------------------------------------------------------------------------------- /traefik/loja.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | loja: 4 | image: linuxtips/nginx-prometheus-exporter:1.0.0 5 | networks: 6 | - traefik-public 7 | deploy: 8 | labels: 9 | - "traefik.enable=true" 10 | - "traefik.http.routers.loja.rule=Host('loja.biqueiranerd.com.br')" 11 | - "traefik.http.routers.loja.entrypoints=web" 12 | - "traefik.http.services.loja.loadbalancer.server.port=80" 13 | networks: 14 | traefik-public: 15 | external: true -------------------------------------------------------------------------------- /traefik/store.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | store: 4 | image: linuxtips/nginx-prometheus-exporter:1.0.0 5 | networks: 6 | - traefik-public 7 | deploy: 8 | labels: 9 | - "traefik.enable=true" 10 | - "traefik.http.routers.store.rule=Host('store.biqueiranerd.com.br')" 11 | - "traefik.http.routers.store.entrypoints=web" 12 | - "traefik.http.services.store.loadbalancer.server.port=80" 13 | networks: 14 | traefik-public: 15 | external: true -------------------------------------------------------------------------------- /traefik/traefik_deploy-https.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | reverse-proxy: 5 | image: traefik:v2.0.2 6 | labels: 7 | - "traefik.enable=true" 8 | - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)" 9 | - "traefik.http.routers.http-catchall.entrypoints=web" 10 | - "traefik.http.routers.http-catchall.middlewares=redirect-to-https@docker" 11 | - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" 12 | command: 13 | - "--providers.docker.endpoint=unix:///var/run/docker.sock" 14 | - "--providers.docker.swarmMode=true" 15 | - "--providers.docker.exposedbydefault=false" 16 | - "--providers.docker.network=traefik-public" 17 | - "--entrypoints.web.address=:80" 18 | - "--entrypoints.websecure.address=:443" 19 | - "--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true" 20 | - "--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web" 21 | - "--certificatesresolvers.letsencryptresolver.acme.email=jeferson@linuxtips.com.br" 22 | - "--certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json" 23 | - "--api.insecure" 24 | - "--api.dashboard=true" 25 | ports: 26 | - 80:80 27 | - 443:443 28 | - 8080:8080 29 | volumes: 30 | # So that Traefik can listen to the Docker events 31 | - /var/run/docker.sock:/var/run/docker.sock:ro 32 | - traefik-certificates:/letsencrypt 33 | networks: 34 | - traefik-public 35 | deploy: 36 | placement: 37 | constraints: 38 | - node.role == manager 39 | 40 | volumes: 41 | traefik-certificates: 42 | 43 | networks: 44 | traefik-public: 45 | external: true -------------------------------------------------------------------------------- /traefik/traefik_deploy.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | reverse-proxy: 5 | image: traefik:v2.0.2 6 | command: 7 | - "--providers.docker.endpoint=unix:///var/run/docker.sock" 8 | - "--providers.docker.swarmMode=true" 9 | - "--providers.docker.exposedbydefault=false" 10 | - "--providers.docker.network=traefik-public" 11 | - "--entrypoints.web.address=:80" 12 | ports: 13 | - 80:80 14 | volumes: 15 | - /var/run/docker.sock:/var/run/docker.sock:ro 16 | networks: 17 | - traefik-public 18 | deploy: 19 | placement: 20 | constraints: 21 | - node.role == manager 22 | 23 | networks: 24 | traefik-public: 25 | external: true --------------------------------------------------------------------------------