home projetos posts
disponível

Arquitetura de um sistema de portfólio

Decisões técnicas, arquitetura e infraestrutura por trás deste site.

Portfólio

O desenvolvimento de um portfólio técnico é algo que eu eventualmente teria que fazer, mas nunca soube ao certo o que colocar em um portfólio de backend. Então por que não construir uma solução própria que por si só, demonstre a capacitação técnica e a aplicacação, sendo o meio e a mensagem da comunicação.

O sistema teve seus requisitos funcionais definidos de modo a permitir:

  • Publicação de projetos com descrição detalhada e histórico de atualizações;
  • Escrita de posts técnicos e de experiências;
  • Devlog continuo de updates de projetos;
  • Painel administrativo próprio;

Stack

A escolha da stack foi orientada pela adequação ao problema a ser resolvido e com a coerência do perfil técnico que o portfólio deve apresentar.

  • GO: Linguagem central do projeto, gerando um binário estático único ao compilar, simplificando o processo de deploy. Não há runtime para instalar, não há dependências de sistema. A escolha é eficiente, confiavel e simples, ideal para operar em uma VPS de baixo custo.
  • Gin: Framework HTTP escolhido por oferecer roteamento de alta performance, suporte nativo a grupo de rotas com middleware encadeado, simplificando a separação entre rotas públicas e rotas protejidas por autenticação. É também um framework já muito bem estabelecido no Go e com amplo suporte da comunidade.
  • PostgreSQL: Banco de dados relacional escolhido por ser um banco robusto, amplamente utilizado e confiavel. Ele trabalha bem com o GORM, que abstrai a maior parte da interação com o banco.
  • GORM: ORM utilizada para a interação com o banco de dados. O AutoMigrate lê as estruturas em Go e cria/atualiza as tabelas automaticamente na inicialização da aplicação, eliminando a necessidade de um sistema de migrations separado. as queries mais específicas são escritas com SQL explícito.
  • HTMX: É utilizado no frontend para requisições parciais. As páginas são renderizadas inteiramente no servidor e entregues como HTML estático, sem framework JS e sem processo de build de assets. Essa escolha gera uma fina camada entre o frontend e o backend, simplificando o desenvolvimento e mantendo um baixo tempo de carregamento. Apesar de não ser a abordagem ideal para aplicações altamente interativas ou com interfaces complexas em tempo real, ela se encaixa bem na proposta deste projeto, priorizando simplicidade arquitetural, performance e facilidade de manutenção.
  • Docker: É utilizado tanto no ambiente de desenvolvimento quanto no de produção, utilizando arquivos Compose separados para cada ambiente. Em desenvolvimento o Air monitora alterações nos arquivos Go e reinicia o servidor automaticamente, sem necessidade de reguild da imagem. Em produção, os containers rodam em uma rede interna isolada. A aplicação não expõe nenhuma porta ao host diretamente, apenas o Caddy é acessível externamente.
  • Caddy: Atua como proxy reverso na proxução. Sua principal vantagem nesse contexto é o gerenciamento automático de certificados TLS via ACME/Let's Encrypt. No atual momento do post ainda não foi configurado o HTTPS, será configurado após a aquisição de um dominio para o sistema.

Arquitetura

O sistema segue o modelo com renderização server-side. Toda a lógica de apresentação ocorre no backend e o cliente recebe o html pronto sem a necessidade de executar o JavaScript. O Javascript foi utilizado apenas para o upload de mídia e o salvamento automático no localstorage para o painel de administrador.

O ponto de entrada é o servidor Go, responsavel por orquestrar toda a sequencia de inicialização: leitura das configurações das variáveis de ambiente, abertura da conexão com o PostgreSQL, execução do AutoMigrate, carregamento dos templates em memória e a inicialização do servidor HTTP.

A engine de template carrega todos os arquivos na inicialização e os mantém em memória durante a execução.

Infraestrutura e Deploy

o ambiente de produção roda em uma VPS Linux com três containers Docker gerenciados pelo compose: a aplicação Go, o PostgreSQL e o Caddy. os containers da aplicação e do banco se comunicam exclusivamente pela rede interna do Docker, nenhuma porta do banco é exposta ao host. O Caddy é o único ponto de entrada externo, realizando o proxy para a aplicação na rede interna.

O processo de deploy foi automatizado via GitHub Actions. Ao realizar um push ou merge para a branch main, é disparado o workflow, que se conecta a VPS utilizando SSH, executando o git pull e o processo de deploy definido no Makefile do projeto. O Docker reconstrói apenas as camadas alteradas da imagem. O estágio de download de dependencias Go é cacheado e substitui o container em execução sem interromper o Caddy.

os ambientes de desenvolvimento e produção são completamente isolados. Cada um possui seu próprio volume para o PostgreSQL, com nomes e credenciais distintas definidos em arquivos de configuração separados.

O Caddy gerencia os certificados TLS automaticamente via protocolo ACME com a Let's Encrypt. Na primeira inicialização em produção ele solicita e instala o certificado, realizando renovações periodicamente antes do vencimento.

A imagem do docker utiliza build multi-stage: o primeiro estágio compila o binário do Go em uma imagem com o toolchain completo, o segundo estágio copia apenas o binário para uma imagem de base mínima, mantendo a imagem final sem ferramentas desnecessárias para a produção.

Conclusão

Esse projeto foi desenvolvido com o objetivo de construir uma presenca técnica online que servisse como um artefato técnico demonstrável, resultando em um sistema completo com backend em Go, banco de dados relacional com PostgreSQL, painel administrativo e pipeline de deploy automatizado operando em produção de forma quase autônoma.

As escolhas arquiteturais priorizam simplicidade operacional e clareza. Renderização no servidor, sem framework JS no frontend, deploy via Compose, sem orquestrador, automação na geração de certificados TLS.

O portfólio continuará evoluindo, novos projetos serão adicionados, futuras atualizações serão documentadas no devlog de cada projeto, posts registrarão aprendizados e experiências ao longo do tempo.