Deploying Go Applications
This comprehensive guide covers everything you need to know about deploying Go applications via Deploy with Git, from simple HTTP servers to complex microservices using Gin, Echo, or Fiber.
Overview
Deploy with Git automatically detects Go applications by looking for:
go.modfilego.sumfor dependency verification.go-versionfor 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
- Detection: Finds
go.modand identifies as Go project - Version Selection:
- Checks
GO_VERSIONenvironment variable - Checks
.go-versionfile - Checks
godirective in go.mod (e.g.,go 1.22) - Falls back to Go 1.22.0
- Checks
- Runtime Installation:
- Downloads official Go binary from golang.org
- Extracts to
/opt/flux-tools/go - Sets GOROOT and GOPATH environment variables
- Dependencies: Runs
go mod downloadandgo mod verify - Build: Compiles optimized static binary with
-ldflags=-w -s - Start: Executes compiled binary
Framework-Specific Guides
Gin Framework
Gin is a high-performance HTTP web framework for Go. Deploy with Git 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, Deploy with Git 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
| Variable | Description | Default |
|---|---|---|
GO_VERSION | Go version to install | Auto-detected from go.mod |
CGO_ENABLED | Enable/disable CGO | 0 (disabled) |
GOOS | Target operating system | linux |
GOARCH | Target architecture | amd64 |
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
pushevent
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
- Use Static Binaries: Keep
CGO_ENABLED=0for faster deploys and smaller images - Optimize Dependencies: Remove unused dependencies from go.mod
- Binary Size: The build uses
-ldflags=-w -sto strip debug info (typically 20-30% size reduction) - Dependency Caching: Dependencies are cached based on go.sum hash - no reinstall if unchanged
- Health Checks: Implement
/healthendpoint 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