Live reload em Go com docker e compile daemon
Tags: go, docker
Published: 2024-04-25 21:13:55

Desenvolver aplicações em Go é bastante produtivo, principalmente quando conseguimos combinar ferramentas que automatizam tarefas ~~chatas~~ comuns de desenvolvimento. Neste artigo, vamos explorar como implementar o live reload em uma aplicação Go usando Docker e o pacote CompileDaemon.

Caso só tenha interesse no código, você pode encontrar o projeto no meu [GitHub](https://github.com/nathaliapavan/go-live-reload-docker)

## O que é live reload?
O live reload é uma técnica que permite que as alterações no código sejam automaticamente refletidas na aplicação em execução, sem a necessidade de reiniciar manualmente o servidor. Isso é muito útil durante o desenvolvimento, pois podemos visualizar imediatamente o impacto das alterações realizadas no código.

## O que é CompileDaemon?
O CompileDaemon automatiza a recompilação do código em projetos Go, eliminando a tediosa tarefa de reiniciar manualmente o servidor a cada modificação no código. Com ele, as alterações são instantaneamente refletidas na aplicação que está sendo executada, garantindo um processo de desenvolvimento mais dinâmico e eficiente. Ao combiná-lo com o Docker, criamos um ambiente de desenvolvimento onde as alterações são aplicadas sem interrupções, reduzindo o tédio e aumentando nossa produtividade.

## Pré-requisitos
Antes de começarmos, certifique-se de ter as ferramentas abaixo instaladas em sua máquina:
[Go](https://go.dev/doc/)
[Docker](https://www.docker.com/)
[Docker-Compose](https://docs.docker.com/compose/)

## Configurando o Projeto

Vamos começar criando um novo projeto Go. Abra seu terminal e crie um diretório e navegue até ele:

``` bash
mkdir go-live-reload-docker && cd go-live-reload-docker
```

Execute o seguinte comando para inicializar o módulo do Go e criar o arquivo `go.mod`:
``` bash
go mod init go-live-reload-docker
```

## Estrutura do Projeto
Crie os arquivos abaixo manualmente. A estrutura do projeto deve ser a seguinte:
``` bash
go-live-reload-docker/
├── docker-compose.yml
├── Dockerfile.dev
├── go.mod
└── main.go
```

### docker-compose.yml
Para simplificar o processo de construção e execução da nossa aplicação, vamos utilizar o `Docker Compose`. 

``` yaml
version: "3"

services:
  app:
    container_name: go-live-reload
    build:
      context: .
      dockerfile: ./Dockerfile.dev
    ports:
      - 8080:8080
    volumes:
      - ./:/app
```

Este arquivo define um serviço chamado `app` que constrói a aplicação Go usando o arquivo `Dockerfile.dev`. Ele também mapeia a porta `8080` do contêiner para a porta `8080` do host, permitindo que a aplicação seja acessível localmente.

### Dockerfile.dev
Este Dockerfile será usado apenas durante o desenvolvimento e incluirá o pacote `CompileDaemon` para habilitar o live reload. Aqui está o conteúdo do arquivo Dockerfile.dev:

``` dockerfile
FROM golang:latest

ENV PROJECT_DIR=/app \
    GO111MODULE=on \
    CGO_ENABLED=0

WORKDIR /app

RUN mkdir "/build"

COPY . .

RUN go get github.com/githubnemo/CompileDaemon

RUN go install github.com/githubnemo/CompileDaemon

ENTRYPOINT CompileDaemon -build="go build -o /build/app -buildvcs=false" -command="/build/app"
```

Este Dockerfile utiliza a imagem oficial do Go como base e define algumas variáveis de ambiente necessárias. Ele também instala o CompileDaemon e configura um ponto de entrada para executar nossa aplicação com live reload.

### main.go
Nosso arquivo `main.go` contém uma simples aplicação HTTP que responde com uma mensagem. Aqui está o conteúdo do arquivo:

``` go
package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, Nat!")
	})

	http.ListenAndServe(":8080", nil)
}
```

## Executando a Aplicação
Agora que tudo está configurado, podemos construir e executar a aplicação com Docker. Basta executar os comandos na raiz do projeto:

```
docker-compose build
docker-compose up -d
```

Isso construirá a imagem Docker e iniciará o contêiner em segundo plano. Você pode validar a aplicação em seu navegador acessando: [http://localhost:8080](http://localhost:8080) 🥳

## Conclusão

Neste artigo, exploramos como implementar o live reload em uma aplicação Go usando Docker e CompileDaemon. O live reload  acelera o ciclo de desenvolvimento, permitindo que os desenvolvedores visualizem instantaneamente as alterações feitas no código. Com o Docker, a configuração do ambiente de desenvolvimento é simplificada e a distribuição da aplicação é facilitada. Espero que este guia tenha sido útil e que você possa aplicar esses conceitos em seus próprios projetos, será um ótimo start pra sair do zero.

Até mais o/

## Fontes
https://github.com/githubnemo/CompileDaemon
https://thegodev.com/live-reloading/
https://blog.logrocket.com/using-air-go-implement-live-reload/
https://harrk.dev/live-reloading-a-go-application-with-docker/
https://stackoverflow.com/a/41429055
https://www.youtube.com/watch?v=EoclvPzeD14&ab_channel=Aregularguy