Skip to main content

Deploying Go Applications

This comprehensive guide covers everything you need to know about deploying Go applications with Flux-Orbit, from simple HTTP servers to complex microservices using Gin, Echo, or Fiber.

Overview

Flux-Orbit automatically detects Go applications by looking for:

  • go.mod file
  • go.sum for dependency verification
  • .go-version for version specification (optional)

Basic Go Deployment

Simple Gin API

docker run -d \
--name gin-api \
-e GIT_REPO_URL=https://github.com/your-username/gin-api \
-e APP_PORT=8080 \
-p 8080:8080 \
runonflux/orbit:latest

What Happens Automatically

  1. Detection: Finds go.mod and identifies as Go project
  2. Version Selection:
    • Checks GO_VERSION environment variable
    • Checks .go-version file
    • Checks go directive in go.mod (e.g., go 1.22)
    • Falls back to Go 1.22.0
  3. Runtime Installation:
    • Downloads official Go binary from golang.org
    • Extracts to /opt/flux-tools/go
    • Sets GOROOT and GOPATH environment variables
  4. Dependencies: Runs go mod download and go mod verify
  5. Build: Compiles optimized static binary with -ldflags=-w -s
  6. Start: Executes compiled binary

Framework-Specific Guides

Gin Framework

Gin is a high-performance HTTP web framework for Go. Flux-Orbit automatically detects and optimizes Gin applications:

docker run -d \
--name gin-rest-api \
-e GIT_REPO_URL=https://github.com/your-username/gin-api \
-e APP_PORT=8080 \
-e GO_VERSION=1.22.0 \
-p 8080:8080 \
runonflux/orbit:latest

Example main.go:

package main

import (
"os"
"github.com/gin-gonic/gin"
)

func main() {
router := gin.Default()
router.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{"status": "healthy"})
})

port := os.Getenv("APP_PORT")
if port == "" {
port = "8080"
}
router.Run("0.0.0.0:" + port)
}

Echo Framework

Echo is a high-performance, minimalist Go web framework:

docker run -d \
--name echo-api \
-e GIT_REPO_URL=https://github.com/your-username/echo-api \
-e APP_PORT=8080 \
-p 8080:8080 \
runonflux/orbit:latest

Example main.go:

package main

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

func main() {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())

e.GET("/health", func(c echo.Context) error {
return c.JSON(200, map[string]string{"status": "healthy"})
})

port := os.Getenv("APP_PORT")
if port == "" {
port = "8080"
}
e.Start(fmt.Sprintf("0.0.0.0:%s", port))
}

Fiber Framework

Fiber is an Express-inspired web framework for Go:

docker run -d \
--name fiber-api \
-e GIT_REPO_URL=https://github.com/your-username/fiber-api \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest

Standard Library (net/http)

For applications using only Go's standard library:

docker run -d \
--name stdlib-server \
-e GIT_REPO_URL=https://github.com/your-username/http-server \
-e APP_PORT=8080 \
-p 8080:8080 \
runonflux/orbit:latest

Version Management

Specify Go Version

Option 1: Environment Variable

docker run -d \
-e GIT_REPO_URL=https://github.com/your-username/go-app \
-e APP_PORT=8080 \
-e GO_VERSION=1.21.5 \
-p 8080:8080 \
runonflux/orbit:latest

Option 2: .go-version File

1.22.0

Option 3: go.mod Directive

module github.com/your-username/app

go 1.22

require (
github.com/gin-gonic/gin v1.9.1
)

Build Optimization

CGO Configuration

By default, Flux-Orbit builds static binaries with CGO_ENABLED=0 for maximum portability:

# Default: Static binary (CGO disabled)
docker run -d \
-e GIT_REPO_URL=https://github.com/your-username/go-app \
-e APP_PORT=8080 \
-p 8080:8080 \
runonflux/orbit:latest

Enable CGO if needed:

docker run -d \
-e GIT_REPO_URL=https://github.com/your-username/go-app \
-e APP_PORT=8080 \
-e CGO_ENABLED=1 \
-p 8080:8080 \
runonflux/orbit:latest

Custom Build Command

Override the default build command if needed:

docker run -d \
-e GIT_REPO_URL=https://github.com/your-username/go-app \
-e APP_PORT=8080 \
-e BUILD_COMMAND="go build -tags production -o myapp ." \
-p 8080:8080 \
runonflux/orbit:latest

Environment Variables

Go-Specific Variables

VariableDescriptionDefault
GO_VERSIONGo version to installAuto-detected from go.mod
CGO_ENABLEDEnable/disable CGO0 (disabled)
GOOSTarget operating systemlinux
GOARCHTarget architectureamd64

Common Application Variables

docker run -d \
--name go-api \
-e GIT_REPO_URL=https://github.com/your-username/go-api \
-e APP_PORT=8080 \
-e GO_VERSION=1.22.0 \
-e CGO_ENABLED=0 \
-e DATABASE_URL=postgres://user:pass@db:5432/mydb \
-e JWT_SECRET=your-secret-key \
-e LOG_LEVEL=info \
-p 8080:8080 \
runonflux/orbit:latest

Advanced Scenarios

Monorepo - Deploy Specific Service

docker run -d \
--name go-auth-service \
-e GIT_REPO_URL=https://github.com/your-username/monorepo \
-e PROJECT_PATH=services/auth \
-e APP_PORT=8080 \
-p 8080:8080 \
runonflux/orbit:latest

Private Repository

docker run -d \
--name private-go-api \
-e GIT_REPO_URL=https://github.com/your-username/private-api \
-e GIT_TOKEN=ghp_your_personal_access_token \
-e APP_PORT=8080 \
-p 8080:8080 \
runonflux/orbit:latest

With Deployment Hooks

Create pre-deploy.sh in your repository root:

#!/bin/bash
# Run database migrations before deployment
echo "Running database migrations..."
# Your migration logic here

Create post-deploy.sh:

#!/bin/bash
# Warm up cache after deployment
echo "Warming up cache..."
curl http://localhost:$APP_PORT/api/warmup
docker run -d \
--name go-api-with-hooks \
-e GIT_REPO_URL=https://github.com/your-username/go-api \
-e APP_PORT=8080 \
-p 8080:8080 \
runonflux/orbit:latest

CI/CD Integration

Automatic Deployment with Webhooks

docker run -d \
--name go-api \
-e GIT_REPO_URL=https://github.com/your-username/go-api \
-e APP_PORT=8080 \
-e WEBHOOK_SECRET=my-secret-phrase \
-p 8080:8080 \
-p 9001:9001 \
runonflux/orbit:latest

Configure GitHub Webhook:

  • Payload URL: https://your-app-9001.app.runonflux.io/webhook
  • Content type: application/json
  • Secret: my-secret-phrase
  • Events: Just the push event

Polling for Updates

docker run -d \
--name go-api \
-e GIT_REPO_URL=https://github.com/your-username/go-api \
-e APP_PORT=8080 \
-e POLLING_INTERVAL=300 \
-p 8080:8080 \
runonflux/orbit:latest

Troubleshooting

Binary Not Found After Build

Problem: "No Go binary found in /app/src"

Solution: Ensure your go.mod has a valid module name. The binary name is derived from the module:

module github.com/your-username/my-api  // Binary will be named "my-api"

go 1.22

require (
github.com/gin-gonic/gin v1.9.1
)

CGO Dependencies

Problem: Build fails with CGO-related errors

Solution: Enable CGO if your application requires it:

-e CGO_ENABLED=1

Port Binding Issues

Problem: Application not accessible

Solution: Ensure your Go application binds to 0.0.0.0 (not localhost or 127.0.0.1):

// Good: Accessible from outside container
router.Run("0.0.0.0:" + port)

// Bad: Only accessible from inside container
router.Run("localhost:" + port)

Build Takes Too Long

Problem: Go build timeout

Solution: Increase build timeout:

-e BUILD_TIMEOUT=2400  # 40 minutes

Performance Tips

  1. Use Static Binaries: Keep CGO_ENABLED=0 for faster deploys and smaller images
  2. Optimize Dependencies: Remove unused dependencies from go.mod
  3. Binary Size: The build uses -ldflags=-w -s to strip debug info (typically 20-30% size reduction)
  4. Dependency Caching: Dependencies are cached based on go.sum hash - no reinstall if unchanged
  5. Health Checks: Implement /health endpoint for faster deployment verification

Example Repository Structure

my-go-api/
├── go.mod # Module definition
├── go.sum # Dependency checksums
├── .go-version # Optional: Pin Go version
├── main.go # Application entry point
├── pre-deploy.sh # Optional: Pre-deployment hook
├── post-deploy.sh # Optional: Post-deployment hook
├── handlers/
│ ├── users.go
│ └── auth.go
├── models/
│ └── user.go
└── middleware/
└── auth.go

Next Steps