Subindo uma API via proxy reverso com Caddyserver e Go
Um amigo pediu um exemplo de como subir uma API usando proxy reverso com a linguagem Go. A seguir, apresento um pequeno roteiro.
Primeiro, suba um servidor e registre seu IP no provedor de DNS. Atribua o IP a um nome para criar um certificado HTTPS para a máquina.
Configure o firewall da máquina e abra apenas as portas 22 (SSH), 80 (HTTP) e 443 (HTTPS).
Caddy
Eu uso o servidor HTTP Caddy. Ele é prático e cria certificados HTTPS automaticamente. Por padrão, redireciona as requisições HTTP para HTTPS.
Para instalar o Caddy no seu sistema operacional, siga as instruções em https://caddyserver.com/docs/install.
Após a instalação, edite o arquivo /etc/caddy/Caddyfile
e adicione a seguinte configuração:
example.com {
# Define um arquivo para registrar o log do servidor
log {
output file /var/log/caddy/example.com.log
}
# Configura o servidor para servir páginas estáticas
root * /var/www/html
file_server
# Redireciona chamadas iniciadas com o endpoint /api
route /api* {
reverse_proxy 127.0.0.1:8080
}
}
O Caddy pegará o domínio configurado no lugar de example.com, consultará o servidor de DNS para verificar se corresponde ao IP do servidor e criará os certificados TLS para você.
Essa configuração supõe que você deseja servir arquivos estáticos. Se preferir que o código Go sirva a base do servidor, remova as configurações do caminho root e altere a rota como no exemplo a seguir:
route /* {
reverse_proxy 127.0.0.1:8080
}
API
Para este exemplo, criaremos um servidor HTML simples. Ele escutará na porta 8080 e responderá “Hello, world!” para as requisições.
package main
import (
"io"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello, world!")
}
func main() {
http.HandleFunc("/", handler)
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic(err)
}
}
Este código serve apenas para demonstrar que o redirecionamento de porta via proxy reverso com o Caddy funciona.
tmux
O tmux está presente em todas as distribuições Linux. Assim como o GNU Screen, podemos usar ele para manter um servidor rodando durante testes, mesmo que a conexão caia. Não é uma boa prática usar o tmux para serviços em produção. No entanto, durante o debug, examinar as saídas na tela ajuda bastante. Se você não conhece o tmux, vale a pena aprender sobre a ferramenta.
Supervisor
Para produção, uma ótima forma de gerenciar seu serviço é usando o supervisor.
Para instalar no Debian ou Ubuntu, use o comando:
apt-get install supervisor
Em seguida, crie um arquivo api.conf no diretório /etc/supervisor/conf.d/
. (O caminho pode variar conforme a distribuição Linux)
Este é um exemplo simples de arquivo de configuração para iniciar nosso serviço:
[program:api]
command=/path/api
directory=/path
autostart=true
O supervisor usará o executável /path/api
para iniciar o serviço. Você pode adicionar mais configurações, como reiniciar automaticamente em caso de erro ou redirecionar os logs.
Após criar o arquivo de configuração, recarregue o supervisor com o comando:
supervisorctl reread # recarrega a configuração
supervisorctl update # executa as mudanças
Você pode ver o estado do seu serviço com o seguinte comando:
supervisorctl status api
Para iniciar o serviço, use:
supervisorctl start api
E para parar o serviço, use:
supervisorctl stop api
Existem muitos outros comandos. Use man supervisorctl
para aprender mais sobre eles.
Conclusão
Este é um resumo simplificado de como subir uma aplicação escrita em Go de forma controlada, com certificados TLS e possibilidade de crescimento sem sacrificar a simplicidade. Conforme seu sistema cresce, você provavelmente adicionará mais serviços e rotas no Caddy, mas não ficará mais complicado.
Esta é uma forma de subir uma aplicação Go permite que você suba o serviço como um usuário comum em uma porta alta. O Caddy cuidará do proxy reverso e dos certificados TLS. O supervisor cuidará do serviço em produção.
Eventualmente, você pode precisar de workers para tarefas assíncronas. Para isso, use o crontab
e pequenos executáveis. Será fácil de manter.