Skip to main content

Go

In this guide we will setup a basic Go HTTP server connected to a postgres database and deploy it using LocalOps.

Prerequisites​

To follow this tutorial, you will need the following:

  • Go
  • [Docker] to build standalone containers to serve your Go app.
note

This guide assumes that you have basic knowledge of the above-mentioned technologies and tools. If you are not familiar with any of them, it is recommended to review their official documentation and tutorials to get up to speed before proceeding with this guide.

Go Http Server​

  1. Run the command go mod init go-http-server to set up your project and manage its dependencies.
  2. Now, create a file named main.go and add the following code to set up a basic http server using the gin web framework.
package main

import (
"log"
"net/http"

"github.com/gin-gonic/gin"
)

func main() {
router := gin.Default()

router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Hello, World!",
})
})

router.Run(":" + os.Getenv("APP_PORT")) // Default port 8080
}
  1. Export the required environment variables,
export APP_PORT=8080
  1. Run go mod download command to download the required dependencies.
  2. Run the command go run main.go to start the server.

Connect to your DB​

  1. Update the main.go file with the following code to connect your app to the database server
main.go
package main

import (
"database/sql"
"fmt"
"log"
"net/http"

_ "github.com/lib/pq"
"github.com/gin-gonic/gin"
)

func main() {

// Get the PostgreSQL connection details from environment variables
dbHost := os.Getenv("DB_HOST")
dbPort := os.Getenv("DB_PORT")
dbUser := os.Getenv("DB_USER")
dbPass := os.Getenv("DB_PASS")
dbName := os.Getenv("DB_NAME")

// Construct the connection string
connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", dbHost, dbPort, dbUser, dbPass, dbName)

// Connect to the PostgreSQL database
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatalf("Unable to connect to database: %v\n", err)
}
defer db.Close()

router := gin.Default()

router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Hello, World!",
})
})

router.Run(":" + os.Getenv("APP_PORT")) // Default port 8080
}
  1. Export the required environment variables,
export APP_PORT=8080 \
DB_HOST=localhost \
DB_NAME=example-app-db \
DB_USER=localops \
DB_PASS=localops \
DB_PORT=5432
  1. Make sure you have already created the provided database with username and password.
  2. Run the command go run main.go to start the server.

Visit http://localhost:8080/ to see the response from the Go http server.

Dockerise​

Dockerizing makes the app run anywhere, agnostic of the platform. As long as Docker is installed, whether it's Windows, Mac, or Linux, it can run with the same behavior.

Create .dockerignore​

Before creating the dockerfile, let's create a .dockerignore file and add that contents that should not be copied over to the docker file system.

.dockerignore
bin/
Dockerfile
.dockerignore
README.md
.git

Read more about .dockerignore here

important

Creating a .dockerinogre file and adding folders like node_modules is must, since dependencies will be installed while building the image based on the platform preferences used. Copying those from file system will overwrite the installed dependecies and might error out during deployment

Create Dockerfile​

Now, Create a Dockerfile. The Dockerfile is a text file that contains the instructions for Docker to build the image.

The Dockerfile is posted for reference with steps to create the production image. Though docker supports Multi-Stage Builds we won't be using that here. In this example we will copy source code and build and run it inside the container. You can opt for multi stage build, if you want to build the go binary in build stage and run it in another stage.

tip

Refer to this doc to know more about building docker images for go applications.

Dockerfile
# syntax=docker/dockerfile:1
FROM golang:1.21

# Set destination for COPY
WORKDIR /app

# Download Go modules
COPY go.mod go.sum ./
RUN go mod download

# Copy the source code.
COPY *.go ./

# Build
RUN GOOS=linux go build -o /go-http-server ./main.go

# Optional:
# To bind to a TCP port, runtime parameters must be supplied to the docker command.
# But we can document in the Dockerfile what ports
# the application is going to listen on by default.
# https://docs.docker.com/reference/dockerfile/#expose
EXPOSE 8080

# Run
CMD ["/go-http-server"]

Build docker image​

Now you can build and run the Docker image. To build the Docker image:

docker build --platform linux/amd64 -t go-http-server .

This command builds the go-http-server image for platform linux/amd64.

If you are locally testing your application, you can skip the platform key to build the images

# only for testing in local machine
docker build -t go-http-server .

Run the docker image​

Let's run the Docker container using the image created of the react application with the command below.

docker run \
-it \
-p 8080:8080 \
-e DB_HOST=localhost \
-e DB_PORT=5432 \
-e DB_NAME=example-app-db \
-e DB_USER=localops \
-e DB_PASS=localops \
--name go-http-server \
go-http-server

This command requires PostgresDB to be running on localhost:5432.

Next steps​

Once the docker is ready, the next steps include