Docker avançado

Objetivo do módulo

Hero with bird

Ao final do módulo você irá aprender:

  • Utilizar um Container Registry
  • Criar e executar uma imagem Docker
  • Implementar técnicas de performance na criação de uma imagem
  • Executar multiplos containers com Docker Compose

Aplicação prática

Agora vamos utilizar uma aplicação de exemplo para por em prática os conhecimentos necessários para utilização do docker.

O nosso projeto é uma aplicação básica que mostrará apenas uma lista de invetários parecida com aquelas que encontramos em jogos.

Tela da aplciação

Importante

Lembrando que a aplicação a parte de codificação já está pronta, não é o foco do nosso curso de Docker aprender a programar nos frameworks: Angular, node e etc.

Estrutura do sistema do sistema

Repositório inicial do projeto

O primeiro passo para iniciarmos será fazer um checkout do nossso projeto no repositório:

Repositório do projeto - Parte 1

Ou usar o Link para download.

Criando a imagem do Backend

FROM node:10
ARG NPM_ENV=production
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install && npm i sequelize-cli -g
COPY . .
EXPOSE 3000
CMD ["npm", "start" ]

Publicando a imagem do Backend

O primeiro passo é fazer o processo de autenticação

docker login

Ao executar o comando docker login, as credenciais serão armazenadas no host para futuras operações.

O próximo passo fazer o build da imagem:

docker build . -t <NOME_DA_CONTA_DOCKERHUB>/codeadventure-backend:0.1.0

Publicar a imagem:

docker push <NOME_DA_CONTA_DOCKERHUB>/codeadventure-backend:0.1.0

Entendo as Layers

Uma imagem docker é constituida por várias camadas (Layers) que correspodem a instruções do Dockerfile, como por exemplo RUN, ADD, COPY, CMD e etc.

Para escrever um Dockerfile realmente eficiente e com um tamanho reduzido, é importante otimizar os scripts utilizados, garantir que cada camada possua os artefatos necessários da camada anterior.

Criando a imagem do Frontend

O Angular no modo desenvolvimento pode ser criado da seguinte forma:

FROM node:10
ARG NPM_ENV=production
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 4200
CMD [ "ng", "serve" ]

No ambiente de produção não será necessário utilizar o node, por este motivo vamos trabalhar o nosso Dockerfile da seguinte forma:

FROM node:10 as builder
ARG NPM_ENV=prod
WORKDIR /usr/src/app
COPY . .
RUN npm install -g @angular/cli && npm install
RUN ng build --${NPM_ENV}
FROM nginx:1.15.5
COPY --from=builder /usr/src/app/dist/frontend/ /usr/share/nginx/html
EXPOSE 80

É importante fazermos o Multi Stage Build com o recurso COPY --from=, dessa forma conseguirmos uma redução drástica do tamanho da nossa imagem conforme podemos ver na imagem a seguir.

Publicando a imagem do Frontend

Gerar o build da imagem:

docker build . -t <NOME_DA_CONTA_DOCKERHUB>/codeadventure-frontend:0.1.0

Publicar a imagem:

docker push <NOME_DA_CONTA_DOCKERHUB>/codeadventure-frontend:0.1.0

Execurando o projeto

Criar a network:

docker network create internal

Executar o container de banco de dados:

docker run -d -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=codeadventure --name=code_database -p 3306:3306 --network internal mysql:8

Executar o container do frontend:

docker run -d --network internal --name=code_frontend -p 80:80 thecodeadventure/codeadventure-frontend:0.1.0

caso a porta 80 esteja ocupada substituir no comando acima a configuração das portas por -p 8080:80

Executar o container do backend:

docker run -d --network internal -e NODE_ENV=production --name=code_backend -p 3000:3000 <NOME_DA_CONTA_DOCKERHUB>/codeadventure-backend:0.1.0

Migrar e popular o banco de dados:

docker exec -it code_backend /bin/bash -c "sequelize db:migrate && sequelize db:seed:all"

Docker Compose

Conclusão

Repositório do projeto - Projeto final