Como empacotar um aplicativo VueJS + NodeJS + MongoDB no Docker

Como empacotar um aplicativo VueJS + NodeJS + MongoDB no Docker
Como pode ser entendido a partir do artigo anterior, eu trabalhei em diferentes projetos. Os primeiros dias na nova equipe costumam ser iguais: o backend se junta a mim e realiza ações mágicas para instalar e implantar o aplicativo. O Docker é indispensável para os front-enders, já que o backend é frequentemente escrito em uma ampla gama de stacks como PHP/Java/Python/C#, e o front-end não precisa desviar a atenção do backend a cada vez para instalar e implantar tudo. Apenas em um lugar eu vi a combinação Docker-Jenkins com implantação transparente, logs e testes automatizados integrados.

Há muitos artigos detalhados sobre o Docker. Este artigo abordará a implantação de uma Aplicação de Página Única usando VueJS/Vue Router, com a parte do servidor em formato de RESTful API com NodeJS, e o MongoDB como banco de dados. O Docker Compose é utilizado para descrever e iniciar vários aplicativos-contêineres.

Por que o Docker é necessário

O Docker permite automatizar o processo de implantação do aplicativo. O desenvolvedor não precisa mais instalar programas manualmente ou lutar contra a incompatibilidade de versões em sua máquina. Basta instalar o Docker e digitar 1-2 comandos no console. É mais conveniente fazer isso no Linux.

Começando

Instalando Docker e Docker compose

Estrutura de pastas

Criamos 2 pastas para os aplicativos cliente e servidor. O arquivo com a extensão .yml é a configuração Docker Compose, onde os contêineres do aplicativo são definidos e vinculados.
Docker-compose.yml:

version: "3"
services:
  mongo:
    container_name: mongo
    hostname: mongo
    image: mongo
    ports:
      - "27017:27017"
  server:
    build: server/
    #command: node ./server.js #aqui você pode sobrescrever o CMD do Dockerfile em /server
    ports:
      - "3000:3000"
    links:
      - mongo
  client:
    build: client/
    #command: http-server ./dist #aqui você pode sobrescrever o CMD do Dockerfile em /client
    network_mode: host
    ports:
      - "8089:8089"
    depends_on:
      - server

Criamos 3 serviços no Docker: para NodeJS, MongoDB e para os arquivos estáticos no Vue. Para conectar o cliente ao servidor, foi adicionado depends on server. Para o link MongoDB com a API do servidor, é utilizado links mongo. Server, client, mongo — são os nomes dos serviços.

Cliente em VueJS

Na pasta /client o aplicativo está localizado em VueJS. O aplicativo foi criado com Vue Cli. Ao construir a imagem, o aplicativo cliente é montado em um conjunto de arquivos estáticos na pasta /dist. O Dockerfile descreve um conjunto de comandos para construir a imagem:

FROM node:10
WORKDIR /client
COPY ./package*.json ./
RUN npm install
RUN npm install -g http-server
COPY . .
RUN npm run build
EXPOSE 8081
CMD ["npm", "test:dev"]

Observe que o package.json é copiado e instalado separadamente dos outros arquivos do projeto. Isso é feito para otimização, permitindo que o conteúdo da pasta /node_modules seja armazenado em cache durante a recompilação. Cada linha de comando é armazenada em cache separadamente.

No final, ao iniciar o contêiner, é executado o comando npm run dev. Este comando está descrito no package.json:


"scripts": {
	 "test:dev": "http-server dist -p 8081 -c 1 --push-state"
}

Para executar os arquivos da pasta /dist, é instalado globalmente http-server, e no dev-dependencies o pacote spa-http-server, para que o Vue Router funcione corretamente. A flag —push-state redireciona para o index.html. A flag -c com o valor de 1 segundo foi adicionada para http-server não armazenar em cache os scripts. Este é um exemplo de teste; em um projeto real, é melhor usar o nginx.

No Vuex store, criamos o campo apiHost: 'http://localhost:3000', onde é especificada a porta da API NodeJS. A parte cliente está pronta. Agora, todas as requisições do cliente para o backend vão para esta URL.

API do servidor NodeJS

Na pasta /server criamos server.js e o Dockerfile:


FROM node:10
WORKDIR /server
COPY ./package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Em server.js indica-se url para o banco de dados const url = 'mongodb://mongo:27017/';. Permitimos requisições cross-domain do cliente:


const clientUrl = 'http://localhost:8081';
const corsOptions = {
  origin: clientUrl,
  optionsSuccessStatus: 200,  // alguns navegadores legados (IE11, várias SmartTVs) têm problemas com 204
};
app.use(cors());
app.all('*', (req, res, next) => {
  res.header('Access-Control-Allow-Origin', clientUrl);
  res.header('Access-Control-Allow-Headers', 'X-Requested-With');
  next();
});
  app.get('/getProducts', cors(corsOptions), (req, res) => {
    products.getContent
      .then(data => res.json(data), err => res.json(err));
  });
  app.get('/getUsers', cors(corsOptions), (req, res) => {
    db.getUsers()
      .then(data => res.json(data), err => res.json(err));
  });

Conclusão

Agora vamos para o diretório do projeto e iniciar docker-compose build para a construção das imagens e docker-compose up para iniciar os contêineres. O comando levantará 3 contêineres: server, client, mongo. Para o servidor em NodeJS, pode-se configurar hot-reload, conectando-o com a pasta user. E o cliente, em fase de desenvolvimento, deve ser executado localmente com hot reload, iniciando separadamente servidor e mongo. Para iniciar um serviço separado, basta especificar seu nome docker-compose up client. Não esqueça de fazer às vezes prune e remover contêineres (containers), redes (networks) e imagens (images), para liberar recursos.

O código completo pode ser conferido aqui. O projeto ainda está em fase de desenvolvimento.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster