Bem-vindo ao guia sobre como automatizar a implantação de um aplicativo de postagem de blog usando GitHub Actions, Node.js,
CouchDB e Aptible.
Este tutorial abrangente irá guiá-lo na construção, implantação e gerenciamento de um aplicativo de postagem de blog usando as ferramentas e tecnologias acima.
Mas primeiro, deixe-me dar uma breve visão geral do aplicativo Blogpost , o que ele faz e seus principais componentes. O aplicativo Blogpost é um aplicativo da web que permite aos usuários criar e compartilhar postagens de blog.
Os usuários podem escrever, editar, excluir e visualizar postagens de outros usuários. O aplicativo usa Node.js como back-end, CouchDB como banco de dados e GitHub Actions como ferramenta de integração e implantação contínua.
Por que eu escolhi estes? Bem, existem muitos motivos, mas aqui estão alguns dos principais:
- Node.js é um ambiente de execução JavaScript rápido, escalonável e fácil de usar que pode ser executado em várias plataformas. Possui muitas bibliotecas e frameworks para desenvolvimento web, como o Express, um framework de aplicação web minimalista e flexível que utilizarei neste projeto.
- CouchDB é um sistema de banco de dados NoSQL de código aberto confiável, seguro e poderoso. É um banco de dados orientado a documentos que usa JSON para armazenar dados.
- GitHub Actions é uma ferramenta flexível, conveniente e integrada que permite automatizar fluxos de trabalho para seus repositórios GitHub. Ele também possui muitas ações predefinidas que você pode usar ou personalizar de acordo com suas necessidades, como a ação Aptible Deploy, que usarei neste projeto para implantar o aplicativo no Aptible.
- Aptible é uma plataforma baseada em nuvem para implantação e gerenciamento de aplicativos em contêineres, fornecendo recursos fáceis de provisionamento, dimensionamento e monitoramento.
Pré-requisitos
Antes de iniciar a jornada de desenvolvimento, é essencial configurar as ferramentas e tecnologias necessárias.
- Node.js: certifique-se de que o Node.js esteja instalado em sua máquina.
- CouchDB: verifique se o CouchDB está instalado e em execução no seu sistema.
- Experiência em Node.js e JavaScript: possua um conhecimento sólido dos fundamentos de Node.js e JavaScript.
- Docker: instale e execute o Docker em sua máquina.
- Conta Aptible: Crie uma conta Aptible e familiarize-se com a implantação de um aplicativo básico.
- Conta Docker Cloud: Adquira uma conta Docker Cloud para hospedar seus aplicativos.
Desenvolvendo o aplicativo Blogpost
1: Configure seu projeto Node.js.
- Crie um diretório de projeto para seu aplicativo de postagem de blog.
- Inicialize um projeto Node.js usando npm:
npm init -y
- Instale o framework Express.js, que servirá de base para o backend:
npm install express nano
Etapa 2: configurar o CouchDB
- Certifique-se de que o CouchDB esteja instalado e em execução. Você pode acessar o CouchDB através do seu navegador em
http://127.0.0.1:5984/_utils/
.
Etapa 3: crie seu aplicativo Node.js
- Crie um arquivo
blog.js
no diretório do seu projeto.
- Inicialize o Express e conecte-o ao CouchDB:
const express = require("express"); const nano = require("nano")("http://admin:[email protected]:5984"); const app = express(); const port = 3000; // Middleware to parse JSON data app.use(express.json()); // async function asyncCall() { // // await nano.db.destroy("alice"); // await nano.db.create("blogposts"); // const db = nano.use("blogposts"); // return response; // } // asyncCall(); const db = nano.use("blogposts");
Este código define endpoints de API para criar, recuperar, atualizar e excluir postagens de blog usando um banco de dados CouchDB.
// Create a new blog post app.post("/posts", async (req, res) => { const { title, description, author } = req.body; try { const doc = await db.insert({ title, description, author, createdAt: new Date(), updatedAt: new Date(), }); res.json({ id: doc.id, rev: doc.rev }); } catch (err) { console.error(err); res.status(500).send("Error creating post"); } }); // Get all blog posts app.get("/posts", async (req, res) => { try { const docs = await db.list({ include_docs: true }); res.json(docs.rows); } catch (err) { console.error(err); res.status(500).send("Error retrieving posts"); } }); // Get a specific blog post app.get("/posts/:id", async (req, res) => { const { id } = req.params; try { const doc = await db.get(id); res.json(doc); } catch (err) { console.error(err); res.status(404).send("Post not found"); } }); // Update a blog post app.put("/posts/:id", async (req, res) => { const { id } = req.params; const { title, description } = req.body; try { await db.insert({ _id: id, title, description, updatedAt: new Date(), }); res.json({ message: "Post updated successfully" }); } catch (err) { console.error(err); res.status(500).send("Error updating post"); } }); // Delete a blog post app.delete("/posts/:id", async (req, res) => { const { id } = req.params; try { await db.destroy(id); res.json({ message: "Post deleted successfully" }); } catch (err) { console.error(err); res.status(500).send("Error deleting post"); } }); app.listen(port, () => { console.log(`Blogpost app listening on port ${port}`); });
Testando localmente:
Testes completos são cruciais para garantir a funcionalidade e robustez do seu projeto. Aqui está um exemplo de documentação da API para orientar seu processo de teste:
Documentação da API
URL base :
Supondo que seu servidor esteja rodando localmente na porta 3000, a URL base da sua API seria:
http://localhost:3000
Pontos finais da API:
Crie uma nova postagem no blog
Ponto final :
POST /posts
Descrição : Cria uma nova postagem no blog.
Corpo da solicitação :
{ "title": "String", "description": "String", "author": "String" }
Exemplo :
POST http://localhost:3000/posts { "title": "Sample Title", "description": "Sample Description", "author": "John Doe" }
Obtenha todas as postagens do blog
Ponto final :
GET /posts
Descrição : Recupera todas as postagens do blog.
Resposta :
[ { "id": "String", "key": "String", "value": { "rev": "String" }, "doc": { "_id": "String", "_rev": "String", "title": "String", "description": "String", "author": "String", "createdAt": "Date", "updatedAt": "Date" } } ]
Exemplo :
GET http://localhost:3000/posts
Obtenha uma postagem específica no blog
Ponto final :
GET /posts/:id
Descrição : recupera uma postagem de blog específica por seu ID.
Parâmetros :
-
id
: ID da postagem do blog.
-
Resposta :
{ "_id": "String", "_rev": "String", "title": "String", "description": "String", "author": "String", "createdAt": "Date", "updatedAt": "Date" }
Exemplo :
GET http://localhost:3000/posts/your-post-id
Atualizar uma postagem do blog
Ponto final :
PUT /posts/:id
Descrição : atualiza uma postagem específica do blog por seu ID.
Parâmetros :
-
id
: ID da postagem do blog.
-
Corpo da solicitação :
{ "title": "String", "description": "String" }
Exemplo :
PUT http://localhost:3000/posts/your-post-id { "title": "Updated Title", "description": "Updated Description" }
Excluir uma postagem do blog
Ponto final :
DELETE /posts/:id
Descrição : exclui uma postagem específica do blog por seu ID.
Parâmetros :
-
id
: ID da postagem do blog.
-
Exemplo :
DELETE http://localhost:3000/posts/your-post-id
Substitua your-post-id
por um ID real da postagem do blog ao testar as solicitações GET
, PUT
e DELETE
.
Etapa 4: Dockerize seu aplicativo Node.js
Você precisa ter uma conta Docker Hub. Se você ainda não criou um, cadastre-se no Docker Hub.
Certifique-se de ter o Docker instalado e em execução em sua máquina local.
Etapas para enviar aplicativo Dockerizado para Docker Hub:
- Crie um
Dockerfile
no diretório raiz do seu projeto Node.js.
# Use an official Node.js runtime as the base image FROM node:16 # Set the working directory in the container WORKDIR /usr/src/app # Copy package.json and package-lock.json to the working directory COPY package*.json ./ # Install app dependencies RUN npm install # Copy the rest of the application files to the working directory COPY . . # Expose the port the app runs on EXPOSE 3000 # Define the command to run the app CMD ["node", "blog.js"]
Marque sua imagem Docker: abra seu terminal/prompt de comando e navegue até o diretório raiz de seu aplicativo Node.js, onde seu Dockerfile está localizado.
Execute o seguinte comando para construir sua imagem Docker e marque-a com seu nome de usuário do Docker Hub e o nome do repositório desejado:
docker build -t your-docker-username/blogpost-app:latest .
Substitua your-docker-username
pelo nome de usuário do Docker Hub e blogpost-app
pelo nome do repositório desejado.
Você receberá uma resposta semelhante a esta:
[+] Building 1.1s (10/10) FINISHED docker:desktop-linux => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 489B 0.0s => [internal] load metadata for docker.io/library/node:16 1.0s => [1/5] FROM docker.io/library/node:16@sha256:f77a1aef2da8d83e45ec990f45df50f1a286c5fe8bbfb8c6e4246c6389705c0b 0.0s => [internal] load build context 0.0s => => transferring context: 45.31kB 0.0s => CACHED [2/5] WORKDIR /usr/src/app 0.0s => CACHED [3/5] COPY package*.json ./ 0.0s => CACHED [4/5] RUN npm install 0.0s => CACHED [5/5] COPY . . 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:c5f046a9b99389aea6bf3f503e9b05cce953daf1b3f77ee5fb3f7469dc36c709 0.0s => => naming to docker.io/wise4rmgod/blogpost-app:latest
- Faça login no Docker Hub: Autentique seu cliente Docker com sua conta Docker Hub executando o seguinte comando:
docker login
Digite seu nome de usuário e senha do Docker Hub quando solicitado.
Authenticating with existing credentials... Login Succeeded
- Envie a imagem do Docker para o Docker Hub: uma vez logado, envie a imagem do Docker marcada para o repositório do Docker Hub usando o seguinte comando:
docker push your-docker-username/blogpost-app:latest
Este comando carrega sua imagem local para Docker Hub no repositório especificado.
Verifique o Push: Vá para sua conta Docker Hub na web e navegue até seu repositório para confirmar se sua imagem Docker foi enviada com sucesso.
aptible deploy --app reactgame --docker-image wise4rmgod/blogpost-app --private-registry-username wise4rmgod --private-registry-password H$(_tS+W~ZBST63
Etapa 5: implantação adequada
Este tutorial pressupõe que você tenha um conhecimento básico de configuração de ambiente , aplicativo , endpoint e banco de dados na plataforma Aptible. O tutorial utiliza CouchDB como banco de dados e emprega Direct Docker para implantação.
- Faça login no Aptible via CLI usando o seguinte comando:
aptible login
Você será solicitado a inserir seu e-mail e senha. Se for bem-sucedido, você receberá uma resposta semelhante a esta:
Token written to /Users/wisdomnwokocha/.aptible/tokens.json This token will expire after 6 days, 23 hrs (use --lifetime to customize)
- Agora, implante seu aplicativo usando o seguinte comando:
Sintaxe:
aptible deploy --app <app name> --docker-image <docker image in cloud>
Aqui está um exemplo de comando:
aptible deploy --app reactgame --docker-image wise4rmgod/blogpost-app
Você receberá uma resposta semelhante à seguinte:
INFO -- : Starting App deploy operation with ID: 61135861 INFO -- : Deploying without git repository INFO -- : Writing .aptible.env file... INFO -- : Fetching app image: wise4rmgod/blogpost-app... INFO -- : Pulling from wise4rmgod/blogpost-app INFO -- : 26ee4ff96582: Pulling fs layer INFO -- : 446eab4103f4: Pulling fs layer INFO -- : 2e3c22a0f840: Pulling fs layer INFO -- : a7ab8ad9b408: Pulling fs layer INFO -- : 3808fdf0c601: Pulling fs layer INFO -- : ab9e4075c671: Pulling fs layer INFO -- : 362360c8cef6: Pulling fs layer INFO -- : 928b5d11ac66: Pulling fs layer INFO -- : dc87e077ac61: Pulling fs layer INFO -- : f108e80f4efc: Pulling fs layer INFO -- : 84ac53840ac8: Pulling fs layer INFO -- : e81f21b79a1f: Pulling fs layer INFO -- : 2e3c22a0f840: Downloading: 523 KB / 49.8 MB INFO -- : 446eab4103f4: Downloading: 173 KB / 16.6 MB INFO -- : 26ee4ff96582: Downloading: 483 KB / 47 MB INFO -- : 2e3c22a0f840: Downloading: 25.7 MB / 49.8 MB INFO -- : a7ab8ad9b408: Downloading: 528 KB / 175 MB INFO -- : ab9e4075c671: Downloading: 355 KB / 33.4 MB INFO -- : a7ab8ad9b408: Downloading: 35.3 MB / 175 MB INFO -- : 26ee4ff96582: Pull complete INFO -- : 446eab4103f4: Pull complete INFO -- : 2e3c22a0f840: Pull complete INFO -- : a7ab8ad9b408: Downloading: 71.2 MB / 175 MB INFO -- : a7ab8ad9b408: Downloading: 106 MB / 175 MB INFO -- : a7ab8ad9b408: Downloading: 142 MB / 175 MB INFO -- : a7ab8ad9b408: Pull complete INFO -- : 3808fdf0c601: Pull complete INFO -- : ab9e4075c671: Pull complete INFO -- : 362360c8cef6: Pull complete INFO -- : 928b5d11ac66: Pull complete INFO -- : dc87e077ac61: Pull complete INFO -- : f108e80f4efc: Pull complete INFO -- : 84ac53840ac8: Pull complete INFO -- : e81f21b79a1f: Pull complete INFO -- : Digest: sha256:de9d04d069ca89ebdb37327365a815c88cd40d90cbc5395cc31c351fff1206dd INFO -- : Status: Downloaded newer image for wise4rmgod/blogpost-app:latest INFO -- : No Procfile found in git directory or /.aptible/Procfile found in Docker image: using Docker image CMD INFO -- : No .aptible.yml found in git directory or /.aptible/.aptible.yml found in Docker image: no before_release commands will run INFO -- : Pushing image dualstack-v2-registry-i-0a5ec8cff8e775b34.aptible.in:46022/app-63213/72184c41-7dc6-4313-b10e-749125f72577:latest to private Docker registry... INFO -- : The push refers to repository [dualstack-v2-registry-i-0a5ec8cff8e775b34.aptible.in:46022/app-63213/72184c41-7dc6-4313-b10e-749125f72577] INFO -- : dd387bc6b362: Pushed INFO -- : 586bd9d5efcf: Pushed INFO -- : 8ae0c889ca84: Pushed INFO -- : c91ec53bcc27: Pushing: 522 KB / 93.6 MB INFO -- : aec897bac4f0: Pushed INFO -- : 0ead224631d3: Pushed INFO -- : ad3b30eb29d3: Pushing: 542 KB / 444 MB INFO -- : 2a7587eb01b6: Pushing: 544 KB / 137 MB INFO -- : be36d2a441aa: Pushed INFO -- : 03f6e3800bbe: Pushed INFO -- : a10e482288d1: Pushing: 338 KB / 30.7 MB INFO -- : f9cfc9f6b603: Pushing: 513 KB / 103 MB INFO -- : c91ec53bcc27: Pushing: 31.3 MB / 93.6 MB INFO -- : c91ec53bcc27: Pushing: 62.7 MB / 93.6 MB INFO -- : ad3b30eb29d3: Pushing: 44.5 MB / 444 MB INFO -- : 2a7587eb01b6: Pushing: 34.4 MB / 137 MB INFO -- : a10e482288d1: Pushed INFO -- : ad3b30eb29d3: Pushing: 88.9 MB / 444 MB INFO -- : f9cfc9f6b603: Pushing: 34.6 MB / 103 MB INFO -- : 2a7587eb01b6: Pushing: 68.9 MB / 137 MB INFO -- : ad3b30eb29d3: Pushing: 133 MB / 444 MB INFO -- : f9cfc9f6b603: Pushing: 70.2 MB / 103 MB INFO -- : c91ec53bcc27: Pushed INFO -- : 2a7587eb01b6: Pushing: 103 MB / 137 MB INFO -- : ad3b30eb29d3: Pushing: 178 MB / 444 MB INFO -- : ad3b30eb29d3: Pushing: 224 MB / 444 MB INFO -- : 2a7587eb01b6: Pushed INFO -- : f9cfc9f6b603: Pushed INFO -- : ad3b30eb29d3: Pushing: 270 MB / 444 MB INFO -- : ad3b30eb29d3: Pushing: 312 MB / 444 MB INFO -- : ad3b30eb29d3: Pushing: 355 MB / 444 MB INFO -- : ad3b30eb29d3: Pushing: 401 MB / 444 MB INFO -- : ad3b30eb29d3: Pushed INFO -- : latest: digest: sha256:de9d04d069ca89ebdb37327365a815c88cd40d90cbc5395cc31c351fff1206dd size: 2841 INFO -- : Pulling from app-63213/72184c41-7dc6-4313-b10e-749125f72577 INFO -- : Digest: sha256:de9d04d069ca89ebdb37327365a815c88cd40d90cbc5395cc31c351fff1206dd INFO -- : Status: Image is up to date for dualstack-v2-registry-i-0a5ec8cff8e775b34.aptible.in:46022/app-63213/72184c41-7dc6-4313-b10e-749125f72577:latest INFO -- : Image app-63213/72184c41-7dc6-4313-b10e-749125f72577 successfully pushed to registry. INFO -- : STARTING: Register service cmd in API INFO -- : COMPLETED (after 0.28s): Register service cmd in API INFO -- : STARTING: Derive placement policy for service cmd INFO -- : COMPLETED (after 0.15s): Derive placement policy for service cmd INFO -- : STARTING: Create new release for service cmd INFO -- : COMPLETED (after 0.24s): Create new release for service cmd INFO -- : STARTING: Schedule service cmd .. INFO -- : COMPLETED (after 13.49s): Schedule service cmd INFO -- : STARTING: Stop old app containers for service cmd INFO -- : COMPLETED (after 0.0s): Stop old app containers for service cmd INFO -- : STARTING: Start app containers for service cmd INFO -- : WAITING FOR: Start app containers for service cmd INFO -- : WAITING FOR: Start app containers for service cmd INFO -- : COMPLETED (after 18.4s): Start app containers for service cmd INFO -- : STARTING: Delete old containers for service cmd in API INFO -- : COMPLETED (after 0.0s): Delete old containers for service cmd in API INFO -- : STARTING: Commit app containers in API for service cmd INFO -- : COMPLETED (after 0.26s): Commit app containers in API for service cmd INFO -- : STARTING: Commit service cmd in API INFO -- : COMPLETED (after 0.13s): Commit service cmd in API INFO -- : STARTING: Cache maintenance page INFO -- : COMPLETED (after 0.28s): Cache maintenance page INFO -- : STARTING: Commit app in API INFO -- : COMPLETED (after 0.19s): Commit app in API INFO -- : App deploy successful.
- Visite o Aptible Dashboard para confirmar se a implantação foi bem-sucedida.
- Clique na guia Endpoint no painel e salve o endpoint. Isso permitirá que você exponha seu banco de dados à Internet pública.
- Clique em Adicionar endpoint na próxima tela para criar um novo endpoint.
Conclusão
Este tutorial abrangente ajudará você a construir, implantar e gerenciar um aplicativo de postagem de blog com Node.js, CouchDB e Aptible.
Você compreendeu os fundamentos da configuração das ferramentas e tecnologias essenciais, da criação do back-end do aplicativo de postagem do blog, da dockerização do aplicativo, do envio da imagem do Docker para o Docker Hub e da implantação do aplicativo no Aptible.
Parabéns por concluir este tutorial abrangente e por sua jornada no desenvolvimento de aplicativos nativos da nuvem usando o Aptible!