Como usar o docker para desenvolvimento

Docker para ambiente de desenvolvimento

LinkVersão curta

Para corrigir problemas de compatibilidade, você pode usar Docker durante desenvolvimento. Para fazer isso, crie uma Dockerfile e coloque todas as dependências do projeto lá. Coisas como NodeJS, Git, Python, etc. Você também pode usar o Docker Compose se você precisar de mais de um contêiner.

Agora crie um Docker volume para o seu código-fonte e use seu contêiner de desenvolvimento para executar todos os comandos.

Se você estiver usando VSCode, há uma extensão que integra tudo isso. Vou deixar um link para ela nas referências.

Continue lendo se quiser se aprofundar.

LinkIntrodução Tecnológica

Nós amamos Docker, mas, aparentemente, odiamos nossos colegas de trabalho. Pense nisso. É frustrantemente comum juntar-se a um projeto e gastar um dia inteiro com o processo de integração.

Mas ei, estamos sendo pagos, certo? A menos que seja código aberto, nesse caso, desistimos de contribuir.

Claro, é bom ter um guia para a base de código, mas não deveria demorar tanto. É apenas uma introdução afinal de contas. Você só se familiarizará com a base de código quando começar a trabalhar nela.

E essa é a parte frustrante, "trabalhar nela". Demora muito para configurar o ambiente de desenvolvimento.

Você precisa daquela versão específica do Node, e daquela versão específica do Python, e um servidor NGINX rodando e um Mongo DB populado e assim por diante... Trocar de máquina torna-se inviável.

Agora, imagine entrar em um projeto e a única coisa que você precisa ter instalado é o Docker. Então você executa um único comando e está tudo pronto.

É isso que vamos fazer hoje.

Vou mostrar como configurar o ambiente de desenvolvimento para um projeto que usa Node, Heroku e MongoDB. Quando estiver pronto, estaremos executando npm install, npm run build e npm start de dentro de um contêiner.

LinkConfiguração para projeto Node

Nosso projeto requer Node. Mas não qualquer versão do Node, requer Node versão 14.15.4, e NPM 7.5.4 e o CLI mais recente da Heroku.

Ok, vamos escrever nosso dockerfile.

dockerfile
FROM node:14.15.4
RUN npm install -g [email protected]
RUN curl https://cli-assets.heroku.com/install.sh | sh
WORKDIR /var/www

Feito.

NOTA: isso levaria pelo menos 15 minutos para qualquer novo desenvolvedor se juntando à sua equipe. E eles constantemente executariam seu projeto com a versão errada do Node. Não me agradeça depois, agradeça-me agora.

LinkConectando-se ao contêiner

Agora vamos construir esse contêiner e executá-lo interativamente e com TTY.

bash
docker build --tag dev-container .
docker run --interactive --tty dev-container
# ↑ Same as docker run -it dev-container

NOTA: eu não sei o que significa TTY, mas tenho certeza que alguém vai deixar um tweet nos esclarecendo. Mas se você não usar TTY, seu contêiner irá executar... e morrer. Imediatamente.

A não ser que o comando (CMD) da imagem que você está executando o mantenha vivo. Mas imagens como Ubuntu não permanecem vivas por padrão, então você precisa do TTY nesses casos.

Agora estamos no terminal do contêiner e podemos verificar que o Node, NPM e o CLI da Heroku estão instalados corretamente.

bash
root@90967edcf8f1:/var/www node -v
v14.15.4

root@90967edcf8f1:/var/www npm -v
7.5.4

root@90967edcf8f1:/var/www heroku -v
heroku/7.47.12 linux-x64 node-v12.16.2

Se você matar seu processo, o contêiner também morrerá. Se não é isso que você quer, você pode executar o contêiner desanexado e usar o docker exec para se conectar a ele. Dessa forma, ele não morrerá quando você matar seu processo.

bash
docker run --detach --tty dev-container
# Use `docker ps` to grab the container ID
docker exec --interactive --tty { container_id } bash

LinkCompartilhando arquivos com volumes

Nosso contêiner tem as ferramentas de que precisamos, mas ainda não tem acesso ao nosso código-fonte.

Para corrigir isso, vamos criar um Docker volume quando executarmos o contêiner.

bash
# Use `docker ps` to grab the container ID
docker kill { container_id }
docker run --detach --tty --volume $(pwd):/var/www dev-container
# Use `docker ps` to grab the new container ID
docker exec --interactive --tty { new_container_id } bash

Agora podemos acessar os arquivos do projeto dentro do contêiner /var/www.

bash
root@90967edcf8f1:~ cd /var/www
root@90967edcf8f1:/var/www ls
dist  node_modules  package-lock.json  package.json  src  tsconfig.json

Vamos executar npm clean-install e logo npm run build, apenas pelo prazer de ver como funciona.

LinkVSCode integration

Legal, funciona!

Mas executar o contêiner e anexar a ele é repetitivo.

Além disso, se você tentar usar Git dentro do contêiner, você perceberá que não está autenticado nos seus repositórios remotos.

A boa notícia é que se você estiver usando VSCode, como todas as outras pessoas descoladas, você pode evitar esses problemas e tornar todo o processo quase transparente.

Instale a extensão Remote - Containers. Essa extensão do VSCode vai automaticamente construir, executar, e conectar o terminal do VSCode ao o terminal do contêiner de desenvolvimento. Ela também fornece suas autenticações no Git, mata o contêiner ao fechar o VSCode e faz outras coisas que tornam a sua vida mais fácil.

Para configurar essa extensão, precisamos criar um arquivo devcontainer.json dentro da pasta .devcontainer, e também precisamos mover nosso Dockerfile para essa pasta. As propriedades do devcontainer.json são autoexplicativas, e as que são complexas são melhor explicadas em sua documentação, portanto, não tentarei explicá-las.

JSON
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.134.0/containers/javascript-node
{
  "name": "lucas-paganini-api",

  "build": {
    "dockerfile": "./Dockerfile",
    "context": ".."
  },
  "forwardPorts": [3000],

  "workspaceMount": "source=${localWorkspaceFolder},target=/var/www,type=bind",
  "workspaceFolder": "/var/www",

  "postStartCommand": "npm clean-install",
  "shutdownAction": "stopContainer",

  "settings": {
    "terminal.integrated.shell.linux": "/bin/bash"
  },

  // Add the IDs of extensions you want installed when the container is created.
  "extensions": ["ms-vscode-remote.remote-containers", "esbenp.prettier-vscode"]
}

NOTA: você também pode declarar uma lista de extensões do VSCode que você deseja instalar no ambiente de desenvolvimento. E você também pode declarar um comando para ser executado quando o contêiner estiver pronto! Sinceramente, não é incrível?!

Quando você abre o projeto, aparece um pop-up perguntando se você deseja abrir o projeto dentro do contêiner de desenvolvimento. Se isso não acontecer, abra a paleta de comando do VSCode e pesquise por "Remote-Containers: Open Folder in Container". Em seguida, selecione a pasta raiz do projeto.

LinkAdicionando MongoDB com Docker Compose

E se você depende de outros contêineres? Por exemplo, um banco de dados MongoDB. Nesse caso, você precisaria de um arquivo do Docker Compose e algumas mudanças no devcontainer.json.

yml
# Docker compose for development

version: '3.8'

services:
  mongo-db:
    image: mongo:4.4.3
    networks:
      - main-net

  main:
    build:
      dockerfile: ./.devcontainer/Dockerfile
      context: ..
    image: lucas-paganini-api/main
    ports:
      - '3000:3000'
    networks:
      - main-net
    environment:
      DB_HOST: mongo-db:27017
      PORT: 3000
    depends_on:
      - mongo-db
    tty: true
    volumes:
      - ..:/var/www
    command: bash

networks:
  main-net:
    driver: bridge
JSON
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.134.0/containers/javascript-node
{
  "name": "lucas-paganini-api",

  "dockerComposeFile": "./docker-compose.yml",
  "forwardPorts": [3000],
  "service": "main",

  "workspaceFolder": "/var/www",
  "postStartCommand": "npm clean-install",
  "shutdownAction": "stopCompose",

  "settings": {
    "terminal.integrated.shell.linux": "/bin/bash"
  },

  // Add the IDs of extensions you want installed when the container is created.
  "extensions": ["ms-vscode-remote.remote-containers", "esbenp.prettier-vscode"]
}

LinkConclusão

Tenho certeza que seus projetos se beneficiarão de um ambiente de desenvolvimento normalizado.

Vou deixar um link para o repositório nas referências abaixo.

Como sempre, tenha um ótimo dia e nos vemos em breve!

LinkReferências

  1. Repositório no GitHub
  2. Como Definir seu Ambiente de Desenvolvimento Local com Node.js Usando Docker
  3. Como Definir seu Ambiente de Desenvolvimento Local com Node.js Usando Docker – Parte 2
  4. Porque e Como Usar Docker para Desenvolvimento
  5. Usando Containers Para Desenvolvimento
  6. Extensões do VSCode para containers
  7. devcontainer.json Referência

Assine a nossa Newsletter e seja avisado quando eu lançar um curso, postar um vídeo ou escrever um artigo.

Campo obrigatório
Campo obrigatório