<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Renan Santos</title>
    <description>The latest articles on DEV Community by Renan Santos (@renanssantos1).</description>
    <link>https://dev.to/renanssantos1</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F187849%2F3b47ba18-0239-4d5a-9796-3ae9ec7acd72.png</url>
      <title>DEV Community: Renan Santos</title>
      <link>https://dev.to/renanssantos1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/renanssantos1"/>
    <language>en</language>
    <item>
      <title>Gerenciamento de senhas com Kubernetes ☸️🐳</title>
      <dc:creator>Renan Santos</dc:creator>
      <pubDate>Fri, 03 Nov 2023 15:16:04 +0000</pubDate>
      <link>https://dev.to/renanssantos1/gerenciamento-de-senhas-com-kubernetes-1bdg</link>
      <guid>https://dev.to/renanssantos1/gerenciamento-de-senhas-com-kubernetes-1bdg</guid>
      <description>&lt;h2&gt;
  
  
  Como Trabalhar com Senhas Criptografadas Dentro do Kubernetes
&lt;/h2&gt;

&lt;p&gt;Quando se trata de gerenciamento de senhas e manipulação de dados sensíveis, todo cuidado é pouco, e no Kubernetes não é diferente. Uma má prática, ou até mesmo um esquecimento, é armazená-las em 'plain_text' (texto simples). Esses tipos de gerenciamentos podem e irão causar muita dor de cabeça se caírem em mãos erradas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gerenciamento de Senhas com Kubernetes
&lt;/h3&gt;

&lt;p&gt;O Kubernetes trabalha de maneira muito inteligente com o gerenciamento de senhas, utilizando criptografia eficaz que funciona para a maioria das aplicações. Além disso, é fácil gerenciá-las em ambientes de nuvem, como &lt;strong&gt;AWS, GCP, Azure&lt;/strong&gt;, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que são Secrets
&lt;/h3&gt;

&lt;p&gt;O objetivo dos &lt;strong&gt;'Secrets'&lt;/strong&gt; (segredos) é armazenar com segurança uma ou mais informações dentro do seu cluster. Um bom exemplo de uso é o armazenamento de chaves de API, chaves de banco de dados e até mesmo uma chave SSH, ou qualquer tipo semelhante de informação secreta que não queremos que o mundo externo tenha fácil acesso.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuração
&lt;/h4&gt;

&lt;p&gt;A comunidade Kubernetes recomenda sempre usar um arquivo de configuração e permitir que o próprio Kubernetes administre as coisas para nós. No entanto, para a senha, criaremos um arquivo e utilizaremos um comando imperativo que criará o segredo para nós. Ao utilizar essa abordagem, quando abstrairmos as configurações para o ambiente de produção, também precisamos garantir que criemos outro segredo manualmente no ambiente.&lt;/p&gt;

&lt;p&gt;Comando padrão:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;create&lt;/code&gt;: cria um novo arquivo de configuração.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;secret&lt;/code&gt;: tipo do arquivo de configuração.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;generic&lt;/code&gt;: indica que estamos salvando um número arbitrário de chaves e valores.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/pt-br/docs/tasks/configmap-secret/managing-secret-using-kubectl/"&gt;Leia mais 🔗&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;secret_name&lt;/code&gt;: A propriedade &lt;code&gt;name&lt;/code&gt; é como nos referimos ao segredo em algum momento futuro, se desejarmos consumi-lo e utilizá-lo dentro de uma configuração de POD.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--from-literal&lt;/code&gt;: Significa que escreveremos as informações a serem armazenadas dentro do segredo, em vez de tentar gravar as informações dentro de um arquivo e depois carregá-las.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;key=value&lt;/code&gt;: Codificação da senha. No exemplo que utilizaremos, será a referência da senha do banco de dados &lt;code&gt;PGPASSWORD=senha_do_banco&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observação:&lt;/strong&gt; &lt;code&gt;PGPASSWORD&lt;/code&gt; é uma referência da senha, caso haja a necessidade de utilizá-la no futuro. &lt;em&gt;"Ei, Kubernetes, pegue aquela senha com a referência &lt;code&gt;PGPASSWORD&lt;/code&gt; para mim?"&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Comando Completo
&lt;/h3&gt;

&lt;p&gt;Input:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
kubectl create secret generic pgpassword --from-literal PGPASSWORD=12345asdf&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
secret/pgpassword created&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Para verificar os segredos que criamos:&lt;/p&gt;
&lt;h3&gt;
  
  
  Utilização da Senha como Variáveis de Ambiente
&lt;/h3&gt;

&lt;p&gt;📁 Arquivo &lt;code&gt;api.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PGPASSWORD&lt;/span&gt;
    &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pgpassword&lt;/span&gt;
        &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PGPASSWORD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📁 Arquivo banco.yaml:&lt;br&gt;
POSTGRES_PASSWORD: de acordo com a nova atualização do Postgres, a variável de senha é utilizada com underscore &lt;code&gt;POSTGRES_PASSWORD&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD&lt;/span&gt;
    &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pgpassword&lt;/span&gt;
        &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PGPASSWORD&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Aplicar as configurações&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Input --&amp;gt;
kubectl apply -f k8s

&amp;lt;!-- Input --&amp;gt;
filename_config configured
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse foi um tutorial básico de como iniciar e trabalhar com senhas dentro do kubernetes, deixo o link para a documentação de referenca, clicando &lt;a href="https://kubernetes.io/pt-br/docs/concepts/configuration/secret/"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Até logo.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>docker</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Zero to Hero 🚀 - Como criar uma Aplicação Fullstack</title>
      <dc:creator>Renan Santos</dc:creator>
      <pubDate>Tue, 31 Oct 2023 19:33:55 +0000</pubDate>
      <link>https://dev.to/renanssantos1/zero-to-hero-como-criar-uma-aplicacao-fullstack-2g6h</link>
      <guid>https://dev.to/renanssantos1/zero-to-hero-como-criar-uma-aplicacao-fullstack-2g6h</guid>
      <description>&lt;h2&gt;
  
  
  Como criar sua primeira aplicação fullstack com Docker.
&lt;/h2&gt;

&lt;p&gt;Organizar uma aplicação completa do zero, pode ser uma tarefa bastante complicada no começo, devido a alta quantidade de maneiras de resolver o mesmo problema. Muitos programadores ficam perdidos por onde começar, &lt;strong&gt;principalmente os iniciantes&lt;/strong&gt;, focam em tecnologia, quando oque é uma das coisas mais legais, é colocar a mão na massa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fa4xEwxA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i63zi8fxtexjnd2th1bm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fa4xEwxA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i63zi8fxtexjnd2th1bm.png" alt="Show me the code" width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Porque utilizar Docker?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Com docker é possivel abstrair todo o ambiente e acoplar somente em um local, sendo facilmente utilizado&lt;br&gt;
para coloca-lo em produção, ou colocar para funcionar em um projeto do amigo dev. Além disso não precisamos&lt;br&gt;
instalar diversos pacotes dentro da nossa maquina, já que o próprio emula esse ambiente pra gente. Alguns benefícios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fácil instalação&lt;/li&gt;
&lt;li&gt;fácil deploy&lt;/li&gt;
&lt;li&gt;versionamento de build com docker hub&lt;/li&gt;
&lt;li&gt;pode ser integrado com pipelines&lt;/li&gt;
&lt;li&gt;evita instalar N Versões da aplicação na própria máquina&lt;/li&gt;
&lt;li&gt;fácil reciprocidade da comunidade&lt;/li&gt;
&lt;li&gt;receita de bolo&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  *&lt;em&gt;Como organizar a aplicação: *&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Primeiro de tudo iremos escrever nossa receita &lt;strong&gt;docker&lt;/strong&gt; onde a mesma irá se encarregar de praticamente tudo, optei por escolher o banco de dados &lt;strong&gt;Postgres&lt;/strong&gt;, devido ser bastante fácil de mexer, o código é aberto, e tem muito conteudo na web. O projeto está divido em 4 camadas. Sendo elas, client onde será usado um framework React (pode ser qualquer um, como vue, angular etc..), server com node + express, redis, e banco de dados. *&lt;em&gt;Nginx para chavear as portas da aplicação e servir o frontend e o backend em portas dinamicas. *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Na raiz do projeto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3'
services:
  postgres:
    image: "postgres:latest"
    environment:
      - POSTGRES_PASSWORD=postgres_password
  redis:
    image: "redis:latest"
  nginx:
    restart: always
    build:
      dockerfile: Dockerfile.dev
      context: ./nginx
    ports:
      - "3050:80"
    depends_on:
      - api
      - client       
  api:
    build:
      dockerfile: Dockerfile.dev
      context : ./server
    volumes:
      - /app/node_modules 
      - ./server:/app  
    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - PGUSER=postgres
      - PGHOST=postgres
      - PGDATABASE=postgres
      - PGPASSWORD=postgres_password
      - PGPORT=5432  
  client:
    build:
      dockerfile: Dockerfile.dev
      context: ./client
    volumes:
      - /app/node_modules
      - ./client:/app 
    environment:
      - WDS_SOCKET=0   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note que na receita Dockerfile acima estamos fazendo a referencia para seus devidos arquivos &lt;strong&gt;Dockerfile.dev&lt;/strong&gt;&lt;br&gt;
de cada serviço. Estou optando pelo arquivo .dev, pois assim apos o desenvolvedor buildar, podemos fazer versionamento e subir o build com uma esteira de deploy para produção.&lt;/p&gt;

&lt;p&gt;Configuração do servidor:&lt;/p&gt;

&lt;p&gt;📁 ./server/Dockerfile.dev&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:14.14.0-alpine
WORKDIR '/app'
COPY package.json .
RUN npm install 
COPY . .
CMD ["npm", "run", "dev"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📁 ./server/index.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const keys = require('./keys')

const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const { Pool } = require('pg')
const redis = require('redis')

const app = express()
app.use(cors())
app.use(bodyParser.json())

const pgClient = new Pool({
  user: keys.pgUser,
  port: keys.pgPort,
  host: keys.pgHost,
  database: keys.pgDataBase,
  password: keys.pgPassword,
})

pgClient.on("connect", (client) =&amp;gt; {
  client
    .query("CREATE TABLE IF NOT EXISTS values (number INT)")
    .catch((err) =&amp;gt; console.error(err));
});

const redisClient = redis.createClient({
  host: keys.redisHost,
  port: keys.redisPort,
  retry_strategy: () =&amp;gt; 1000
})

const redisPublisher = redisClient.duplicate()

// Express route handlers
app.get('/', (req, res) =&amp;gt; {
  res.send('Hi')
})

app.get('/values/all', async (req, res) =&amp;gt; {
  const values = await pgClient.query('SELECT * FROM values')

  res.send(values.rows)
})

app.get('/values/current', async (req, res) =&amp;gt; {
  redisClient.hgetall('values', (err, values) =&amp;gt; {
    res.send(values)
  })
})

app.post('/values', async (req, res) =&amp;gt; {
  const index = req.body.index

  if (parseInt(index) &amp;gt; 40) {
    return res.status(422).send({ message: 'Index to high' })
  }

  redisClient.hset('values', index, 'Nothing yet!')
  redisPublisher.publish('insert', index)

  pgClient.query('INSERT INTO values(number) VALUES($1)', [index])

  res.send({ working: true })
})


app.listen(5000, () =&amp;gt; {
  console.info('app on listening on port 5000!')
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O script acima é responsável por iniciar o backend, como trata-se de somente um tutorial&lt;br&gt;
optei por deixar todo o código em um arquivo para fácil entendimento, fique a vontade para quebra-lo camadas e arquivos separados, como service, e controllers (recomendado).&lt;/p&gt;

&lt;p&gt;📁 ./server/keys.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    redisHost: process.env.REDIS_HOST,
    redisPort: process.env.REDIS_PORT,
    pgUser: process.env.PGUSER,
    pgHost: process.env.PGHOST,
    pgDataBase: process.env.PGDATABASE,
    pgPassword: process.env.PGPASSWORD,
    pgPort: process.env.PGPORT
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apos a instalação de todos os pacotes, ainda não sera possivel visualizar a aplicação no browser, pois teriamos que fazer uma configuração do nosso proxy nginx, onde o mesmo fica responsável por expor as portas da aplicação&lt;br&gt;
para o mundo externo.&lt;/p&gt;

&lt;p&gt;📁 ./nginx/default.conf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;upstream client {
  server client:3000;
}

upstream api {
  server api:5000;
}

server {
  listen 80;

  location / {
    proxy_pass http://client;
  }

  location /api {
    rewrite /api/(.*) /$1 break;
    proxy_pass http://api;
  }

  location /ws {
    proxy_pass http://client;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A configuração acima, acredito e julgo que seja muito ideal pois o frontend não irá precisar bater um endpoint separada pois tudo que começa com [api] ja temos a referencia que é a nosso serviço, logo oque vier depois disso trata-se somente do backend. Assim facilitando caso optar por deploy da aplicação em ambiente de produção, poupando tempo em troca de ip ou URI. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;, &lt;em&gt;como trata-se de um tutorial deixarei a parte do frontend e escolha do programador,  onde somente mostrarei apenas o arquivo de proxy que ficará dentro da pasta do client. Pode ser usado qualquer tipo de framework frontend, até mesmo js puro com webpack. Desde que seja adicionado o arquivo de configuração do nginx, também fazendo as devidas correções para ouvir o arquivo de html do projeto.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;📁 ./client/nginx/default.conf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 3000;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Como rodar o projeto 🚀&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O comando docker abaixo será responsável por subir todo o nosso projeto, sendo possivel acessá-lo &lt;br&gt;
na porta 3050, para o frontend, e 5000 (/api/)para o backend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker compose -f docker-compose-dev.yml up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Link do repositório &lt;a href="https://gitlab.com/renandasilvasantos557/fullstackdockerapp/-/tree/master?ref_type=heads"&gt;Gitlab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👨‍💻 Volte sempre...&lt;/p&gt;

</description>
      <category>node</category>
      <category>redis</category>
      <category>docker</category>
      <category>react</category>
    </item>
  </channel>
</rss>
