Skip to content

Getting Started with Go Echo

A live example is available at https://go-echo.nullstone.dev.

This quickstart launches a Go Echo web application to AWS via Nullstone. It also configures a local development environment using Docker that works identical to production.

This quickstart contains a walkthrough for generating a Go Echo app. A working example is available to fork at nullstone-io/go-echo-quickstart.

Create Echo app

Initialize app

shell
go mod init go-echo-quickstart
go get github.com/labstack/echo/v4
go mod init go-echo-quickstart
go get github.com/labstack/echo/v4

Create minimal app

For this quickstart, we are going to create a minimal application. Create a file named server.go with the following contents.

go
package main

import (
	"fmt"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
    "net/http"
	"os"
)

func main() {
   port := os.Getenv("PORT")
   if port == "" {
      port = "8080"
   }
   
	// Echo instance
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Route => handler
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!\n")
	})

	// Start server
   e.Logger.Fatal(e.Start(fmt.Sprintf(":%s", port)))
}
package main

import (
	"fmt"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
    "net/http"
	"os"
)

func main() {
   port := os.Getenv("PORT")
   if port == "" {
      port = "8080"
   }
   
	// Echo instance
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Route => handler
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!\n")
	})

	// Start server
   e.Logger.Fatal(e.Start(fmt.Sprintf(":%s", port)))
}

Install dependencies

shell
go mod tidy 
go mod vendor
go mod tidy 
go mod vendor

Prepare for Local

Configure docker locally

In your project's root directory, create a file named Dockerfile with the following contents.

dockerfile
FROM golang:1.21-alpine AS builder
RUN apk add git
WORKDIR /src
ENV CGO_ENABLED=0
COPY go.* ./
RUN go mod download
COPY . ./
RUN --mount=type=cache,target=/root/.cache/go-build go build -o go-echo-quickstart .

FROM alpine:latest
RUN apk --no-cache add ca-certificates
RUN update-ca-certificates

# Add binary
WORKDIR /app/
COPY --from=builder /src/go-echo-quickstart ./

EXPOSE 8080

CMD ["/app/go-echo-quickstart"]
FROM golang:1.21-alpine AS builder
RUN apk add git
WORKDIR /src
ENV CGO_ENABLED=0
COPY go.* ./
RUN go mod download
COPY . ./
RUN --mount=type=cache,target=/root/.cache/go-build go build -o go-echo-quickstart .

FROM alpine:latest
RUN apk --no-cache add ca-certificates
RUN update-ca-certificates

# Add binary
WORKDIR /app/
COPY --from=builder /src/go-echo-quickstart ./

EXPOSE 8080

CMD ["/app/go-echo-quickstart"]

Now, create a docker-compose.yml to run locally using Docker with an attached postgres Docker container.

yaml
version: "3.8"

services:
   app:
      build: .
      ports:
         - "8080:8080"
      environment:
         NULLSTONE_ENV: local
         POSTGRES_URL: postgres://postgres:postgres@db:5432/app
      depends_on:
         - db

   db:
      image: "postgres:15"
      ports:
         - "5432:5432"
      environment:
         POSTGRES_USER: postgres
         POSTGRES_PASSWORD: postgres
         POSTGRES_DB: app

volumes:
   deps: {}
version: "3.8"

services:
   app:
      build: .
      ports:
         - "8080:8080"
      environment:
         NULLSTONE_ENV: local
         POSTGRES_URL: postgres://postgres:postgres@db:5432/app
      depends_on:
         - db

   db:
      image: "postgres:15"
      ports:
         - "5432:5432"
      environment:
         POSTGRES_USER: postgres
         POSTGRES_PASSWORD: postgres
         POSTGRES_DB: app

volumes:
   deps: {}

Let's start our app locally.

shell
docker compose up
docker compose up

Visit http://localhost:8080.

Update dependencies

As you add dependencies to your application, ensure that there is an entry for the dependency in go.mod. Then, restart your docker container with docker compose up or docker compose restart. The local docker image will install dependencies on boot.

Launch to Nullstone

Create app

When launching to Nullstone, we're going to create an app in the Nullstone UI and attach capabilities that automatically configure our app. Follow these steps in the Nullstone UI.

  1. Create an application.
    • Name: In this example, we're naming our app go-echo
    • Framework: golang
    • App Type: Container
    • App Module: Fargate Service
  2. From the Capabilities tab, Add Capability. Choose "Autogen Subdomain" > Create & Connect from the Ingress section.
  3. Open the Configuration tab, click Edit and change "port" to 8080.

Provision

Our application is ready to launch. Click "Launch" through the UI or issue up through the CLI.

shell
nullstone up --wait --app=go-echo --env=dev
nullstone up --wait --app=go-echo --env=dev

Build

Once your application is provisioned, you may build and deploy your app.

You can name your image whatever you want, just remember this image name for the deploy step. In this example, we are using an image name of go-echo-app.

shell
docker build -t go-echo-app .
docker build -t go-echo-app .

Deploy

Now, issue launch to push your docker image and deploy the service with a new version.

shell
nullstone launch --source=go-echo-app --app=go-echo --env=dev
nullstone launch --source=go-echo-app --app=go-echo --env=dev