Este Website

Cover

Cover

Áudios



*Conteúdo gerado por IA

Arquitetura Técnica: caiodonalisio.com

Este documento descreve a arquitetura técnica do site caiodonalisio.com, abordando desde a infraestrutura de rede até o pipeline de CI/CD.

Visão Geral

Internet ↓ Cloudflare Tunnel ↓ NGINX → static files ↓ Django/Gunicorn ↓ PostgreSQL ←→ Redis


1. Infraestrutura de Rede

Hardware

O site roda em um single-node Kubernetes cluster hospedado em um mini-PC local. A topologia de rede é a seguinte:

Internet ↓ Mikrotik Router (RouterOS) • Inter-VLAN routing • Firewall per VLAN ↓ trunk port (tagged) Managed Switch (VLAN-aware) • VLAN 10: Doméstica • VLAN 20: Servidores • VLAN 30: IoT ↓ access port (VLAN 20) Mini-PC • Ubuntu Server • K3s single-node

Isolamento via VLAN

O servidor reside em uma VLAN dedicada (VLAN 20), isolada do restante da rede doméstica. O Mikrotik gerencia:

  • Firewall inter-VLAN: a VLAN de servidores não tem acesso à rede doméstica
  • Acesso de gerenciamento: apenas dispositivos específicos da VLAN Principal podem acessar SSH
  • Saída para internet: permitida para o Cloudflare Tunnel estabelecer conexão outbound

Essa segmentação garante que mesmo em caso de comprometimento do servidor, o atacante não teria acesso lateral aos dispositivos domésticos.

Exposição à Internet

Não há port forwarding no roteador. Todo o tráfego de entrada passa pelo Cloudflare Tunnel, que mantém uma conexão outbound persistente com a edge da Cloudflare. Isso elimina a necessidade de:

  • IP público estático
  • Portas abertas no firewall
  • Gerenciamento manual de certificados TLS

2. Kubernetes (K3s)

Cluster

K3s single-node com os seguintes recursos deployados no namespace caiodonalisio:

| Recurso | Réplicas | Função | |---------|----------|--------| | Django/Gunicorn | 2 | Aplicação web | | NGINX | 1 | Reverse proxy + static files | | PostgreSQL | 1 | Banco de dados | | Redis | 1 | Cache + session store | | Cloudflared | 1 | Tunnel daemon |

Storage

Utiliza local-path provisioner do K3s:

  • staticfiles-pvc (2Gi): arquivos estáticos coletados
  • media-pvc (2Gi): uploads e arquivos de mídia
  • postgres-pvc (10Gi): dados do PostgreSQL

Health Checks e Resiliência

O deployment do Django configura:

```yaml readinessProbe: httpGet: path: /health/ port: 3334 initialDelaySeconds: 60 periodSeconds: 15 failureThreshold: 3

livenessProbe: httpGet: path: /health/ port: 3334 initialDelaySeconds: 90 periodSeconds: 30 failureThreshold: 5 ```

Combinado com PodDisruptionBudget (minAvailable: 1) e rolling updates (maxUnavailable: 0, maxSurge: 1), garante zero-downtime durante deploys.

Graceful Shutdown

Pre-stop hook com sleep de 15 segundos permite que conexões em andamento sejam drenadas antes do SIGTERM:

yaml lifecycle: preStop: exec: command: ["/bin/sh", "-c", "sleep 15"]


3. Cloudflare Tunnel

O daemon cloudflared roda como deployment no cluster, configurado via ConfigMap:

yaml tunnel: <tunnel-id> credentials-file: /etc/cloudflared/creds/credentials.json ingress: - hostname: caiodonalisio.com service: http://nginx-svc:80 - hostname: www.caiodonalisio.com service: http://nginx-svc:80 - service: http_status:404

Configurações relevantes:

  • hostNetwork: true: evita problemas de 502 intermitente em clusters single-node
  • dnsPolicy: ClusterFirstWithHostNet: mantém resolução de serviços internos
  • protocol: http2: conexão multiplexada com a edge

4. Stack da Aplicação

Backend

| Componente | Versão | Configuração | |------------|--------|--------------| | Python | 3.12 | - | | Django | 5.1 | Settings modulares (dev/prod/test) | | Gunicorn | - | 4 workers, port 3334 | | Celery | 5.4 | Configurado, workers desabilitados |

Banco de Dados e Cache

| Componente | Versão | Uso | |------------|--------|-----| | PostgreSQL | 16.4 | Persistência principal | | Redis | 7.4.1 | Sessions, cache, Celery broker |

Estrutura Django

``` website/ # Configurações do projeto ├── settings/ │ ├── base.py │ ├── production.py │ └── development.py ├── urls.py # Rotas + endpoint /health/ └── celery.py

blog/ # App principal ├── models.py # Post, PostFile, PostBook ├── views.py # Renderização Markdown └── storage.py # OverwriteStorage customizado

accounts/ # Autenticação └── models.py # CustomUser

pages/ # Páginas estáticas ```

Serving

  • NGINX: reverse proxy, serve /static/ e /media/ diretamente
  • WhiteNoise: fallback para static files com CompressedManifestStaticFilesStorage
  • Gunicorn: WSGI server para requisições dinâmicas

5. CI/CD Pipeline

GitHub Actions

O workflow build_release.yml executa em push para main:

Test (pytest) ↓ Build (docker) ↓ Semantic Release ↓ ├→ Trivy Scan ├→ Push to Docker Hub └→ Update K8s Manifests ↓ Argo CD Auto-Sync

Semantic Versioning

Versões geradas automaticamente via python-semantic-release:

  • fix: → PATCH
  • feat: → MINOR
  • BREAKING CHANGE: → MAJOR

GitOps com Argo CD

Argo CD monitora o diretório k8s/ e aplica mudanças automaticamente:

yaml syncPolicy: automated: prune: true selfHeal: true retry: limit: 5 backoff: duration: 5s maxDuration: 3m factor: 2

O job update-k8s-manifest do GitHub Actions atualiza a tag da imagem em k8s/website.yml, triggering o sync do Argo CD.


6. Containerização

Multi-stage Build

```dockerfile

Stage 1: Builder

FROM python:3.12.4-slim AS builder COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ RUN uv pip compile requirements.txt -o requirements.lock RUN uv pip sync requirements.lock

Stage 2: Runtime

FROM python:3.12.4-slim COPY --from=builder /.venv /.venv COPY . /usr/src/ EXPOSE 3334 CMD ["./entrypoint.sh"] ```

O uso de uv (package manager em Rust) acelera significativamente o build de dependências.

Entrypoint

O entrypoint.sh executa na inicialização do container:

  1. Aguarda PostgreSQL (healthcheck via netcat)
  2. collectstatic
  3. migrate
  4. Sync de arquivos de mídia
  5. Inicia Gunicorn

7. Fluxo Completo de uma Requisição

INTERNET ↓ CLOUDFLARE EDGE (DDoS, SSL) ↓ tunnel MIKROTIK → VLAN 20 → Mini-PC ↓ K3s CLUSTER ↓ cloudflared (hostNetwork) ↓ nginx-svc • /static/ → staticfiles-pvc • /media/ → media-pvc • /* → website-svc ↓ website-svc (2 replicas) Django + Gunicorn :3334 ↓ postgres-svc ←→ redis-svc


8. Considerações de Segurança

| Camada | Medida | |--------|--------| | Rede | Isolamento via VLAN, sem port forwarding | | Edge | Cloudflare DDoS protection, WAF | | Transporte | TLS gerenciado pela Cloudflare | | Cluster | Network policies, secrets para credenciais | | Aplicação | CSRF, secure cookies, ALLOWED_HOSTS | | CI/CD | Trivy scan para vulnerabilidades em imagens |


Última atualização: Janeiro de 2026


Estrutura do Projeto

Abaixo está a árvore de diretórios completa do repositório, gerada automaticamente.







Escrevi este breve texto para registrar a motivação e as experiências que tive por trás da montagem deste website. Espero que seja de interesse daqueles que queiram saber como foi o processo de aprendizado e construção ou planejem fazer algo parecido.

Motivação

Como analista de dados, tenho bastante familiaridade com tarefas como coletar dados da internet, realizar regressões, inferências ou programar processamentos de dados com machine learning utilizando R e Python (com uma pitada de C++). Todas essas atividades podem ser feitas localmente no meu próprio computador, com frequência completamente offline.

Sem dúvida são habilidades importantes de se possuir para o que eu gosto de fazer. No entanto, o mundo está mudando e a tendência crescente, já há algum tempo, é a de se exportar qualquer atividade computacional para a nuvem, isto é, um computador não-local, ao qual temos acesso apenas remotamente. Junto com o mundo, precisamos nós também mudarmos!

Se por um lado estudo ativamente sobre algoritmos, estatística e processamento de dados, ainda restava uma bastante incômoda lacuna no meu conhecimento: como integrar o poder da internet tanto para processar dados quanto para exportar e publicar os meus resultados? Como realizar e publicar inferências e visualização de dados automaticamente sem precisar deixar meu computador pessoal ligado? Estas foram as questões que me motivaram a aprender a lidar com a web.

A maneira mais óbvia de começar a fazer isso é aprender a montar um website, ponderei. Somado ao aprendizado, eu poderia assim ter uma plataforma como trampolim para explorar novas tecnologias, para exposição de projetos e, no espírito open-source da internet e do mundo da programação, compartilhamento dos meus estudos pessoais, sejam em programação, sejam em economia, sejam em história, meus objetos de maior interesse (com a vantagem ainda de me incentivar a realizar uma leitura mais ativa dos livros e artigos que eu escolho ler). Seria possível de fazer isso utilizando simplesmente o Blogspot, um conhecido portal de blogs, ou o GitHub, a principal plataforma de compartilhamento de códigos e projetos, mas eu gostaria de me comunicar também com pessoas de fora do mundo da programação e de uma maneira mais personalizada.

Escolhas

Resta então a questão: como montar um website? Tentando resolver este problema, logo descobri o interessante e diverso mundo do web-development e rapidamente aprendi como, utilizando serviços de servidores compartilhados e designs já prontos livremente disponíveis, é simples e barato criar uma página acessível a qualquer um no mundo. Em 5 minutos um usuário com pouquíssima experiência é capaz de fazê-lo a partir do zero. A primeira versão deste meu website pessoal, do fim de 2020, foi feita desta forma. No entanto, não existe qualquer desafio nisso e páginas com estas ferramentas têm flexibilidade limitada, o que me motivou a ir além.

primeiro site
A primeira versão de www.caiodonalisio.com, quando meu objetivo era aprender a publicar alguma coisa - qualquer coisa - online

Muito resumidamente, um site tem três partes: o back-end, que lida com a lógica e realiza as operação e o processamento de dados de um website, o front-end, responsável pelos elementos fazem a intermediação entre o usuário e o back-end, e o servidor, que armazena e disponibiliza os arquivos para qualquer um com acesso à internet visualizar.

Na linguagem Python, em que geralmente programo, há uma série de bibliotecas extremamente úteis para análise de dados, logo aprendi a lidar com Numpy, Pandas, SciKitLearn e tantas outras essenciais, mas ainda restava uma para mim desconhecida: Django.

Django é uma das grandes e celebradas ferramentas do Python, usada como framework para criar aplicações na web, uma ótima opção para construir o back-end. É bastante robusta e sofisticada, estando presente em produtos como Spotify e Instagram. Ainda que não seja o único pacote com esse fim, me pareceu a escolha natural para que eu pudesse aumentar meu repertório em Python, aprender na prática os fundamentos de web-development e ter um site pessoal.

Este é um site simples e de baixo tráfego, então não haveria necessidade de utilizar uma ferramenta tão poderosa, mas não resisti à oportunidade de aprender este framework tão importante e popular, além de tornar a interação com o banco de dados bastante simples.

Quanto ao front-end, considerei utilizar os bastante apreciados React.js ou Vue.js, que podem ser adaptados para uso com Django. Boa parte da comunidade faz isso, mas como prefiro focar no estudo de ferramentas propriamente de análise de dados, não encontrei boa justificativa para optar por algo além de Django-templates, que já faz parte do framework selecionado, somado de CSS com Bootstrap, que são simples, eficazes e perfeitamente à altura do que eu desejava criar.

This is the first item's accordion body. It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the .accordion-body, though the transition does limit overflow.

This is the second item's accordion body. It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the .accordion-body, though the transition does limit overflow.
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Exemplos de componentes interativos Bootstrap sem modificações, prontos para serem editados e adicionados a um website.


Por fim, permanece apenas a seleção do servidor. Se por um lado todos as outras decisões eram tomadas com critérios técnicos, aqui entra mais uma variável: o custo.

Os enormes e pesados servidores no canto do escritório sempre me causaram uma forte impressão, mas como não tenho dados e processamentos muito volumosos ou confidenciais nem preciso de um novo aquecedor para a minha casa, não haveria por que ter um servidor físico, mesmo um pequeno. A escolha por um servidor na nuvem é muito mais barata, conveniente e óbvia.

No entanto, a nuvem não é uma, mas muitas. O mercado de computação em nuvem cresce rapidamente, e com ele, o número de companhias que oferecem este tipo de serviço. A Google e a Microsoft têm apresentado algumas inovações neste segmento e seus market-shares vêm subindo - A Microsoft Azure é bastante apreciada nas comunidades de machine-learning.

No entanto, a principal plataforma de nuvem utilizada no mundo é a AWS, da Amazon, e me pareceu vantajoso escolhê-la para posteriormente integrar e aprender outros dos incontáveis serviços que a AWS oferece, como o AWS-Lambda e o Sagemaker. Não menos importante é o fato de na minha pesquisa a AWS ter o preço mais competitivo e previsível – o custo costuma ser calculado conforme o uso – do que seus concorrentes, posso dormir com a tranquilidade de não ter que me preocupar com uma fatura surpresa de US$ 90.

cloud market
Crescimento e market share dos principais fornecedores de computação em nuvem.

Com todas as engrenagens devidamente selecionadas, eu tinha um plano! Basta apenas tirá-lo do papel.

Execução

Meu primeiro obstáculo foi descobrir que o mundo web é movido a Linux, um sistema operacional open-source bastante distinto do Windows. Se eu quisesse configurar um servidor para o meu website, eu precisaria reaprender a interagir com as funções mais básicas do computador.

Para a minha sorte, no ano de 2021 isso é mais fácil do que nunca! Se até poucos tempo atrás eu teria que instalar uma máquina virtual ou acomodar um segundo sistema operacional junto ao Windows, o que é bastante trabalhoso, hoje ter um computador com Linux é tão simples quanto instalar o Whatsapp. Avanço tecnológico não significa apenas criar coisas novas, mas também facilitar as antigas.

imagem_store
Microsoft Store, onde qualquer um pode baixar Candy Crush ou um subsistema Linux (na imagem, a distribuição Ubuntu) em qualquer computador comum.

Após brincar e seguir vários guias por muitas horas neste playground local e sem compromissos, eu já me sentia preparado para lidar com o meu servidor na nuvem de verdade.

Antes de fazer isso, no entanto, mais importante ainda era criar o projeto Django em si, o website, no meu próprio computador para depois colocá-lo no servidor. Felizmente esta é uma ferramenta com uma excelente documentação e com muito material para aprender como lidar. embora não seja das coisas mais simples que existem em Python, logo me acostumei a lidar com os templates, views, models e os outros elementos para fazer tudo funcionar conforme o planejado.

Quanto ao design em si, recorri a um dos muitos modelos livremente disponíveis na internet, que modifiquei completamente para acomodar aos meus gostos. Com uma breve introdução e incontáveis tentativas e erros para lidar com a linguagem HTML e CSS (essa é a parte mais trabalhosa e que requer mais ajustes finos), auxiliado pelos elementos prontos do Bootstrap, consegui enfim criar uma webpage com todas as partes necessárias.

Com um site que funcionasse perfeitamente na minha máquina, em uma agradável manhã de sábado consegui aprender a lidar com os básicos de desempenho e segurança do software do servidor, o Nginx, que julguei mais adequado e robusto do que o também popular Apache.

O último passo afinal foi agregar tudo isso. Seguindo rigorosamente guias para fazer isso, instalei o servidor NginX no servidor Linux contratado na nuvem, o qual serve à internet o meu projeto Django (conectado e acoplado a um banco de dados PostgreSQL), utilizando como intermediador o software Gunicorn, e é por meio destas tecnologias que eu disponibilizo este conteúdo.

diagrama_website
Esquema das tecnologias utilizadas neste website.

Sem dúvida realizar todas essas operações agregou muitos conhecimentos ao meu repertório e já me sinto bastante mais confortável lidando com servidores, APIs e a internet em geral. Com um site bem-estruturado, funcional, bonito e agradável de navegar (espero que concorde!), já tenho toda estrutura necessária para adicionar com facilidade mais dos meus projetos, textos e cadernos futuros exatamente da forma como eu projetei e focar nos meus interesses de análise de dados e afins.