Docker: Node.js

Como usar e implementar uma aplicação Node.js com Docker

Bem-vindo à documentação da Stackhero

A Stackhero disponibiliza uma plataforma Docker cloud CaaS (Containers as a Service) pronta a usar, concebida para implementações de contentores rápidas e fiáveis:

  • Implemente em produção com um simples docker-compose up. Não é necessária qualquer configuração adicional: basta iniciar os seus contentores.
  • Escolha o seu próprio nome de domínio, automaticamente protegido com HTTPS (por exemplo: https://api.sua-empresa.com, https://www.sua-empresa.com ou https://backoffice.sua-empresa.com).
  • Beneficie de elevado desempenho e segurança robusta numa infraestrutura privada e dedicada.
  • Aplique atualizações com um clique para uma manutenção simples e sem esforço.

Pode ter os seus contentores em produção em cerca de cinco minutos. A Stackhero gere a infraestrutura, as atualizações e a segurança por si, para que se possa focar na entrega das suas aplicações. Saiba mais sobre alojamento cloud Docker CaaS.

Este guia oferece uma base sólida para desenvolver uma aplicação Node.js e implementá-la em produção de forma rápida e fácil.

Não é necessário conhecimento prévio de Docker. Tudo está configurado para garantir uma experiência tranquila; só precisa ter o Docker instalado no seu computador.

Esta documentação é destinada tanto a iniciantes quanto a utilizadores experientes que desejam implementar uma aplicação Node.js usando tecnologias modernas e escaláveis sem complicações desnecessárias.

As principais características desta solução incluem:

  • 💪 Configuração fácil com mínimo esforço
  • 🐳 Utilização do Docker para ambientes de desenvolvimento e produção
  • 🔄 Recarregamento automático do Node.js ao alterar o código usando nodemon
  • 🚀 Implementação em produção com um único comando
  • 🔒 Gestão de certificados TLS para encriptação HTTPS segura
  • 🚧 Suporte para plataformas de staging e pré-produção
  • 🧱 Arquitetura modular e escalável

Se o Docker ainda não estiver instalado no seu computador, pode descarregá-lo do site oficial do Docker. Para verificar se o Docker está a funcionar corretamente, abra um terminal e execute docker version. Deverá ver as informações da versão sem erros.

Após instalar o Docker, clone o seguinte repositório de boilerplate:

git clone https://github.com/stackhero-io/nodejsWithDockerGettingStarted/
cd nodejsWithDockerGettingStarted

Depois, inicie a plataforma de desenvolvimento executando make development-start ou veja todos os comandos disponíveis com make help.

Para iniciar a plataforma de desenvolvimento, execute:

make development-start

Este comando constrói a imagem Docker, executa-a e lança o script dev definido em my-app/package.json (equivalente a executar npm run dev).

Neste exemplo, é criada uma simples API REST usando Express. Pode visualizar a API navegando para http://localhost:5000. A página deverá exibir "Hello World".

Em seguida, abra o ficheiro my-app/src/app.js no seu IDE preferido e modifique a seguinte linha:

res.send('Hello World');

Altere para:

res.send('Updated!');

Guarde o ficheiro. O código Node.js será recarregado automaticamente e uma atualização de http://localhost:5000 refletirá a resposta atualizada da API.

Parabéns - agora tem uma plataforma de desenvolvimento totalmente operacional!

Se precisar de instalar pacotes adicionais, pode executar make development-shell para aceder ao shell do contêiner. Uma vez dentro, use NPM com npm install <package> ou Yarn com yarn add <package> para instalar os pacotes desejados.

Se tiver um projeto Node.js existente que deseja integrar com Docker, siga estes passos:

  1. Crie um novo diretório chamado my-app dentro do seu projeto.

  2. Mova todos os seus ficheiros de projeto para o diretório my-app, excluindo os ficheiros .gitignore e .git.

  3. Copie o docker, secrets, e Makefile do boilerplate para o diretório raiz do seu projeto.

  4. Edite o ficheiro .gitignore no seu projeto e adicione as seguintes linhas:

    node_modules/
    secrets/*.production
    secrets/*.staging
    

Este boilerplate assume que a sua aplicação escuta na porta 5000. Se preferir outra porta, pode editar o ficheiro docker/docker-compose.development.yml e depois reiniciar o ambiente com make development-start.

Se desejar especificar uma versão diferente do Node.js, siga estes passos:

  1. Abra o ficheiro docker/my-app.dockerfile, que define a imagem Docker para a sua aplicação.
  2. Localize a primeira linha que lê FROM node:<version>-alpine.
  3. Substitua <version> pela versão do Node.js da sua escolha. Recomenda-se usar a versão Long-Term Support (LTS). Pode verificar a última versão LTS no site do Node.js. Por exemplo, para usar a última versão LTS (atualmente 22), atualize a linha para FROM node:22-alpine. Se preferir um número de versão específico, pode usar algo como FROM node:22.13.0-alpine.
  4. Guarde as suas alterações no Dockerfile.

Defina as variáveis de ambiente para a plataforma de desenvolvimento no ficheiro secrets/my-app.development.

Para produção, use o ficheiro secrets/my-app.production.

Não cometa o ficheiro secrets/my-app.production no seu repositório Git! Este ficheiro contém informações sensíveis e é ignorado por padrão no .gitignore do boilerplate para evitar partilha acidental.

Se a sua aplicação Node.js precisar armazenar ficheiros (por exemplo, uploads de utilizadores), considere usar um serviço de armazenamento de objetos como MinIO. Um serviço de armazenamento de objetos ajuda a sua aplicação a escalar sem problemas enquanto reduz potenciais problemas.

Se preferir armazenar ficheiros localmente, certifique-se de usar sempre um volume Docker. Armazenar ficheiros diretamente num contêiner pode levar a perda de dados. Este boilerplate fornece um volume montado em /persistent para armazenar ficheiros com segurança.

Nunca armazene dados persistentes fora do diretório /persistent a menos que tenha criado volumes personalizados e esteja certo da configuração. Armazenar ficheiros fora de /persistent resultará em perda de dados!

Pode facilmente modificar este boilerplate para adicionar um ambiente de staging. Para isso:

  1. Crie uma cópia de docker/docker-compose.production.yml e nomeie-a docker/docker-compose.staging.yml. Este ficheiro define os contêineres e a configuração para o seu ambiente de staging.
  2. Crie o ficheiro de segredos secrets/my-app.staging contendo qualquer informação sensível necessária para o staging, como senhas de base de dados ou chaves API.
  3. No Makefile, localize a seção intitulada "Staging platform" e descomente-a.

Finalmente, execute make help para ver os novos comandos de staging que agora estão disponíveis.

Se ainda não tiver um serviço Stackhero for Docker, pode criar um facilmente a partir do seu painel Stackhero. Será ativado em aproximadamente 2 minutos.

Se é novo no Stackhero, pode experimentar o alojamento em cloud de contêineres Docker gratuitamente durante um mês.

Antes de implementar a sua aplicação em produção, precisa preparar alguns ficheiros de configuração:

  1. Copie secrets/global.production.example para secrets/global.production.
  2. Edite secrets/global.production e substitua <XXXXXX>.stackhero-network.com pelo nome de host do seu serviço Docker a partir do seu painel Stackhero.
  3. Copie secrets/my-app.production.example para secrets/my-app.production.
  4. Edite secrets/my-app.production e insira as suas credenciais.
  5. Atualize docker/docker-compose.production.yml substituindo <XXXXXX>.stackhero-network.com pelo nome de host do seu serviço Docker.

A implementação em produção é simples: execute:

make production-deploy

Este comando cria um contêiner Docker, transfere os dados do seu projeto e envia-os para o seu serviço Docker em produção. Abra o seu navegador e navegue para o nome de host do seu serviço Docker (por exemplo, https://<XXXXXX>.stackhero-network.com). Deverá ver a sua API REST responder "Hello World".

Também pode usar make production, que implementa os seus contêineres e exibe logs em tempo real.

Para monitorizar o seu ambiente de produção ou resolver problemas, pode consultar os seus logs usando estes comandos:

  • Para transmitir logs ao vivo, execute: make production-logs-live
  • Para recuperar todos os logs armazenados, execute: make production-logs
  • Para recuperar logs de um dia específico (substitua YYYY-MM-DD pela data desejada), execute: make production-logs | grep "YYYY-MM-DD"

Se desejar usar um nome de domínio diferente de https://<XXXXXX>.stackhero-network.com, o Stackhero for Docker integra o Traefik para simplificar a gestão de domínios. O Traefik lida com o roteamento HTTP e a encriptação TLS (HTTPS) para si.

Aqui estão alguns exemplos para personalizar os seus nomes de domínio:

  • Para servir api.my-company.com através do seu contêiner my-app na porta 5000 com encriptação TLS, atualize o ficheiro docker/docker-compose.production.yml substituindo a seção labels por:

        labels:
          - "traefik.enable=true" # Ativar Traefik para rotear o tráfego para este contêiner
          - "traefik.http.routers.my-app.rule=Host(`api.my-company.com`)" # Definir o host
          - "traefik.http.routers.my-app.tls.certresolver=letsencrypt" # Usar letsencrypt para certificados TLS
          - "traefik.http.services.my-app.loadbalancer.server.port=5000" # Especificar a porta 5000
    
  • Para servir my-company.com através do seu contêiner my-app na porta 5000 e redirecionar todas as solicitações de www.my-company.com para my-company.com, atualize a seção labels no mesmo ficheiro com:

        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.my-app.rule=Host(`my-company.com`) || Host(`www.my-company.com`)" # Incluir ambos os domínios
          - "traefik.http.routers.my-app.tls.certresolver=letsencrypt"
          - "traefik.http.services.my-app.loadbalancer.server.port=5000" # Especificar a porta 5000
    
          # Redirecionar www.my-company.com para my-company.com:
          - "traefik.http.routers.my-app.middlewares=redirect-www"
          - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
          - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
          - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"
    

Não se esqueça de configurar o DNS para my-company.com e www.my-company.com para que cada um aponte como um CNAME para o seu serviço Docker em https://<XXXXXX>.stackhero-network.com.