Mamura
Mamura Programador web com mais de 15 anos de experiência.

Como criar uma devstack moderna

Como criar uma devstack moderna

Sempre que eu começava um novo projeto full stack, acabava repetindo o mesmo ritual: configurar Docker, ajustar proxy reverso, definir hosts locais, subir frontend e backend separadamente e documentar tudo para que outros desenvolvedores conseguissem rodar o ambiente.

O problema é que esse processo quase nunca era tão simples quanto deveria. Bastava faltar uma network no Docker, uma porta entrar em conflito ou um serviço subir fora da ordem para o setup local virar uma fonte de atrito.

Para resolver isso, montei no projeto Toothly uma estrutura de desenvolvimento local focada em projetos modernos com arquitetura app + api.

A ideia foi criar uma base que fosse:

  • simples de entender
  • rápida de subir
  • reutilizável em outros projetos
  • amigável para onboarding

Neste artigo, vou mostrar passo a passo como organizar essa stack usando Docker, Traefik, subdomínios locais, um script de bootstrap e um Makefile para centralizar os comandos.

Objetivo da stack

A proposta dessa devstack é resolver os principais problemas do ambiente local.

Ela entrega:

  • Frontend (app)
  • Backend (api)
  • Proxy reverso com Traefik
  • Subdomínios locais amigáveis
  • Setup automatizado
  • Comandos padronizados
  • Zero dor de cabeça para novos devs

Estrutura do projeto

1
2
3
4
5
6
7
8
9
toothly/
├── app/
├── api/
├── docker-compose.yml
├── Makefile
├── scripts/
│   └── bootstrap.sh
└── traefik/
    └── traefik.yml

Docker Compose

Aqui está uma versão simplificada da stack:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
services:
  traefik:
    image: traefik:v3.3
    container_name: toothly-traefik
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik/traefik.yml:/etc/traefik/traefik.yml
    networks:
      - dev-network

  app:
    image: node:22-alpine
    working_dir: /app
    volumes:
      - ./app:/app
    labels:
      - traefik.enable=true
      - traefik.http.routers.app.rule=Host(`app.toothly.localhost`)
      - traefik.http.routers.app.entrypoints=web
      - traefik.http.services.app.loadbalancer.server.port=3000
    networks:
      - dev-network

  api:
    image: php:8.2-fpm
    working_dir: /var/www
    volumes:
      - ./api:/var/www
    labels:
      - traefik.enable=true
      - traefik.http.routers.api.rule=Host(`api.toothly.localhost`)
      - traefik.http.routers.api.entrypoints=web
      - traefik.http.services.api.loadbalancer.server.port=9000
    networks:
      - dev-network

networks:
  dev-network:
    external: true

Por que usar Traefik?

O Traefik funciona como um proxy reverso inteligente. Com ele, você pode acessar:

  • http://app.toothly.localhost
  • http://api.toothly.localhost

Em vez de:

  • localhost:3000
  • localhost:8000

Isso melhora muito:

  • organização
  • legibilidade
  • proximidade com ambiente de produção

O problema da netword Docker

Um problema comum: Se a network dev-network não existir, o projeto quebra. E isso é péssimo para onboarding.

Resolvendo com bootstrap.sh

Para evitar esse problema, criamos um script de bootstrap.

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env bash
set -e

NETWORK_NAME="dev-network"

if ! docker network inspect "$NETWORK_NAME" >/dev/null 2>&1; then
  echo "Docker network '$NETWORK_NAME' não encontrada. Criando..."
  docker network create "$NETWORK_NAME"
else
  echo "Docker network '$NETWORK_NAME' já existe."
fi

echo "Ambiente pronto"

Centralizando comandos com Makefile

Em vez de decorar comandos Docker, usamos um Makefile:

bootstrap:
	./scripts/bootstrap.sh

up:
	docker compose up -d

down:
	docker compose down

logs:
	docker compose logs -f

restart:
	docker compose down && docker compose up -d

Fluxo para novos desenvolvedores

Essa estrutura traz vários ganhos:

  • Setup previsível
  • Menos erro manual
  • Onboarding rápido
  • Padronização entre projetos
  • Fácil reutilização
  • Melhor experiência para o time

Próximos passos

Essa devstack pode evoluir facilmente:

  • HTTPS local com certificados
  • Integração com banco de dados
  • Hot reload para frontend/backend
  • Template base para novos projetos
  • CLI própria para automação

Conclusão

No fim, mais do que subir containers, a proposta dessa devstack é criar um padrão de trabalho. Quando a estrutura é intuitiva:

  • o time ganha velocidade
  • o onboarding fica mais leve
  • novos projetos começam mais rápido

E o melhor: você nunca mais precisa configurar tudo do zero.

Rating:

comments powered by Disqus