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.

Cesar Gimenes

Última modificação