go.modابران وجود go.mod را تشخیص میدهد، یک binary لینوکسی static میسازد و آن را در image حداقلی distroless با کاربر non-root اجرا میکند.
۱. server را برای cloud آماده کنید
برنامه باید PORT را بخواند و روی همه interfaceها گوش دهد:
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func main() {
port := os.Getenv("PORT")
if port == "" {
port = "3000"
}
http.HandleFunc("/health", func(w http.ResponseWriter, _ *http.Request) {
_, _ = fmt.Fprint(w, "ok")
})
log.Fatal(http.ListenAndServe("0.0.0.0:"+port, nil))
}روی 127.0.0.1 یا یک پورت hard-codeشده گوش ندهید.
۲. module و build را بررسی کنید
در build context باید go.mod معتبر وجود داشته باشد:
module example.com/my-api
go 1.24پیش از deploy اجرا کنید:
go test ./...
go build ./...Builder بهصورت پیشفرض CGO_ENABLED=0، GOOS=linux و GOARCH=amd64 تنظیم و command زیر را در source root اجرا میکند:
go build -trimpath -ldflags='-s -w' -o /out/app .اگر package اجرایی در ./cmd/api است، command را در abrun.yaml مشخص کنید:
builder:
platform: go
build_command: go build -trimpath -ldflags='-s -w' -o /out/app ./cmd/api
runtime:
port: 3000
health: /health۳. App را بسازید و deploy کنید
abrun app create my-go-api --plan <plan> --port 3000
abrun deploy my-go-api --logsدر deployment plan باید language و framework برابر go و runtime kind برابر binary باشد. runtime generated فقط binary نهایی را کپی و با UID غیر root اجرا میکند.
monorepo
برای module داخل services/api:
abrun deploy my-go-api . --root-directory services/apiاین مسیر باید go.mod و package قابل build را در خود داشته باشد. اگر workspace چند module یا چند executable مبهم دارد، builder.root و builder.build_command را صریح کنید.
فایل و state محلی
image distroless shell و package manager ندارد و filesystem برنامه را persistent فرض نکنید. برای فایل ماندگار، persistent disk بسازید؛ برای داده application معمولاً دیتابیس مدیریتشده مناسبتر است.
برنامهای که CGO، shared library، timezone data سفارشی، shell command یا certificate سفارشی میخواهد باید با Dockerfile آزمایششده deploy شود.
shutdown و health
برای deploy بدون قطع طولانی، signalهای termination را دریافت، پذیرش request جدید را متوقف و requestهای جاری را با timeout محدود تمام کنید. health endpoint باید سریع و بدون اطلاعات حساس پاسخ دهد.
رفع مشکل
no Go files: build context یاbuilder.rootروی package درست نیست.- چند main package دارید:
builder.build_commandرا روی entrypoint مشخص تنظیم کنید. - App بالا میآید ولی reachable نیست: listener باید
0.0.0.0:$PORTباشد. - binary اجرا نمیشود: dependency مبتنی بر CGO با generated static build سازگار نیست؛ Dockerfile بسازید.
- health check timeout میشود: endpoint را سبک نگه دارید و dependency دوردست را مستقیم در readiness قفل نکنید.