Golang Local Development with Live Reloading using Air and Docker Compose
Learn how to set up a Golang development environment with live reloading using Air and Docker Compose, making your development process faster and more efficient.
Loading...
Prerequisites
- Mention the tools that need to be installed before proceeding:
- Golang (at least version 1.18+)
- Docker and Docker Compose
- air (installation instructions will be provided later)
Project Setup
Create a new directory for your project and navigate into it:
mkdir golang-docker-air
cd golang-docker-airInitialize a new Go module:
go mod init github.com/yourusername/golang-docker-airCreate a simple main.go file:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}Installing Air
Use the following command to install Air for live reloading. This instruction works fine for Unix systems, you can look for more informations here on Air documentation.
curl -sSfL https://raw.githubusercontent.com/air-verse/air/master/install.sh | sh -sConfigure Air
Run air init, and will be created a file on root of your project called .air.toml.
Now update cmd value property from .air.toml to:
Before:
cmd = "go build -o ./tmp/main ."After:
cmd = "go build -o ./tmp/main ./cmd/app/main.go"Now, let's create a directory cmd/app on the root of the project, and move our main.go file to this new directory.
Setting up Docker and Docker Compose
Create a Dockerfile to define the Go environment:
FROM golang:1.22.5
# Set the working directory
WORKDIR /app
# Install air for hot reloading
RUN go install github.com/air-verse/air@latest
# Copy go.mod and go.sum files
COPY go.mod go.sum ./
RUN go mod tidy && go mod verify
# Copy the rest of the application code
COPY . .
# Install air configuration
COPY .air.toml .air.toml
# Command to run air for hot reloading
CMD ["air"]Create a docker-compose.yaml file to define the services:
services:
api:
build: .
env_file:
- .env
ports:
- "3000:3000"
volumes:
- .:/app
- /app/tmp
networks:
- backend
volumes:
api_volume:
networks:
backend:
driver: bridgeTesting
Now, let's add chi package to make the test, just to try to have something close to a real scenario.
Install chi package
Run the following command below to install chi package to our project. Link from chi repository is here.
go get -u github.com/go-chi/chi/v5Update main file
Now, let's just add the following code to our main.go file (cmd/app/main.go):
package main
import (
"fmt"
"log"
"net/http"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
fmt.Println("Server starting at http://localhost:3000")
err := http.ListenAndServe(":3000", r)
if err != nil {
log.Fatalf("Server failed: %v", err)
}
}Run docker compose
Now, let's just run the following command on our terminal:
docker-compose upAnd we'll have something like this:
[+] Building 0.0s (0/0) docker:desktop-linux
[+] Running 2/2
β Network golang-docker-air_backend Created 0.0s
β Container golang-docker-air-api-1 Created 0.1s
Attaching to golang-docker-air-api-1
golang-docker-air-api-1 |
golang-docker-air-api-1 | __ _ ___
golang-docker-air-api-1 | / /\ | | | |_)
golang-docker-air-api-1 | /_/--\ |_| |_| \_ v1.52.3, built with Go go1.22.5
golang-docker-air-api-1 |
golang-docker-air-api-1 | watching .
golang-docker-air-api-1 | watching cmd
golang-docker-air-api-1 | watching cmd/app
golang-docker-air-api-1 | !exclude tmp
golang-docker-air-api-1 | building...
golang-docker-air-api-1 | go: downloading github.com/go-chi/chi/v5 v5.1.0
golang-docker-air-api-1 | running...
golang-docker-air-api-1 | Server starting at http://localhost:3000Now let's add a π at the and of our log message, just to show that our container will be reloaded:
package main
import (
"fmt"
"log"
"net/http"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
fmt.Println("Server starting at http://localhost:3000 π")
err := http.ListenAndServe(":3000", r)
if err != nil {
log.Fatalf("Server failed: %v", err)
}
}This is our terminal:
[+] Building 0.0s (0/0) docker:desktop-linux
[+] Running 2/2
β Network golang-docker-air_backend Created 0.0s
β Container golang-docker-air-api-1 Created 0.1s
Attaching to golang-docker-air-api-1
golang-docker-air-api-1 |
golang-docker-air-api-1 | __ _ ___
golang-docker-air-api-1 | / /\ | | | |_)
golang-docker-air-api-1 | /_/--\ |_| |_| \_ v1.52.3, built with Go go1.22.5
golang-docker-air-api-1 |
golang-docker-air-api-1 | watching .
golang-docker-air-api-1 | watching cmd
golang-docker-air-api-1 | watching cmd/app
golang-docker-air-api-1 | !exclude tmp
golang-docker-air-api-1 | building...
golang-docker-air-api-1 | go: downloading github.com/go-chi/chi/v5 v5.1.0
golang-docker-air-api-1 | running...
golang-docker-air-api-1 | Server starting at http://localhost:3000
golang-docker-air-api-1 | cmd/app/main.go has changed
golang-docker-air-api-1 | building...
golang-docker-air-api-1 | running...
golang-docker-air-api-1 | Server starting at http://localhost:3000 πConclusion
By following the steps in this guide, you've successfully set up a Golang development environment with live reloading using Air and Docker Compose. This setup streamlines your workflow, allowing you to focus on writing and testing your code without the need to restart your application manually.
With the combination of Docker Compose and Air, you now have a flexible, containerized development environment that can be easily scaled or adapted to fit more complex applications. Whether you're building a simple API or a larger microservices architecture, this approach ensures your development process remains efficient and productive.
Feel free to expand on this foundation by integrating other tools or services, exploring different Go packages, or customizing your Docker setup. The possibilities are vast, and this setup is just the beginning of what you can achieve with Go and Docker.
Happy coding! π