Prefácio
Para começar, um dia eu quis criar um aplicativo. Esse desejo surgiu porque eu amo ler, mas simplesmente não existem agregadores de livros normais na vasta Internet russa. Na verdade, com a dor de procurar algo para ler e tentar lembrar o nome do livro que li recentemente e em que capítulo parei, nasceu o desejo de criar um aplicativo da Web no qual tudo isso fosse possível e conveniente. Vale ressaltar que nenhuma experiência em desenvolvimento, programação, etc. Eu não tinha, meu trabalho não está ligado a isso. No entanto, o desejo superou a preguiça e se transformou em ações concretas, uma espécie de hobby.
Não vou contar como estudei javascript, node.js, reagir, html, css etc., passaremos para o que descobri no momento, o que gostaria de compartilhar com você e, é claro, ouvir críticas construtivas de especialistas.
Como muitos, eu treinei no meu próprio PC no localhost: 3000, criei front-ends, digitei, trabalhei com API, etc., mas sempre fiquei preocupado com o pensamento de como transferir tudo isso para a hospedagem mais tarde? Será que vai funcionar? Será necessário reescrever o código por causa disso?
E o mais importante, é possível configurar tudo para que eu possa trabalhar no aplicativo a partir de qualquer PC e transferir tudo facilmente para a hospedagem na produção? Eu vou falar sobre issoEscolha de hospedagem
Para o meu hobby, eu estava pronto para gastar US $ 10 por mês, então escolhi a hospedagem com a qual planejava ficar no futuro. Como eu disse, antes eu tinha 0 experiência, inclusive com hospedagem de sites. Tentei e recusei o seguinte:
Jelastic :
interface bonita e fácil de usar, tudo parece ser intuitivo, escalável e compreensível. No entanto, encontrei dificuldades na configuração (o nginx, por algum motivo, não queria trabalhar com vps, apenas com seu módulo separado) e na conexão SSL (e atualização automática) ao domínio de língua russa por meios padrão (eles prometeram corrigir o bug, mas não quero esperar)
Hospedagem na nuvem REG.RU : Eu também tenho um domínio ali, então a solução parecia lógica, mas eles não tinham o PostgreSQL configurado separadamente e, como eu não queria entrar em contato com a administração do banco de dados, comecei a procurar mais.
AWS e Google Cloud : tentei, tudo parece estar bem, mas lembrei-me das nossas leis "maravilhosas" e da exigência de colocar dados do usuário em servidores na Federação Russa. Infelizmente, esses caras não tinham servidores na Federação Russa. Não era advogado, mas pelo pecado decidiu procurar nuvens com servidores na Federação Russa.
Se é improvável que seu aplicativo tenha problemas com a lei, é uma boa escolha.Embora houvesse nuvens com servidores na Federação Russa, eu ainda queria algo que me salvasse de ter que mergulhar na administração do PostgreSQL. O impulso surgiu há pouco tempo atrás,
Yandex.Nuvens que se tornaram disponíveis, tentei, parece que tudo é simples e conveniente, então parei com elas por enquanto. Vale ressaltar que a hospedagem PostgreSQL vem imediatamente com 1core e 4GB de RAM, que custa cerca de 2k rublos por mês, portanto, para o tempo de desenvolvimento e carga baixa, planejo executar o PostgreSQL no VPS por ~ 300r e transferir o banco de dados com maior carga e deixar Yandex está envolvido na administração e atualização.
Configurando o Yandex.Cloud
Nuvem privada virtual
1) Crie um diretório para o seu site:

2) Crie uma nuvem privada virtual:
A principal coisa que ele me fornece no estágio atual é o IP para acessar o recurso criado de fora. Familiarizei-me com sub-redes, zonas, isolamento e tolerância a falhas superficialmente; se necessário, atualizo.
3) Crie uma sub-rede e atribua um IP interno (como eu entendo, trata-se de uma rede local)

4) Vá para a guia IP e reserve um IP estático.
Nele nos conectaremos de casa e de outros lugares. Você provavelmente pode trabalhar com dinâmica, mas eu não entendi em que casos isso muda.

Computar em nuvem
Aqui teremos cálculos :) Ou seja, criaremos uma máquina virtual com Linux (escolhi o ubuntu 18.04), instalaremos as aplicações node.js e o postgreSQL.

Clicamos para criar uma VM, desaparafusamos todas as configurações no mínimo, já que não haverá carga durante o desenvolvimento (quando nosso aplicativo for lançado, em seguida, torça um pouco mais, bem, monitoraremos pelos gráficos).
Ssh
O ponto do problema que encontrei nesta fase é o SSH:

O que era e por que eu não tinha ideia, então fui estudar. Acabou - este é apenas um método de acesso, mas não por senha, mas pela chave SSH gerada. Para realmente gerá-lo, faça o download e instale o
Putty conforme recomendado.
Execute C: \ Arquivos de Programas \ PuTTY \ puttygen.exe

Pressionamos o botão Gerar e movemos o mouse para dar aleatoriedade à tecla gerada (como eu a entendo). Em seguida, copie a linha que aparece começando com ssh-rsa em algum lugar do arquivo de texto e clique em Salvar chave privada, Salvar chave pública. A chave copiada para o arquivo de texto é inserida no campo SSH da chave da página Yandex Yandex. Especificamos root como o login, caso contrário, você não terá acesso ao trabalhar com o sistema de arquivos gráficos do aplicativo pelo qual se conectará à nuvem a partir de casa / trabalho (talvez exista uma maneira, mas eu não entendi).
Conforme observado por andreymal, é melhor não usar o root para que os bots chineses não obtenham a senha da sua nuvem, mas como o Yandex.cloud tem apenas acesso SSH, você pode viver assim.
Um aplicativo em uma hospedagem deve ser iniciado exclusivamente por um usuário não root, para não permitir que invasores executem códigos maliciosos por meio de possíveis vulnerabilidades em seu aplicativo.
Conectamos à nuvem a partir de um PC e selecionamos um cliente SSH gratuito
O Putty padrão permite que você trabalhe apenas na linha de comando e, como não estou familiarizado com o usuário do Windows, comecei a procurar um cliente com um pseudo-explorador. No começo, experimentei o Mobaxterm, mas após algum tempo de inatividade, o explorador congela por completo. Agora, estou trabalhando com o
bitvise ssh e até agora não vejo problemas como o Mobaxterm.
Configurar bitvise ssh

Aqui no campo Servidor> Host, indique nossa nuvem IP externa. Porta 22. Clique em Gerenciador de Chaves do Cliente> Importar e especifique a chave privada gerada anteriormente. Você ainda pode precisar de uma frase-chave, escolha algo que não esquecerá. Feche esta janela e especifique o nome de usuário no campo de autenticação: raiz, chave pública do método, chave do cliente - selecione a importada anteriormente. Clique em login e, se fizemos tudo corretamente, conecte-se à nuvem:

Instale o Node.js
Aqui eu recomendo usar as instruções do digitalocean.com, elas são muito detalhadas e muitas estão em russo. Normalmente, eu pesquiso no “digitalocean ubuntu 18.04 node.js” ou o que você deseja instalar ou configurar lá.
Como instalar o Node.js pode ser lido
aqui .
Em resumo, vamos ao
nodesource (aqui as versões mais recentes do node.js podem ser instaladas), folheando aqui:

Copie e execute os comandos por sua vez:
curl -sL https:
Verificamos como foi estabelecido pela equipe
nodejs -v
Veremos a versão do node.js
npm -v
Seremos mostradas a versão do gerenciador de pacotes para o node.js.
Em seguida, vá para a pasta / opt / mysuperapp (my_super_app_name - você deve criar esta pasta). O diretório opt foi escolhido como o local do aplicativo após uma longa pesquisa "onde é apropriado colocar os arquivos node.js do aplicativo no ubuntu".
Por fim, crie o arquivo server.js, que será o ponto de entrada do aplicativo, e cole o código simples do servidor no node.js:
const http = require('http'); const hostname = 'localhost'; const port = 80; const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World!\n'); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
A porta 80 é para solicitações http, 443 é para https. Enquanto nós temos um servidor em http.
Nós salvamos tudo e executamos o comando:
node server.js
O console deve exibir a linha 'Servidor em execução no
host local : 80 /'
Agora você pode abrir um navegador, inserir um IP externo (aquele na nuvem Yandex da sua VM do ubuntu) e veremos "Hello World!"
Fazemos tudo de forma conveniente ou o ciclo de desenvolvimento com o git
Tudo parece funcionar, mas não trabalhamos o tempo todo conectando-nos à nuvem. Além disso, de repente, não trabalharemos sozinhos no futuro.
Github
O Github é o local onde o código do nosso aplicativo estará. Em suma, o princípio do trabalho para uma pessoa é o seguinte:
- Estamos desenvolvendo nosso aplicativo em um PC doméstico.
- Nós salvamos e descarregamos o código no Github em um clique.
- Na hospedagem ou em outro PC, baixe nosso aplicativo no github, reinicie o servidor (se estiver hospedando) e a nova versão do nosso aplicativo da Web está disponível na World Wide Web.
Tudo é rápido, simples e conveniente.
Na verdade, registre-se no Github e crie um repositório privado para o nosso aplicativo (ele estará disponível apenas para nós):

Copie a linha
github.com/ReTWi/mysuperapp.git para baixar o aplicativo.

- Retornamos à linha de comando do bitvise, paramos o aplicativo pressionando ctrl + c (se ainda funcionar).
- Vá para o diretório / opt e exclua a pasta com o aplicativo que criamos
Git é o que usaremos para fazer upload de nosso aplicativo para o github e de lá para um host ou outro PC. Git é um tópico separado para discussão, então vamos discutir isso por enquanto.
Instale o
git na hospedagem com os seguintes comandos:
sudo apt update sudo apt install git
Verifique se tudo está bem estabelecido:
git --version
A versão do git deve aparecer.
Nós preenchemos os dados do git (eu não entendi o porquê, mas aparentemente pode haver alguns avisos chatos).
git config --global user.name "Your Name" git config --global user.email "youremail@domain.com"
Por fim, carregamos nosso aplicativo na hospedagem com o comando:
(deve haver um link para sua inscrição)
git clone https:
Um novo mysuperapp aparecerá no diretório / opt, onde nossos arquivos de aplicativo baixados do github estarão localizados.
Agora é hora de repetir o mesmo para PC e fechar a cadeia de PCs (diferente) -> Github -> Hospedagem
Instale o
node.js no PC .
Código do Visual Studio
Para começar, selecione o editor de código fonte onde trabalharemos. Eu escolhi o código do Visual studio, por isso é simples, conveniente, possui muitos plugins e você pode definir a sincronização de configurações se trabalhar com vários dispositivos. Na verdade, baixamos, instalamos, iniciamos, selecionamos a pasta do aplicativo compartilhado, pois o git clone criará o seu para nós.
Os plugins que eu uso são os seguintes:
Instale o git para PC .
Abra um console no VScode usando ctrl + shift + `ou terminal> novo terminal
Retiro:
No console do Windows, os caracteres russos são ruins; para que não haja rachaduras, abra o arquivo> preferências> configurações, digite terminal.integrated.shellArgs.windows no campo, clique em

E adicione a linha "terminal.integrated.shellArgs.windows": ["-NoExit", "/ c", "chcp 65001"],

Repita o comando para baixar arquivos do github:
git clone https:
No VScode, clique em Arquivo> Abrir Pasta e abra a pasta do nosso aplicativo.
Crie o arquivo server.js com o mesmo código de servidor simples:
const http = require('http'); const hostname = 'localhost'; const port = 80; const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World!\n'); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
Instale o nodemon para reiniciar automaticamente o servidor quando forem feitas alterações no código:
npm i nodemon -g
i - abreviação de instalação
g - instalação global (disponível no console), e não apenas para o nosso aplicativo.
Execute o comando:
nodemon server.js
Abra
localhost : 80 / no navegador ou apenas localhost: 80 e veja Hello World.
Agora é hora de conferir nossa cadeia de PCs> Github> Hosting.
Faça o download da área de trabalho do Github para maior comodidade, conecte sua conta do github, clique no arquivo adicionar repositório local e especifique o diretório do nosso aplicativo.
No aplicativo, vemos as alterações que fizemos em comparação com a versão baixada do Github (adicionamos server.js):

Clique em "comprometer-se com o domínio"> "origem de envio", baixando arquivos do PC para o Github.

Vamos para a nossa conta do github no navegador e vemos o arquivo server.js baixado:

Vamos praticar um pouco mais, no VScode substituímos a linha “res.end ('Hello World! \ N');" para "res.end ('OmNomNom');". Veremos que o próprio servidor foi reiniciado:

Vamos verificar o navegador e ver as alterações feitas por nós "OmNomNom" lá.
O github para desktop também nos mostrará que alteramos a linha:

Novamente, clique em confirmar para dominar> enviar origem para enviar arquivos ao github.
Alterne para a linha de comando de hospedagem.
Paramos nosso aplicativo se ele ainda estiver em execução (ctrl + c).
Baixe nosso aplicativo atualizado com os seguintes comandos:
git config credential.helper store git pull
O primeiro salvará nossos dados para que você não precise digitar seu nome de usuário e senha constantemente. No futuro, o git pull será suficiente para nós.
Instale o pm2 - algo semelhante ao nodemon, apenas para hospedagem:
npm i pm2 -g
Vamos iniciar o aplicativo usando o pm2, que reiniciará o servidor no próximo git pull na hospedagem:
pm2 start server.js --watch
Abra o navegador em nossa nuvem IP externa e veja nosso "OmNomNom".
Assim, fechamos a cadeia de trabalho com o aplicativo e sua rápida implantação na hospedagem.
Criamos certificados SSL temporários para HTTPS em host local e hospedagem
Vamos ao site
zerossl.com
Nos domínios, ip ... campo, primeiro digite localhost, clique em gerar e faça o download de 2 arquivos por botão:

Nós os salvamos em nosso projeto na pasta ssl / localhost.
Repita o procedimento para a nuvem IP externa e salve-a em ssl / myapp.
Inicie um servidor https node.js mais complexo
Estrutura de aplicação:

- cliente - aqui nosso front-end estará. Eu reajo.
- logs - os logs de hospedagem caem aqui
- node_modules - módulos node.js
- private - seus arquivos particulares, eu armazeno acesso SSH à nuvem lá
- servidor é o seu back-end
- ssl - certificados ssl para trabalhar https no localhost e hospedagem
- .babelrc - o aplicativo webpack'om reage às configurações de compilação (permite que você use JS mais moderno ao desenvolver frontend)
- .gitignore - arquivos que não serão movidos para o github (o git parece não vê-los)
- client.js - ponto de entrada para gerar o assembly de reação
- package.json - o node_modeles que você está usando e vários trechos de comando.
- package-lock.json - alterações nos módulos (como eu o entendo, o arquivo verificará se os mesmos módulos estão instalados na sua hospedagem e no seu PC).
- pm2-watch.json - configurações de inicialização do pm2 para hospedagem
- README.md - capa para o github
- server.js - o ponto de partida do nosso servidor Node.js. back-end
- webpack.config.js - reage à configuração da compilação
.gitignore
Aqui, indicamos os arquivos / pastas que não queremos carregar no github. Eles estarão apenas neste dispositivo e o git não rastreará / exibirá suas alterações. Abra e insira:
/node_modules/ /logs/* # exception to the rule !logs/.gitkeep /public/react_bundle.js /public/isProd.js
Como o github não descarrega pastas vazias, você pode colocar algo dentro, por exemplo, de um arquivo .gitkeep vazio. Salve o arquivo e feche.
package.json
Abra e cole o seguinte (após // comentários adicionados)
{ "name": "myapp",
Vou me concentrar em duas estruturas / bibliotecas principais selecionadas para o aplicativo:
O Fastify foi escolhido como uma alternativa ao express.js, como o primeiro já possui suporte experimental para o htpp2, ele está se desenvolvendo ativamente e me parece que ele tem mais futuro que o express.js, que se tornou muito lento e de alguma forma se desenvolve. Por outro lado, o express.js trabalha há muito tempo e será mais fácil encontrar informações sobre ele.
O React foi escolhido porque era mais fácil para mim trabalhar com ele, entender e tentar tudo com minhas próprias mãos. Vue - parecia algo com suas próprias regras, direção. Embora no Vue possa ser necessário escrever algo menos com suas próprias mãos, mas como a prioridade é o treinamento e para uma pessoa que não tenha programado anteriormente, a reação foi de alguma maneira mais fácil.
Salvamos o arquivo package.json e instalamos todos os módulos especificados nas dependências com o comando:
npm i
Teremos uma pasta node_modules, na qual haverá todos os módulos para nosso aplicativo.
cliente - enquanto a pasta vazia
logs - dentro do arquivo .gitkeep, para que a pasta seja migrada para a hospedagem e os logs caiam com êxito lá. Durante o desenvolvimento, produziremos tudo para o console.
público
Aqui estão os arquivos estáticos do nosso site, imagens, favicons etc.
Vamos nos debruçar sobre dois arquivos:
index.html:
<!DOCTYPE html> <html> <head> <base href="/" /> <meta charset="UTF-8" /> <title>MyApp</title> </head> <body> <div id="cookies"> react_bundle </div> <noscript >: Javscript</noscript > <script src="react_bundle.js"></script> </body> </html>
- aqui temos um front-end de reação carregado e renderizado em uma tag por seu ID.
isProd.js contém uma única linha "module.exports = false"
Como está nas exceções .gitignore, não é portátil. Conseqüentemente, definimos como falso no PC e verdadeiro na hospedagem. Em seguida, usamos esse arquivo para entender em que ambiente estamos atualmente (desenvolvimento / produção). Pareceu-me o mais conveniente, além disso, você pode alterar parcialmente o código durante o desenvolvimento e verificar a operação dos módulos em produção.
ssl - existem certificados salvos anteriormente nas pastas localhost e myapp
.babelrc
{ "presets": [ [ "@babel/preset-env", { "targets": { "browsers": [">0.25%", "not ie 11", "not op_mini all"] } } ], "@babel/preset-react" ], "plugins": [ "babel-plugin-styled-components", "@babel/plugin-transform-runtime" ] }
Configurações para criar nosso react_bundle com suporte ao navegador usado por mais de 0,25% dos usuários.
client.js
import React from 'react' import { render } from 'react-dom' render(<div>!!</div>, document.getElementById('cookies'))
Renderiza nosso frontend em uma div com uma tag de cookie.
pm2-watch.json - permite executar o servidor com o comando "npm run server" na hospedagem, acompanhando as alterações no código e reinicializando automaticamente.
webpack.config.js
Construtor de aplicativos do reator:
const webpack = require('webpack'), path = require('path'), BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin module.exports = (env, argv) => { let prod = argv.mode == 'production' let config = { entry: './client.js', output: { path: path.resolve('./public'), filename: 'react_bundle.js' }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, loader: 'babel-loader' }, { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] }, resolve: { alias: { client: path.resolve('./client/shared'), public: path.resolve('./public') } }, plugins: [ argv.analyze ? new BundleAnalyzerPlugin() : false, prod ? new webpack.optimize.AggressiveMergingPlugin() : false, new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /ru/) ].filter(Boolean), optimization: { minimize: prod ? true : false }, performance: { hints: false } } return config }
Em resumo, ele abre o arquivo client.js e tudo o que está dentro dele, coletando react_bundle e colocando-o na pasta pública, de onde será carregado através do arquivo index.html aberto.
server.js
const isProd = require('./public/isProd'), fs = require('fs'), log = require('./server/logger'), path = require('path')
Pasta do servidor
Aqui reside o back-end e todas as formas.
logger.js - dependendo do ambiente, os logs do isProd no console ou no errors.log
'use strict' const pino = require('pino'), isProd = require('../public/isProd') let logOptions = isProd ? { level: 'warn',
servidor / api /
open.js - adicione nossos caminhos aqui.
'use strict' module.exports = function(fastify, options, next) { fastify.route({ method: 'GET', url: '/', handler: async (req, res) => { res.send('api / route') } }) fastify.route({ method: 'GET', url: '/hi', handler: async (req, res) => { res.send('api / route hi') } }) next() }
Depois de configurar e verificar tudo no Localhost, apenas carregamos tudo no github e, a partir daí, o git pull para a hospedagem. Tudo o que precisa ser feito na hospedagem é instalar os módulos node.js com o comando “npm i” e criar o arquivo isProd.js
SSL atualizado automaticamente
Ao comprar um domínio e vinculá-lo à nuvem IP, um exemplo de
instruções para o REG.RU , você pode instalar SSL gratuito atualizado automaticamente no servidor para o site funcionar via https.
Nosso servidor funciona sem o nginx. Podemos precisar no futuro como um balanceador de carga ou um servidor HTTP mais rápido para distribuir arquivos estáticos, mas até agora não vejo a necessidade. Ainda não precisamos do balanceamento de carga, mas não encontrei comparações quanto à velocidade de distribuição de estática.
Antes de instalar na pasta ssl, crie a pasta .well conhecida e nela acme-challenge. Acontece que /opt/myapp/ssl/.well-known/acme-challenge
Para instalar o SSL atualizado automaticamente em um servidor com node.js sem nginx
, clique no link . Por sua vez, execute os comandos no console de hospedagem:
sudo apt-get update sudo apt-get install software-properties-common sudo add-apt-repository universe sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install certbot sudo certbot certonly
Selecionamos o segundo método de verificação, que colocará um arquivo específico na pasta /opt/myapp/ssl/.well-known/acme-challenge e, após confirmar o proprietário do servidor, ele será excluído.
Indicamos nosso domínio mediante solicitação, por exemplo: "example.com" e o caminho para a pasta ssl do nosso aplicativo (o servidor está configurado para fornecer o arquivo criado pelo bot) "/ opt / myapp / ssl".
O bot irá configurar a própria tarefa cron para renovar o certificado antes de expirar em 90 dias.
Eu não achava que demoraria tanto tempo para escrever tudo, às 4 horas da manhã eu já podia perder alguma coisa:
Interessante é a opinião dos hebraicos e especialistas que dominaram essa tela ou leram alguns pontos individuais. Como é organizado o seu ciclo de desenvolvimento? Existem pontos em que eu estou enganado ou fazendo a coisa errada?