0:00:08.952,0:00:13.039 Um dos passos mais importantes quando[br]nós falamos da utilização de Docker 0:00:13.039,0:00:16.730 é justamente aprender a criar[br]o nosso próprio Docker, 0:00:16.730,0:00:19.720 ou pelo menos a nossa[br]própria imagem. 0:00:20.280,0:00:23.406 Para isso, nós vamos ter que utilizar[br]algumas ferramentas. 0:00:23.406,0:00:29.686 A primeira e provavelmente mais importante[br]nesse processo vai ser o Dockerfile. 0:00:29.686,0:00:34.925 Ele é basicamente um arquivo que vai permitir[br]que eu passe instruções para o Docker 0:00:34.925,0:00:37.656 de como ele deve[br]construir aquela imagem. 0:00:37.656,0:00:41.498 Antes de mais nada, eu vou precisar[br]pelo menos de algum código 0:00:41.498,0:00:45.238 para que eu consiga colocar[br]em desenvolvimento. 0:00:45.238,0:00:51.153 Para isso, eu peguei um códigozinho bem[br]simples de "hello, world" baseado em Node, 0:00:51.153,0:00:55.238 é basicamente uma página que tem[br]um campinho de preenchimento de busca 0:00:55.238,0:00:59.239 e um botãozinho, mas essa função[br]não tem nada programado, 0:00:59.239,0:01:02.540 é realmente só para nós[br]termos um código para utilizar. 0:01:02.540,0:01:06.359 Nesse caso, nós vamos[br]utilizar um código em Node 0:01:06.359,0:01:11.328 e, justamente por isso, eu preciso utilizar,[br]como base para a minha imagem, 0:01:11.328,0:01:15.383 uma imagem que já tenha um Node[br]pronto para eu poder utilizar. 0:01:15.383,0:01:18.114 Caso nós não achemos[br]uma imagem dessa forma, 0:01:18.114,0:01:21.732 nós podemos passar comandos[br]dentro de um container 0:01:21.732,0:01:25.805 para que ele faça todo o processo[br]de instalação daquele software 0:01:25.805,0:01:29.387 e disponibilize todo aquele[br]ambiente montado para nós. 0:01:29.387,0:01:34.137 Aqui dentro da minha tela, eu vou ter,[br]então, uma pasta chamada "app", 0:01:34.137,0:01:39.634 que eu criei dentro do meu desktop,[br]e nela eu vou ter alguns arquivos. 0:01:40.640,0:01:46.613 O "yarn.lock", o "package",[br]a pasta "src" e a pasta "spec" 0:01:46.613,0:01:51.054 são justamente conteúdos que eu[br]tenho dessa minha aplicação. 0:01:51.054,0:01:56.269 Se eu abro, por exemplo, aqui,[br]o "src", eu vou ter um "index.js", 0:01:56.269,0:02:00.836 que vai ser, justamente, o arquivo[br]inicial da minha aplicação. 0:02:02.272,0:02:06.141 Aqui nessa pasta, eu ainda tenho[br]o arquivo chamado Dockerfile. 0:02:06.141,0:02:09.172 Esse é o arquivo que vai[br]trazer todas as instruções 0:02:09.172,0:02:12.757 que o Docker precisa[br]para construir a nossa imagem. 0:02:13.316,0:02:15.892 Existem algumas características[br]muito importantes 0:02:15.892,0:02:17.921 que nós temos[br]que nos atentar nele, 0:02:17.921,0:02:23.243 a primeira delas é que esse[br]arquivo não tem extensão, 0:02:24.144,0:02:27.990 a segunda é que ele sempre[br]vai começar com D maiúsculo 0:02:27.990,0:02:30.769 e Dockerfile vai estar[br]escrito tudo junto. 0:02:30.769,0:02:34.461 Eu preciso justamente prestar[br]atenção em todos esses padrões 0:02:34.461,0:02:37.423 para que eu não impeça[br]o Docker de achar o arquivo 0:02:37.423,0:02:40.125 e, assim, começar o processo[br]de build da imagem. 0:02:40.125,0:02:45.251 Agora, como eu valido isso aqui[br]dentro dos meus arquivos? 0:02:45.251,0:02:49.549 Basta eu vir na aba de visualização[br]do Explorer no Windows 0:02:49.549,0:02:56.029 e marcar a opção "file name extensions"[br]ou mostrar extensões de arquivo. 0:02:56.029,0:03:00.023 Note que agora todos os meus[br]arquivos ganharam uma extensão, 0:03:00.023,0:03:02.168 menos o dockerfile. 0:03:02.168,0:03:07.812 Pode ser que, quando você criou o arquivo[br]utilizando, por exemplo, o bloco de notas, 0:03:07.812,0:03:11.942 ele tivesse mostrado[br]uma opção como txt. 0:03:11.942,0:03:16.526 Caso ele tenha aparecido como txt[br]no final, basta apertar a tecla F2 0:03:16.526,0:03:22.692 e renomear o arquivo, excluindo[br]o ".txt" e deixando apenas "dockerfile". 0:03:22.692,0:03:27.424 O Windows vai pedir que você confirme[br]que aquele arquivo não vai ter uma extensão, 0:03:27.424,0:03:30.833 basta confirmar e seguir[br]para as próximas etapas. 0:03:30.833,0:03:34.180 Quando nós abrimos o Dockerfile[br]dentro de um bloco de notas, 0:03:34.180,0:03:36.990 nós vamos ter uma estrutura[br]até bem simples. 0:03:36.990,0:03:40.977 A primeira coisa que nós vamos[br]ver é justamente um comentário 0:03:40.977,0:03:46.419 definindo qual tipo de sintaxe nós estamos[br]utilizando para construção desse arquivo. 0:03:46.419,0:03:49.364 Nesse caso, uma sintaxe de versão 1. 0:03:49.364,0:03:54.531 As linhas de comando que definem a sintaxe[br]estão lá na documentação do Docker. 0:03:54.531,0:03:59.303 Por hora, você pode simplesmente copiar[br]essa linha para todos os seus arquivos 0:03:59.303,0:04:02.417 e tudo vai correr sem[br]maiores problemas. 0:04:02.417,0:04:05.959 Agora, caso você se torne[br]um usuário avançado de Docker, 0:04:05.959,0:04:12.052 algumas funções só vão estar disponíveis[br]em versões específicas do Dockerfile, 0:04:12.052,0:04:16.880 então você vai ter que ficar atento[br]a qual tipo de Dockerfile utilizar 0:04:16.880,0:04:21.237 para poder criar exatamente[br]o container da forma que você precisa. 0:04:21.237,0:04:25.331 Logo em seguida, eu tenho[br]um comando chamado "FROM". 0:04:25.331,0:04:31.171 Esse comando serve para eu especificar[br]qual imagem de base que eu vou utilizar. 0:04:31.171,0:04:37.259 Nesse caso, uma imagem chamada[br]"node" na versão "12-alpine". 0:04:37.259,0:04:42.627 É justamente aqui, por exemplo, que caso eu[br]queira criar um container totalmente do zero 0:04:42.627,0:04:45.562 utilizando só um sistema[br]operacional de base, 0:04:45.562,0:04:49.519 eu vou conseguir especificar que eu[br]quero esse sistema operacional. 0:04:49.519,0:04:52.992 Se eu quisesse, por exemplo,[br]criar um servidor Apache do zero, 0:04:52.992,0:04:58.466 eu poderia fazer um FROM Ubuntu[br]e, nos comandos que se seguem, 0:04:58.466,0:05:02.198 fazer todo o passo a passo[br]de instalação do Apache. 0:05:02.198,0:05:08.140 Nesse caso, nós já estamos reaproveitando[br]parte da estrutura do Node que já está pronta 0:05:08.140,0:05:11.301 e, aí, eu só preciso rodar[br]alguns poucos comandos 0:05:11.301,0:05:14.495 e copiar os meus arquivos[br]para dentro do container. 0:05:14.495,0:05:19.203 Nosso próximo passo, então,[br]é rodar um "apk add" 0:05:19.203,0:05:24.515 para garantir que eu tenho[br]um python2, o compilador C 0:05:24.515,0:05:27.246 e o make dentro[br]da minha máquina. 0:05:27.777,0:05:33.423 O nosso próximo passo, então, vai[br]ser criar um diretório de trabalho, 0:05:33.423,0:05:35.747 nesse caso, chamado "app". 0:05:35.747,0:05:40.236 Esse diretório de trabalho vai[br]basicamente informar para o container 0:05:40.236,0:05:43.219 qual pasta ele deve utilizar[br]para poder trabalhar. 0:05:43.219,0:05:49.232 Note que todo o nosso conteúdo do arquivo[br]está dentro de uma pasta chamada "app", 0:05:49.232,0:05:52.665 dessa forma, eu vou conseguir[br]navegar para dentro dessa pasta, 0:05:52.665,0:05:55.179 utilizar ela como pasta padrão 0:05:55.179,0:05:58.766 e, a partir de então, começar[br]a executar os demais comandos. 0:05:58.766,0:06:04.387 O comando "COPY" serve justamente para eu[br]copiar arquivos para dentro do container. 0:06:04.387,0:06:08.988 Ele vai copiar todos os arquivos[br]da pasta que eu me encontro, 0:06:08.988,0:06:14.627 por isso o ponto, para a pasta que eu[br]estarei utilizando dentro do container, 0:06:14.627,0:06:17.561 por isso, eu vou utilizar[br]"." novamente. 0:06:17.561,0:06:19.812 E aqui vai vir um ponto[br]bem interessante: 0:06:19.812,0:06:23.466 a cópia do arquivo não é[br]exatamente uma boa prática, 0:06:23.466,0:06:29.468 como nós vimos, se nós não soubermos utilizar[br]o armazenamento de arquivos de forma correta, 0:06:29.468,0:06:32.826 isso vai atrapalhar o bom[br]funcionamento de um container. 0:06:32.826,0:06:37.397 A questão, nesse caso, é que, como eu[br]estou criando um container novo, 0:06:37.397,0:06:42.192 eu preciso passar todos os códigos[br]que vão servir de base para ele, 0:06:42.192,0:06:47.010 então eu posso copiar esses arquivos[br]sem a menor dor de cabeça, 0:06:47.010,0:06:50.476 já que eles vão passar[br]a ser parte fundamental 0:06:50.476,0:06:52.590 de todo o container[br]que eu estou criando. 0:06:52.590,0:06:54.267 O passo seguinte, então, 0:06:54.267,0:07:00.560 é garantir que esse meu sistema esteja[br]utilizando um ambiente de produção. 0:07:00.560,0:07:03.298 Para isso, eu posso[br]executar um "yarn install". 0:07:03.298,0:07:06.506 Esse comando é um comando[br]que pertence ao ambiente Node 0:07:06.506,0:07:10.250 e serve basicamente para instalar[br]todos os pacotes necessários 0:07:10.250,0:07:13.622 e preparar o ambiente para a execução[br]daquela minha aplicação. 0:07:13.622,0:07:17.363 Em seguida, eu vou[br]utilizar o "CMD", 0:07:17.363,0:07:22.822 que é basicamente uma forma de criar[br]linhas de comando dentro do container. 0:07:22.822,0:07:27.267 Nesse caso, eu estou chamando[br]o comando Node e informando para ele 0:07:27.267,0:07:34.971 que o arquivo de origem da minha aplicação[br]está dentro da pasta "src/index". 0:07:34.971,0:07:38.591 E esse é exatamente o caminho[br]que nós checamos agora há pouco 0:07:38.591,0:07:41.601 de onde estava o index[br]da minha aplicação. 0:07:41.601,0:07:45.575 Então, a partir do momento que eu copiei[br]esses dados para dentro do container, 0:07:45.575,0:07:48.668 eu, agora, mostrei para o Node[br]como executá-lo. 0:07:48.668,0:07:53.037 Por fim, eu estou fazendo[br]um "EXPOSE" da porta 3000. 0:07:53.037,0:07:56.109 Esse comando serve[br]justamente para eu informar 0:07:56.109,0:07:59.297 que eu vou ter que acessar[br]uma porta desse container, 0:07:59.297,0:08:03.586 dessa forma, na hora que eu for criar[br]o container para colocá-lo em execução, 0:08:03.586,0:08:07.699 o Docker vai saber que eu posso[br]ter uma conexão de rede ali 0:08:07.699,0:08:10.289 e vai permitir a criação[br]dessa interação. 0:08:10.289,0:08:15.328 Outro detalhe muito importante é que eu[br]tenho duas formas de executar comandos. 0:08:15.328,0:08:18.931 A primeira é a partir[br]do comando "run". 0:08:18.931,0:08:25.004 O run vai simplesmente executar aquela[br]linha de comando dentro do meu container 0:08:25.004,0:08:28.875 na hora que eu estiver fazendo[br]toda a parte de construção dele. 0:08:28.875,0:08:33.012 Enquanto isso, CMD vão ser[br]comandos que vão ser executados 0:08:33.012,0:08:35.515 posteriormente à criação[br]do meu container. 0:08:35.515,0:08:41.521 Dessa forma, quando eu crio lá o CMD chamando[br]um comando Node e passando o index, 0:08:41.521,0:08:46.759 toda vez que esse container for colocado[br]em execução, esse comando vai ser chamado. 0:08:46.759,0:08:49.996 Agora que todo esse[br]processo está finalizado, 0:08:49.996,0:08:54.446 eu posso utilizar esses arquivos[br]para construir o meu container. 0:08:54.446,0:09:00.674 Utilizando, então, o prompt de comando, eu[br]vou poder recorrer a uma função chamada 0:09:01.407,0:09:02.975 "docker build". 0:09:02.975,0:09:05.106 Esse comando é[br]um comando bem simples 0:09:05.106,0:09:08.281 e não tem muita coisa que nós[br]temos que configurar nele. 0:09:08.281,0:09:12.852 Nesse caso, por exemplo, nós[br]só vamos nomear a imagem 0:09:12.852,0:09:16.789 e, em seguida, informar o endereço,[br]para o Dockerfile, que vai ser utilizado. 0:09:16.789,0:09:21.904 Para isso, eu vou informar o "-t"[br]seguido do nome da imagem. 0:09:23.629,0:09:29.268 Nesse caso, eu vou chamar ela de "ola"[br]e, em seguida, eu vou informar um ponto. 0:09:29.268,0:09:35.509 A função desse ponto é informar que eu já[br]estou na pasta onde eu tenho o Dockerfile, 0:09:35.509,0:09:39.230 caso eu não esteja nessa pasta,[br]ao invés de informar o ponto, 0:09:39.230,0:09:43.649 eu vou ter que informar todo[br]o endereçamento de pasta 0:09:43.649,0:09:48.154 e esse endereçamento vai variar[br]entre sistemas operacionais. 0:09:48.154,0:09:52.627 A forma mais fácil, então, é utilizar[br]os comandos de navegação de terminal, 0:09:52.627,0:09:56.429 como CD, para poder[br]navegar pelos diretórios 0:09:56.429,0:09:59.365 e, chegando no diretório[br]que tem o Dockerfile, 0:09:59.365,0:10:03.903 simplesmente executar o "docker build"[br]com o ponto no final. 0:10:03.903,0:10:08.975 Executando, então, o processo de build,[br]várias coisas vão ser executadas. 0:10:08.975,0:10:12.445 A primeira delas é todo[br]o download de imagens, 0:10:12.445,0:10:17.964 seguido da construção das aplicações,[br]e todo o teste de funcionamento 0:10:17.964,0:10:21.253 para ver se o comando inicial[br]vai ser executado com sucesso. 0:10:21.253,0:10:27.960 Caso você possua alguma falha nesse processo,[br]você pode recorrer ao "docker logs". 0:10:27.960,0:10:32.031 Esse é um comando que nos permite[br]checar logs no ambiente Docker. 0:10:32.031,0:10:36.559 Inclusive é legal que você pode utilizar[br]ele para checar logs individualmente 0:10:36.559,0:10:37.859 de cada container. 0:10:37.859,0:10:40.573 Com o processo de build concluído, 0:10:40.573,0:10:45.411 o Docker sempre vai perguntar se você não[br]quer fazer um scan de vulnerabilidades. 0:10:45.411,0:10:47.880 Nesse caso, não[br]vai ser preciso. 0:10:47.880,0:10:52.885 A única coisa que nos falta agora é colocar,[br]justamente, esse container em execução. 0:10:52.885,0:10:56.288 Para isso, nós vamos recorrer[br]ao comando "docker run", 0:10:56.288,0:11:00.459 só que, dessa vez, eu vou ter que passar[br]alguns parâmetros de execução para ele. 0:11:00.459,0:11:03.396 O primeiro parâmetro vai[br]ser justamente para garantir 0:11:03.396,0:11:07.133 que essa imagem vai ficar[br]em execução o tempo todo. 0:11:07.133,0:11:09.769 Para isso, vou utilizar o "-d". 0:11:09.769,0:11:17.443 Enquanto o segundo parâmetro, "-p", vai ser[br]para informar o apontamento de portas de rede, 0:11:17.443,0:11:21.706 dessa forma, todo o conteúdo da minha[br]aplicação vai ficar disponível para acesso. 0:11:21.706,0:11:25.496 Para executar, então, o container[br]que nós acabamos de criar, 0:11:25.496,0:11:27.591 eu vou fazer um "docker run", 0:11:31.665,0:11:32.615 "-d", 0:11:33.392,0:11:36.429 "-p", para informar a porta, 0:11:36.429,0:11:44.336 e, nesse caso, eu expus a porta 3000,[br]então eu vou utilizar "3000 : 3000". 0:11:44.336,0:11:50.209 A razão de eu ter que repetir o 3000 duas vezes[br]é porque eu estou falando de duas portas. 0:11:50.209,0:11:56.062 A primeira é a porta na minha máquina base[br]e a segunda é a porta do meu container, 0:11:56.857,0:12:02.254 Se eu especifico, por exemplo, a primeira[br]porta, que é a da máquina base, como 80, 0:12:02.254,0:12:08.094 ela vai apontar um acesso realizado[br]na porta 80 do meu servidor base 0:12:08.094,0:12:11.355 para a porta 3000[br]do meu container. 0:12:12.198,0:12:15.434 Isso é algo que nós temos[br]que prestar bastante atenção, 0:12:15.434,0:12:17.703 às vezes, quando nós[br]vamos criar uma aplicação, 0:12:17.703,0:12:22.374 nós temos vários containers[br]que têm exposta a porta 80 0:12:22.374,0:12:26.979 e eu posso apontar diversas portas[br]para dentro desses containers, 0:12:26.979,0:12:30.783 utilizando numerações[br]diferentes no meu host base. 0:12:30.783,0:12:36.630 O próximo passo, então, é informar o nome[br]da minha imagem, nesse caso, "ola". 0:12:36.630,0:12:42.361 Colocando a imagem em execução, eu[br]vou receber o código de validação dela 0:12:42.361,0:12:45.364 e, se eu executar um "docker ps", 0:12:45.364,0:12:49.168 note que essa minha imagem[br]já se encontra em execução 0:12:49.168,0:12:55.741 e me informando que a porta 3000 está[br]apontando para a porta 3000 do container. 0:12:55.741,0:12:59.378 O último passo, então,[br]é abrir o navegador web 0:12:59.378,0:13:04.083 e acessar, justamente, a nossa[br]máquina na porta 3000. 0:13:04.083,0:13:11.056 O IP que eu informei aqui 127.0.0.1[br]é o que se chama de local host, 0:13:11.056,0:13:13.759 ele representa a própria[br]máquina na rede. 0:13:13.759,0:13:19.832 Outra forma que você teria era escrever[br]por extenso "local host: 3000". 0:13:19.832,0:13:25.404 Qualquer uma das duas formas já faria com que[br]toda a interface funcionasse normalmente. 0:13:25.404,0:13:28.507 No nosso caso, após[br]acessar a aplicação, 0:13:28.507,0:13:33.312 todo o código que nós criamos e compilamos[br]já está aqui disponível para uso 0:13:33.312,0:13:39.852 e eu consigo, por exemplo, ir adicionando[br]itens dentro dessa minha aplicação. 0:13:39.852,0:13:42.688 Esse é um exemplo[br]de uma aplicação bem simples, 0:13:42.688,0:13:46.643 só para nós entendermos como é que eu[br]começo a construir todo esse ambiente. 0:13:47.359,0:13:50.696 A partir de agora, você pode[br]utilizar esses conhecimentos 0:13:50.696,0:13:54.300 para começar a containerizar[br]as suas próprias aplicações 0:13:54.300,0:13:58.304 e, com isso, entender um pouco mais[br]como todo esse ecossistema funciona.