Implante um aplicativo da web isomórfico usando o Nuxt.js como exemplo.


Em projetos de médio e grande porte, o site não se limita a um serviço - por exemplo, apenas um site, como regra, há um banco de dados, uma API, um servidor que roteia solicitações para todos esses serviços. A implantação e atualização de tudo isso sem padronização não é fácil, e a expansão para muitos servidores é ainda mais difícil.

O Docker, que se tornou o padrão de fato no mundo dos aplicativos de embalagem, entrega e publicação, nos ajudará a resolver esse problema.

O Docker nos permite agrupar um aplicativo ou serviço com todas as dependências e configurações em um contêiner isolado, garantindo a consistência do conteúdo em qualquer plataforma.

Como um aplicativo isomórfico, usaremos a estrutura Nuxt.js, que consiste em Vue.js e Node.js, permitindo escrever aplicativos da Web universais com renderização do lado do servidor (SSR).

Essa opção é devido à preferência pessoal, no entanto, da mesma maneira, você pode usar qualquer outra estrutura, por exemplo, Next.js.

Coletamos e publicamos a primeira imagem.


Primeiro de tudo, você precisa configurar a porta e o host dentro do aplicativo. Existem várias maneiras de fazer isso. Usaremos as configurações em package.json adicionando uma nova seção:

"config": { "nuxt": { "host": "0.0.0.0", "port": "3000" } } 

Para ações posteriores, precisamos do docker, docker-compone instalado no sistema e um editor com um projeto aberto.

Crie um Dockerfile que colocamos na raiz e descreva as instruções para criar a imagem.

Precisamos construir a imagem com base na imagem da versão 10 do Node.js. Nesse caso, a versão leve do alpine é usada:

 FROM node:10-alpine 

Em seguida, defina a variável de ambiente com o nome do diretório:

 ENV APP_ROOT /web 

Defina como o diretório de trabalho e adicione a fonte:

 WORKDIR ${APP_ROOT} ADD . ${APP_ROOT} 

Instale as dependências e construa o aplicativo:

 RUN npm ci RUN npm run build 

E escrevemos o comando de inicialização do aplicativo dentro da imagem:

 CMD ["npm", "run", "start"] 

Dockerfile
 FROM node:10-alpine ENV APP_ROOT /web ENV NODE_ENV production WORKDIR ${APP_ROOT} ADD . ${APP_ROOT} RUN npm ci RUN npm run build CMD ["npm", "run", "start"] 


Depois disso, abra a pasta atual no terminal e colete a imagem:

 docker build -t registry.gitlab.com/vik_kod/nuxtjs_docker_example . 

Execute a imagem localmente para verificar se tudo funciona corretamente:

 docker run -p 3000:3000 registry.gitlab.com/vik_kod/nuxtjs_docker_example 

Indo para localhost: 3000, devemos ver o seguinte:



Ótimo! Iniciamos com sucesso a produção construindo o aplicativo na máquina local.

Agora, precisamos publicar a imagem no repositório do docker para usar a imagem montada finalizada no servidor de destino. Você pode usar um repositório auto-hospedado ou qualquer outro, por exemplo, o hub.docker.com oficial.

Vou usar o repositório no gitlab, a guia com repositórios docker é chamada de registro. Anteriormente, eu já criei um repositório para o projeto, então agora eu executo o comando:

 docker push registry.gitlab.com/vik_kod/nuxtjs_docker_example 

Após a inicialização da imagem, você poderá começar a configurar o servidor VPS,
o meu é o seguinte:

  • 1 GB de RAM
  • 4 núcleos
  • Unidade de 30 GB

Também aproveitei a oportunidade para instalar o docker imediatamente ao criar o servidor; portanto, se ele não estiver instalado no seu VPS, você poderá ler as instruções no site oficial.

Depois de criar o servidor, vá para ele e efetue login no repositório do docker, no meu caso é o gitlab:

 docker login registry.gitlab.com 

Após a autorização, podemos iniciar o aplicativo com o comando visto anteriormente:

 docker run -p 3000:3000 registry.gitlab.com/vik_kod/nuxtjs_docker_example 



A imagem foi baixada e iniciada, vamos verificar:



Vemos uma imagem familiar, lançamos o contêiner com o aplicativo, mas já no servidor remoto.

O toque final permaneceu; agora, quando o terminal estiver fechado, a imagem será interrompida; portanto, adicionaremos o atributo -d para iniciar o contêiner em segundo plano.
Pare e reinicie:

 docker run -d -p 3000:3000 registry.gitlab.com/vik_kod/nuxtjs_docker_example 

Agora podemos fechar o terminal e garantir que nosso aplicativo esteja funcionando com sucesso.

Conseguimos o que era necessário - lançamos o aplicativo no docker e agora ele é adequado para implantação, como imagem independente e como parte de uma infraestrutura maior.

Adicionar proxy reverso


No estágio atual, podemos publicar projetos simples, mas e se precisarmos colocar o aplicativo e a API no mesmo domínio e, além disso, fornecer as estatísticas não através do Node.js.

Assim, surge a necessidade do chamado servidor proxy reverso, para o qual todas as solicitações serão recebidas e redirecionadas, dependendo da solicitação para serviços relacionados.

Como servidor, usaremos o nginx.

Gerenciar contêineres se houver mais de um individualmente não é muito conveniente. Portanto, usaremos o docker-compose como uma maneira de organizar e gerenciar contêineres.

Crie um novo projeto vazio, na raiz do qual adicionamos o arquivo docker-compose.yml e a pasta nginx.

No docker-compose.yml, escrevemos o seguinte:

 version: "3.3" #      services: #  , nginx nginx: image: nginx:latest #   80  http  443  https ports: - "80:80" - "443:443" #      container_name: proxy_nginx volumes: #   nginx ,      - ./nginx:/etc/nginx/conf.d #            - ./logs:/var/log/nginx/ #   Nuxt.js  nuxt: #     image: registry.gitlab.com/vik_kod/nuxtjs_docker_example container_name: nuxt_app #        ports: - "3000:3000" 

Na pasta nginx, adicione a configuração, recomendada pelo site oficial Nuxt.js , com pequenas alterações.

nginx.conf
 map $sent_http_content_type $expires { "text/html" epoch; "text/html; charset=utf-8" epoch; default off; } server { root /var/www; listen 80; #    nginx server_name localhost; #   ip  gzip on; gzip_types text/plain application/xml text/css application/javascript; gzip_min_length 1000; location / { expires $expires; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 1m; proxy_connect_timeout 1m; #   ,       # docker-compose        ,    nuxt_app proxy_pass http://nuxt_app:3000; } } 


Executamos o comando para executar:

 docker-compose up 



Tudo começou corretamente, agora, se formos para o endereço que está ouvindo o nginx, localhost - veremos nosso aplicativo, não haverá diferenças visuais, mas agora todas as solicitações vão para o nginx primeiro, onde são redirecionadas, dependendo das regras especificadas.

Agora não temos serviços ou estatísticas adicionais, vamos adicionar uma pasta estática na qual colocaremos alguma imagem.

Monte-o no contêiner nginx adicionando uma linha ao docker-compose:

 ... container_name: proxy_nginx volumes: #     - ./static:/var/www/static ... 

Docker-compose.yml atualizado
 version: "3.3" #      services: #  , nginx nginx: image: nginx:latest #   80  http  443  https ports: - "80:80" - "443:443" #      container_name: proxy_nginx volumes: #   nginx ,      - ./nginx:/etc/nginx/conf.d #            - ./logs:/var/log/nginx/ #     - ./static:/var/www/static #   Nuxt.js  nuxt: #     image: registry.gitlab.com/vik_kod/nuxtjs_docker_example container_name: nuxt_app #         ports: - "3000:3000" 


Em seguida, adicione o novo local ao nginx.conf:

 location /static/ { try_files $uri /var/www/static; } 

Nginx.conf atualizado
 map $sent_http_content_type $expires { "text/html" epoch; "text/html; charset=utf-8" epoch; default off; } server { root /var/www; listen 80; #    nginx server_name localhost; #   ip  gzip on; gzip_types text/plain application/xml text/css application/javascript; gzip_min_length 1000; location / { expires $expires; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 1m; proxy_connect_timeout 1m; #   ,       # docker-compose        ,    nuxt_app proxy_pass http://nuxt_app:3000; } location /static/ { try_files $uri /var/www/static; } } 


Reinicie a janela de encaixe-composição:

 docker-compose up --build 

Vá para localhost / static / demo.jpg




Agora, as estatísticas são fornecidas pelo Nginx, removendo a carga do Node.js no aplicativo principal.

Depois de garantir que tudo funcione, você pode publicar nossa montagem no servidor. Para fazer isso, vou criar um repositório no diretório atual. Tendo adicionado anteriormente os logs e a pasta estática ao .gitignore.

Depois disso, vamos ao servidor, paramos a imagem do docker que foi lançada anteriormente e clonamos o repositório.



Antes de iniciar a montagem, você precisa mover a pasta com as estáticas para o servidor, acessar o terminal na máquina local e usar o utilitário de linha de comando scp para mover a pasta para o servidor:

 scp -r /Users/vik_kod/PhpstormProjects/nuxtjs_docker_proxy_example/static root@5.101.48.172:/root/example_app/ 

Se o volume de estática for grande, é melhor compactar primeiro a pasta e enviá-la como um arquivo morto e depois descompactá-la no servidor. Caso contrário, o download poderá demorar muito tempo.

Retornamos ao terminal no servidor e vamos para a pasta clonada, execute o comando:

 docker-compose up -d 

Feche o terminal e acesse o site:




Ótimo! Usando o proxy reverso, separamos a estática do aplicativo.

Passos adicionais


Tudo o que fizemos acima é uma opção bastante simples; em grandes projetos, você precisa considerar mais coisas; abaixo está uma pequena lista do que você pode fazer a seguir.

  • Contêineres de dados apenas para áreas administrativas estáticas, aplicativos SPA e bancos de dados
  • Serviços adicionais para processamento e otimização de imagens, por exemplo
  • Integração de CI / CD, montagem da imagem ao avançar para a ramificação selecionada, bem como atualização automática e reinicialização de serviços
  • Crie um cluster Kubernetes ou Swarm se houver mais de 1 servidor, para balanceamento de carga e fácil dimensionamento horizontal

Total


  • Publicamos o aplicativo com sucesso no servidor e o preparamos para mais redimensionamentos.
  • Conhecemos o docker e tivemos uma idéia de como agrupar seu aplicativo em um contêiner.
  • Aprendemos quais medidas podem ser tomadas ainda mais para melhorar a infraestrutura.

Código fonte


App
Configs

Obrigado por sua atenção e espero que este material tenha ajudado!

Source: https://habr.com/ru/post/pt438862/


All Articles