Um dos passos mais importantes quando nós falamos da utilização de Docker é justamente aprender a criar o nosso próprio Docker, ou pelo menos a nossa própria imagem. Para isso, nós vamos ter que utilizar algumas ferramentas. A primeira e provavelmente mais importante nesse processo vai ser o Dockerfile. Ele é basicamente um arquivo que vai permitir que eu passe instruções para o Docker de como ele deve construir aquela imagem. Antes de mais nada, eu vou precisar pelo menos de algum código para que eu consiga colocar em desenvolvimento. Para isso, eu peguei um códigozinho bem simples de "hello, world" baseado em Node, é basicamente uma página que tem um campinho de preenchimento de busca e um botãozinho, mas essa função não tem nada programado, é realmente só para nós termos um código para utilizar. Nesse caso, nós vamos utilizar um código em Node e, justamente por isso, eu preciso utilizar, como base para a minha imagem, uma imagem que já tenha um Node pronto para eu poder utilizar. Caso nós não achemos uma imagem dessa forma, nós podemos passar comandos dentro de um container para que ele faça todo o processo de instalação daquele software e disponibilize todo aquele ambiente montado para nós. Aqui dentro da minha tela, eu vou ter, então, uma pasta chamada "app", que eu criei dentro do meu desktop, e nela eu vou ter alguns arquivos. O "yarn.lock", o "package", a pasta "src" e a pasta "spec" são justamente conteúdos que eu tenho dessa minha aplicação. Se eu abro, por exemplo aqui o "src", eu vou ter um "index.js", que vai ser, justamente, o arquivo inicial da minha aplicação. Aqui nessa pasta, eu ainda tenho o arquivo chamado Dockerfile. Esse é o arquivo que vai trazer todas as instruções que o Docker precisa para construir a nossa imagem. Existem algumas características muito importantes que nós temos que nos atentar nele, a primeira delas é que esse arquivo não tem extensão, a segunda é que ele sempre vai começar com D maiúsculo e Dockerfile vai estar escrito tudo junto. Eu preciso justamente prestar atenção em todos esses padrões para que eu não impeça o Docker de achar o arquivo e, assim, começar o processo de build da imagem. Agora, como que eu valido isso aqui dentro dos meus arquivos? Basta eu vir na aba de visualização do Explorer no Windows e marcar a opção "file name extensions" ou mostrar extensões de arquivo. Note que agora todos os meus arquivos ganharam uma extensão, menos no dockerfile. Pode ser que quando você criou o arquivo utilizando, por exemplo, o bloco de notas, ele tivesse mostrado uma opção como txt. Caso ele tenha aparecido como txt no final, basta apertar a tecla F2 e renomear o arquivo excluindo ".txt" e deixando apenas "dockerfile". O Windows vai pedir que você confirme que aquele arquivo não vai ter uma extensão, basta confirmar e seguir para as próximas etapas. Quando nós abrimos o Dockerfile dentro de um bloco de notas, nós vamos ter uma estrutura até bem simples. A primeira coisa que nós vamos ver é justamente um comentário definindo qual tipo de sintaxe nós estamos utilizando para construção desse arquivo. Nesse caso, uma sintaxe de versão 1. As linhas de comando que definem a sintaxe estão lá na documentação do Docker. Por hora, você pode simplesmente copiar essa linha para todos os seus arquivos e tudo vai correr sem maiores problemas. Agora, caso você se torne um usuário avançado de Docker, algumas funções só vão estar disponíveis em versões específicas do Dockerfile, então você vai ter que ficar atento a qual tipo de Dockerfile utilizar para poder criar exatamente o container da forma que você precisa. Logo em seguida, eu tenho um comando chamado "FROM". Esse comando serve para eu especificar qual imagem de base que eu vou utilizar. Nesse caso, uma imagem chamada "node" na versão "12-alpine". É justamente aqui, por exemplo, que caso eu queira criar um container totalmente do zero utilizando só um sistema operacional de base, eu vou conseguir especificar que eu quero esse sistema operacional. Se eu quisesse, por exemplo, criar um servidor Apache do zero, eu poderia fazer um FROM Ubuntu e, nos comandos que se seguem, fazer todo o passo a passo de instalação do Apache. Nesse caso, nós já estamos reaproveitando parte da estrutura do Node que já está pronta e, aí, eu só preciso rodar alguns poucos comandos e copiar os meus arquivos para dentro do container. Nosso próximo passo, então, é rodar um "apk add" para garantir que eu tenho um python2, o compilador C e o make dentro da minha máquina. Nosso próximo passo, então, vai ser criar um diretório de trabalho, nesse caso, chamado "app". Esse diretório de trabalho vai basicamente informar para o container qual pasta ele deve utilizar para poder trabalhar. Note que todo o nosso conteúdo do arquivo está dentro de uma pasta chamada "app", dessa forma, eu vou conseguir navegar para dentro dessa pasta, utilizar ela como pasta padrão e, a partir de então, começar a executar os demais comandos. O comando "COPY" serve justamente para eu copiar arquivos para dentro do container. Ele vai copiar todos os arquivos da pasta que eu me encontro, por isso o ponto, para a pasta que eu estarei utilizando dentro do container, por isso, eu vou utilizar "." novamente. E aqui vai vir um ponto bem interessante: a cópia do arquivo não é exatamente uma boa prática, como nós vimos, se nós não soubermos utilizar o armazenamento de arquivos de forma correta, isso vai atrapalhar o bom funcionamento de um container. A questão, nesse caso, é que, como eu estou criando um container novo, eu preciso passar a todos os códigos que vão servir de base para ele. Então eu posso copiar esses arquivos sem a menor dor de cabeça, já que eles vão passar a ser parte fundamental de todo o container que eu estou criando. O passo seguinte, então, é garantir que esse meu sistema esteja utilizando o ambiente de produção. Para isso, eu posso executar um Warning Stall. Esse comando é um comando que pertence ao ambiente novo e serve basicamente para instalar todos os pacotes necessários e preparar o ambiente para a execução daquela minha aplicação. Em seguida, eu vou utilizar o C MD, que é basicamente uma forma de criar linhas de comando dentro do container. Nesse caso, eu estou chamando o comando node e informando para ele que o arquivo de origem da minha aplicação está dentro da pasta SCR index. E esse é exatamente o caminho que a gente checou agora a pouco de onde estava o index da minha aplicação. Então, a partir do momento que eu copiei esses dados para dentro do container, eu agora mostrei para o novo de como executá lo. Por fim, eu estou fazendo um ex pouso da porta 3000. Esse comando serve justamente para eu informar que eu vou ter que acessar uma porta desse conta e dessa forma, na hora que eu for criar o container para colocá lo em execução, o Docker vai saber que eu posso ter uma conexão de rede ali e vai permitir a criação dessa interação. Outro detalhe muito importante é que eu tenho duas formas de executar comandos. O primeiro é a partir do comando run. O run vai simplesmente executar aquela linha de comando dentro do meu container. Na hora que eu estiver fazendo toda a parte de construção dele. Enquanto isso, sem MD, vão ser comandos que vão ser executados posteriores à criação do meu container. Dessa forma, quando eu crio lá o C. MD chamando um comando novo e passando o index, toda vez que esse container for colocado em execução, esse comando vai ser chamado. Agora que todo esse processo está finalizado, eu posso utilizar esses arquivos para construir o meu container, utilizando então o prompt de comando. Eu vou poder recorrer a uma função chamada Docker build. Esse comando é um comando bem simples e não tem muita coisa que a gente deve configurar nele. Nesse caso, por exemplo, a gente só vai nomear a imagem e em seguida informar o endereço do Dockerfile que vai ser utilizado. Para isso eu vou informar o menos ter seguido do nome da imagem, nesse caso vou chamar ela de Olá e em seguida eu vou informar um ponto. A função desse ponto é para informar que eu já estou na pasta aonde eu tenho o Dockerfile, caso não esteja nessa pasta, ao invés de informar o ponto eu vou ter que informar todo o endereçamento de pasta e esse endereçamento vai variar entre sistemas operacionais. A forma mais fácil então é utilizar os comandos de navegação de terminal como CD para poder navegar pelos diretórios e chegando no diretório que tem o Dockerfile ou simplesmente executar o Docker build com o ponto no final. Executando então o processo de build, várias coisas vão ser executadas. A primeira delas é todo download de imagens, seguido da construção das aplicações e todo o teste de funcionamento para ver se o comando inicial vai ser executado com sucesso. Caso você possua alguma falha nesse processo, você pode recorrer ao Docker Logs. Esse é um comando que permite a gente checar logo o ambiente Docker. Inclusive é legal que você pode utilizar ele para checar logs individualmente de cada contêiner com o processo de build concluído. O Docker sempre vai perguntar se você não quer fazer um scan de vulnerabilidades. Nesse caso, não vai ser preciso. A única coisa que nos falta agora é colocar justamente esse container em execução. Para isso a gente vai recorrer ao comando docker run. Só que dessa vez eu vou ter que passar alguns parâmetros de execução para ele. O primeiro parâmetro vai ser justamente para garantir que essa imagem vai ficar em execução o tempo todo. Para isso, vou utilizar ao menos o D, enquanto o segundo parâmetro menos p, vai ser para informar o apontamento de portas de rede. Dessa forma, todo o conteúdo da minha aplicação vai ficar disponível para acesso para executar então o container que a gente acabou de criar, eu vou fazer um Docker run em menos de menos P para informar a porta e nesse caso eu expus a porta 3000. Então vou utilizar 3002 pontos, 3000. A razão de eu ter que repetir O31000 duas vezes é porque eu estou falando de duas portas. A primeira é a porta na minha máquina base e a segunda é a porta do meu container, que específico por exemplo, a primeira porta, que é a da máquina base, como 80. Ela vai apontar um acesso realizado na porta 80 do meu servidor base para a porta 3000 do meu container. Isso é algo que a gente tem que prestar bastante atenção. Às vezes, quando a gente vai criar uma aplicação, a gente tem vários containers que tem expostas a porta 80 e eu posso apontar diversas portas para dentro desses containers, utilizando numerações diferentes no meu rosto base. O próximo passo então é informar o nome da minha imagem, nesse caso o LA colocando a imagem em execução eu vou receber o código de validação dela e se eu executar um Docker PRS? Note que essa minha imagem já se encontra em execução e me informando que a porta 3000 está apontando para a porta 3000 do contêiner. O último passo então, é abrir o navegador web e acessar justamente a nossa máquina na porta 3000. O IP que eu informei aqui 127,0 ponto zero ponto um é o que se chama de local Rust. Ele representa a própria máquina na rede. Outra forma que você teria era escrever por extenso local rows de 2,3000. Qualquer uma das duas formas já faria com que toda a interface funcionasse normalmente. No nosso caso, após acessar a aplicação, todo o código que a gente criou e compilou já está aqui disponível para uso e eu consigo, por exemplo, ir adicionando itens dentro dessa minha aplicação. Esse é um exemplo de uma aplicação bem simples, só pra gente entender como é que eu começo a construir todo esse ambiente. A partir de agora, você pode utilizar esses conhecimentos para começar a renderizar as suas próprias aplicações e com isso entender um pouco mais de como todo esse ecossistema funciona.