Dockerizando uma aplicação Node e Mongodb
Tags: node, mongodb, docker
Published: 2021-06-30 19:56:58

E aí gurizada, tudo tranquilo? Muito se fala em _container_, _docker_, aplicação escalável e é por esses e outros motivos que eu resolvi demonstrar como poderíamos criar uma aplicação simples usando um ambiente em container com node e mongodb.

A ideia aqui é mostrar os **princípios do docker** de forma muito breve trazendo um pouquinho de clareza na hora de construir uma aplicação seja ela na linguagem que for.

Ao final desse tutorial, vamos conseguir fazer um CRUD sem ter "nada instalado na nossa máquina", único requisito que precisamos é ter o docker instalado no computador. 

Instruções de instalação podem ser encontradas [aqui](https://docs.docker.com/engine/install/)

É preciso instalar também o _docker-compose_.

Alguns pontos extremamente importantes:

- Não vamos falar sobre arquitetura de projetos. "Ah, mas tua aplicação tem um index e rotas e tudo nele". O objetivo é apenas mostrar o **DOCKER** em ação.
- Não vamos abordar como o Node funciona.
- Não vamos falar sobre segurança e boas práticas.
- Não vamos falar sobre Docker detalhadamente, como funciona, ou detalhes mais aprofundados do docker-compose.

O projeto pode ser encontrado na minha página do [github](https://github.com/pazfelipe/docker-node-mongo)

Dito isso, bora pra prática!!!

## Docker
O Docker é um cara que geralmente roda um Linux minimalista apenas para criar a imagem do que você precisa, ou seja, se você quiser rodar um banco MySQL, a imagem do MySQL vai conter o mínimo, do mínimo, do mínimo ... para poder rodar o banco. Diferente de uma VM onde vai precisar instalar um sistema operacional inteiro para poder rodar o banco. Mas como dito alhures, nosso intento aqui não é esplanar o Docker, deixamos para outra hora isso.

Para que essa mágica aconteça, temos alguns comandos do Docker que vão brilhar no nosso terminal. 

No nosso exemplo, vamos baixar uma imagem do mysql e executar ela:

```shell
docker run -d --name mysql_container -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=True mysql
```

e voilà, temos um banco mysql novinho em folha rodando na nossa máquina. Basicamente estamos falando o seguinte:

`docker run -d` docker, rode em background
`--name mysql_container` alguma coisa com o nome de mysql_container
`-p 3306:3306` onde que a minha porta 3306 vai ser pareada com a porta 3306 desse alguma coisa que  você vai rodar em background
`-e MYSQL_ALLOW_EMPTY_PASSWORD=True` e você também precisa criar essa variável de ambiente pro alguma coisa
`mysql` e esse alguma coisa é a imagem que vai ser baixada e executada, no caso, o mysql.

> MYSQL_ALLOW_EMPTY_PASSWORD - variável de ambiente do mysql. Outra variáveis do MySQL que podem ser usadas também para docker podem ser encontradas [aqui](https://hub.docker.com/_/mysql)

Se você usar um _mysql workbench_, _dbeaver_ ou outro client, vai ser possível conectar no mysql rodando na porta 3306, já que a máquina host está pareando a porta 3306 da imagem que está sendo mantida pelo docker.

Mas esse foi um exemplo super básico, de apenas um serviço. Aplicações profissionais podem ter vários containers se interligando e imagina rodar comandos para cada um desses containers. Diante disso, surgiu o docker-compose, que nada mais é um cara que vai "ler" um arquivo yaml e rodar os comandos que estiverem nele.

Então, se fôssemos converter os comandos do terminal para um arquivo chamado _docker-compose.yaml_, ficaria assim:

```yaml
version: 3.8

services:
  mysql_service:
    image: mysql
    container_name: mysql_container
    ports:
      - "3306:3306"
    environment:
      - "MYSQL_ALLOW_EMPTY_PASSWORD=True"
```

e depois, basta rodar 
```shell
docker-compose up -d
```

se tivéssemos mais de um arquivo `yml`, teríamos de informar para o docker-compose qual arquivo queremos executar. Por exemplo, dentro do diretório _exemplo_ temos dois arquivos:
_docker-compose-um.yml_ e _outro_arquivo.yml_.

Queremos executar o _outro_arquivo.yml_ em background, ou seja, não vamos ver os logs que vão aparecer no terminal enquanto a imagem estiver sendo constrúida.

Para isso, digitamos:

```shell
docker-compose -f outro_arquivo.yml -d
```
E pronto, os comandos que estiverem dentro desse arquivo aí vão ser executados pelo docker-compose.

Mas agora sim, sem mais delongas, bora fazer nosso mongo e node se acharem nesse mundo de containers.

Nosso arquivo _docker-compose.yaml_ vai ser o seguinte:

```yaml
version: "3.3"

services:
  mongo_container:
    container_name: mongo
    image: mongo
    volumes:
      - dbdata:/data/db
    ports:
      - "27017:27017"

  node_container:
    depends_on:
      - mongo_container
    build: .
    container_name: api_node
    env_file: ./.env
    command: yarn dev
    ports:
      - "$PORT:$PORT"
    volumes:
      - ".:/source"
      - node_modules:/source/node_modules
    restart: always

volumes:
  dbdata: {}
  node_modules: {}
```

Rodou esse maluco aí? Então já pode testar usando _curl_, _postman_, _insomnia_ ou qualquer outro aplicativo em `http://localhost:porta_escolhida_via_env`.

E era isso. Legal né?

Uma aplicação node com mongo via docker.

A explicação detalhada desse arquivo aí de cima vou deixar para outro post.

uhul!!!!