Skip to main content

Deploy Go

This guide will help you deploy a Go application to Deployxa.

Overview

Go is a statically typed, compiled programming language designed for simplicity and efficiency. Deployxa provides optimized deployments for Go applications with automatic configuration.

Features:

  • Automatic framework detection
  • Go 1.21+ support
  • Gin, Echo, Fiber support
  • PostgreSQL, MySQL support
  • Automatic HTTPS
  • Global CDN
  • Minimal container size

Prerequisites

  • A Go application
  • A GitHub repository with your code
  • A Deployxa account

Quick Start

1. Create Your Go App

If you don't have a Go app yet:

mkdir my-go-app
cd my-go-app
go mod init my-go-app

Create main.go:

package main

import (
"fmt"
"log"
"net/http"
"os"
)

func main() {
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

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

log.Printf("Server starting on port %s", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}

2. Push to GitHub

git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/yourusername/my-go-app.git
git push -u origin main

3. Deploy to Deployxa

  1. Go to Deployxa Dashboard
  2. Click "New Project"
  3. Select your GitHub repository
  4. Deployxa will automatically detect Go
  5. Click "Deploy"

Your app will be live in under 30 seconds!

Configuration

Detected Settings

Deployxa automatically detects these settings:

SettingValue
FrameworkGo
Build Commandgo build -o main .
Output Directory.
Start Command./main
Port8080

Custom Configuration

If you need to customize settings:

  1. Go to ProjectSettingsBuild
  2. Modify settings as needed
  3. Save changes

Example Custom Settings:

{
"buildCommand": "go build -o main .",
"startCommand": "./main"
}

Environment Variables

Adding Environment Variables

  1. Go to ProjectEnvironment
  2. Click "Add Variable"
  3. Enter key and value
  4. Click "Save"

Common Go Environment Variables:

PORT=8080
GIN_MODE=release

# Database
DATABASE_URL=postgresql://user:pass@host:5432/dbname
DB_HOST=your-db-host
DB_NAME=your-database
DB_USER=your-username
DB_PASSWORD=your-password

Using Environment Variables

In your Go app:

package main

import (
"fmt"
"os"
)

func main() {
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

dbHost := os.Getenv("DB_HOST")

fmt.Printf("Server running on port %s\n", port)
}

Database Configuration

Using PostgreSQL

Install driver:

go get github.com/lib/pq
package main

import (
"database/sql"
"fmt"
"log"
"os"

_ "github.com/lib/pq"
)

func main() {
connStr := os.Getenv("DATABASE_URL")
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()

err = db.Ping()
if err != nil {
log.Fatal(err)
}

fmt.Println("Successfully connected to PostgreSQL!")
}

Using MySQL

Install driver:

go get github.com/go-sql-driver/mysql
package main

import (
"database/sql"
"fmt"
"log"
"os"

_ "github.com/go-sql-driver/mysql"
)

func main() {
connStr := os.Getenv("DATABASE_URL")
db, err := sql.Open("mysql", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()

err = db.Ping()
if err != nil {
log.Fatal(err)
}

fmt.Println("Successfully connected to MySQL!")
}

Web Frameworks

Using Gin

Install Gin:

go get github.com/gin-gonic/gin
package main

import (
"net/http"
"os"

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

func main() {
gin.SetMode(gin.ReleaseMode)
r := gin.Default()

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

port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

r.Run(":" + port)
}

Using Echo

Install Echo:

go get github.com/labstack/echo/v4
package main

import (
"net/http"
"os"

"github.com/labstack/echo/v4"
)

func main() {
e := echo.New()

e.GET("/", func(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]string{
"message": "Hello, Deployxa!",
})
})

port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

e.Start(":" + port)
}

Using Fiber

Install Fiber:

go get github.com/gofiber/fiber/v2
package main

import (
"os"

"github.com/gofiber/fiber/v2"
)

func main() {
app := fiber.New()

app.Get("/", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"message": "Hello, Deployxa!",
})
})

port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

app.Listen(":" + port)
}

Custom Domains

Adding a Custom Domain

  1. Go to ProjectDomains
  2. Click "Add Domain"
  3. Enter your domain (e.g., example.com)
  4. Configure DNS records
  5. Wait for verification

DNS Configuration

For Apex Domain (example.com):

Type: A
Name: @
Value: 76.76.21.21

For Subdomain (www.example.com):

Type: CNAME
Name: www
Value: cname.deployxa.com

Performance Optimization

Enable Gzip Compression

Using Gin:

import "github.com/gin-contrib/gzip"

func main() {
r := gin.Default()
r.Use(gzip.Gzip(gzip.DefaultCompression))
// ...
}

Enable Caching

r.GET("/data", func(c *gin.Context) {
c.Header("Cache-Control", "public, max-age=3600")
c.JSON(http.StatusOK, data)
})

Database Connection Pooling

db.SetMaxOpenConns(25)
db.SetMaxIdleConns(25)
db.SetConnMaxLifetime(5 * time.Minute)

Monitoring

Viewing Logs

  1. Go to ProjectLogs
  2. Select log type:
    • Build Logs: Deployment process
    • Runtime Logs: Application output
    • Error Logs: Application errors

Go Logging

package main

import (
"log"
"os"
)

func main() {
log.SetOutput(os.Stdout)
log.Println("Application started")
}

Monitoring Metrics

  1. Go to ProjectAnalytics
  2. View metrics:
    • Request count
    • Response times
    • Error rates
    • Bandwidth usage
    • CPU/RAM usage

Health Checks

Deployxa automatically monitors your application:

  • HTTP health checks every 30 seconds
  • Automatic restart on failure
  • Alerts on consecutive failures

Add a health check endpoint:

r.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "healthy",
})
})

Troubleshooting

Application Crashes on Start

Problem: Application crashes immediately

Solution:

  1. Check runtime logs for errors
  2. Verify environment variables
  3. Check for missing dependencies
  4. Ensure PORT is configured correctly
  5. Check for port conflicts

Database Connection Failed

Problem: Cannot connect to database

Solution:

  1. Verify DATABASE_URL is correct
  2. Check database host and port
  3. Ensure database exists
  4. Check firewall rules
  5. Verify database credentials

Build Failed

Problem: go build fails

Solution:

  1. Check build logs for specific errors
  2. Verify dependencies are correct
  3. Check for syntax errors
  4. Test build locally
  5. Ensure Go version is compatible

Slow Response Times

Problem: Application responds slowly

Solution:

  1. Enable compression
  2. Use caching
  3. Optimize database queries
  4. Use connection pooling
  5. Upgrade plan for more resources

Best Practices

Project Structure

my-go-app/
├── main.go
├── go.mod
├── go.sum
├── .env.example
├── handlers/
│ └── users.go
├── models/
│ └── user.go
├── database/
│ └── db.go
└── README.md

Environment Variables

  • Never commit .env file
  • Use .env.example as template
  • Rotate secrets regularly
  • Use different values per environment

Security

  • Keep dependencies updated
  • Use HTTPS only
  • Validate all inputs
  • Use parameterized queries
  • Enable CORS properly
  • Use authentication/authorization

Performance

  • Enable compression
  • Use caching
  • Optimize database queries
  • Use connection pooling
  • Use goroutines for concurrency
  • Minimize allocations

Database

  • Use connection pooling
  • Index frequently queried columns
  • Use transactions for complex operations
  • Backup database regularly
  • Use prepared statements

Advanced Configuration

Custom Build Configuration

Create Makefile:

build:
CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o main .

run:
./main

test:
go test -v ./...

Docker Support

For local development with Docker:

FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]

Graceful Shutdown

package main

import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)

func main() {
server := &http.Server{Addr: ":8080"}

go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()

quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit

log.Println("Shutdown Server ...")

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

if err := server.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}

log.Println("Server exiting")
}

Examples

Basic Go App

package main

import (
"fmt"
"net/http"
"os"
)

func main() {
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

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

http.ListenAndServe(":"+port, nil)
}

REST API with Gin

package main

import (
"net/http"
"os"

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

type User struct {
ID int `json:"id"`
Name string `json:"name"`
}

var users = []User{
{ID: 1, Name: "John"},
{ID: 2, Name: "Jane"},
}

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

r.GET("/users", func(c *gin.Context) {
c.JSON(http.StatusOK, users)
})

r.POST("/users", func(c *gin.Context) {
var newUser User
if err := c.ShouldBindJSON(&newUser); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
users = append(users, newUser)
c.JSON(http.StatusCreated, newUser)
})

port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

r.Run(":" + port)
}

With Database

package main

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

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

var db *sql.DB

func main() {
var err error
connStr := os.Getenv("DATABASE_URL")
db, err = sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()

r := gin.Default()

r.GET("/users", getUsers)

port := os.Getenv("PORT")
if port == "" {
port = "8080"
}

r.Run(":" + port)
}

func getUsers(c *gin.Context) {
rows, err := db.Query("SELECT id, name FROM users")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
defer rows.Close()

var users []map[string]interface{}
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
users = append(users, map[string]interface{}{
"id": id,
"name": name,
})
}

c.JSON(http.StatusOK, users)
}

Resources


Need Help? Contact support@deployxa.com or join our community Discord.