Развертывание приложения на Go
Чтобы развернуть приложение на Go в Lizard (lizard.build), загрузите или отправьте через git модуль с файлом go.mod. Сборкой занимается lizardpack: он берёт версию Go из строки go, компилирует статический бинарник (CGO_ENABLED=0) и запускает его на Alpine Linux. Сервис использует порт 8080, и Lizard передаёт его процессу в PORT, поэтому читайте PORT и слушайте на всех интерфейсах.
Статус тестов: пример приложения ниже собирается и запускается локально с Go 1.24, а его план сборки мы проверили в планировщике сборки lizardpack, который использует Lizard. Полный деплой по этому руководству мы ещё не проводили.
Перед началом
- Модуль Go с
go.modв директории, которую вы разворачиваете, иgo.sum, если у модуля есть зависимости. - Lizard CLI с выполненным
lizard loginи тариф Pro или 7-дневный пробный период Pro (нужна карта). См. цены.
Минимальное приложение
go.mod:
module example.com/hello
go 1.24main.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.Fprintln(w, "Hello from Go on Lizard")
})
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "ok")
})
log.Printf("listening on :%s", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}С ":"+port сервер слушает на всех интерфейсах. Адрес вроде 127.0.0.1:8080 принимает подключения только изнутри контейнера, и деплой так и не становится работоспособным.
Проверьте локально:
go run .
curl http://localhost:8080/healthzЧто собирает lizardpack
| Шаг | Что происходит |
|---|---|
| Определение | go.mod, go.work или любой файл .go. Go проверяется раньше Node.js и Python. |
| Версия Go | Строка go в go.mod, только мажорная и минорная версии: go 1.24.3 собирается на golang:1.24-alpine. Без go.mod используется Go 1.24. |
| Сборка | go mod download, затем CGO_ENABLED=0 GOOS=linux go build -ldflags='-s -w' -o /app/server <package> |
| Пакет main | Корневая директория; ./cmd, если есть cmd/main.go; иначе первый по алфавиту cmd/<name>/main.go |
| Рантайм | alpine:3.19 с ca-certificates и tzdata. Рядом с бинарником lizardpack копирует в /app всю директорию исходников, поэтому относительные пути вроде templates/ и static/ продолжают работать. |
| Запуск и порт | /app/server на порту 8080 |
Сгенерированный Dockerfile:
FROM golang:1.24-alpine AS build
WORKDIR /app
COPY go.mod go.sum* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags='-s -w' -o /app/server .
FROM alpine:3.19
RUN apk add --no-cache ca-certificates tzdata
WORKDIR /app
COPY --from=build /app /app
EXPOSE 8080
CMD ["/app/server"]Чтобы получить этот образ, оставьте команды сборки и запуска сервиса пустыми. Если задана любая из них, Lizard пишет по этим командам другой Dockerfile и игнорирует строку go: команда go build … собирается на Go 1.24. Чтобы управлять каждым шагом, закоммитьте собственный Dockerfile; см. Развертывание Docker-контейнера из Dockerfile.
Развертывание
Из корня модуля:
lizard init --name go-app
lizard add --service api
lizard up --service api --port 8080lizard up загружает директорию, собирает её на сборочных машинах Lizard и выводит URL. Docker и Go на машине, где вы запускаете команду, не нужны. Для git push to deploy подключите репозиторий GitHub командой lizard add -r your-org/your-app -n api, затем проверьте, что lizard port --service api выводит 8080.
Фреймворки
- net/http, chi, gorilla/mux: передайте
":" + os.Getenv("PORT")вhttp.ListenAndServe, как в примере выше. - Gin:
r.Run()без адреса читаетPORT, а без него использует:8080. Задайте в сервисеGIN_MODE=release. - Echo, Fiber: передайте адрес сами:
e.Start(":" + os.Getenv("PORT"))илиapp.Listen(":" + os.Getenv("PORT")).
Переменные и базы данных
Задайте конфигурацию в сервисе и читайте её через os.Getenv:
lizard secrets set GIN_MODE=release API_KEY=change-me --service apiДля базы данных добавьте Managed Postgres и передайте его приватный URL через ссылку:
lizard add postgres
lizard secrets set DATABASE_URL='${{postgres.DATABASE_PRIVATE_URL}}' --service apiЗатем откройте подключение своим драйвером, например pgxpool.New(ctx, os.Getenv("DATABASE_URL")). Изменение переменной перезапускает сервис без пересборки.
Проверьте, что всё работает
lizard logs --build --service api
lizard logs --service api --tail 100
lizard psЗапросите /healthz по URL, который вывел lizard up, затем маршрут, который делает реальную работу. В логе сборки видно, какой образ golang: использовался.
Частые проблемы
| Симптом | Что делать |
|---|---|
no Go files in /app | Пакет main лежит не в корне и не в cmd/. Перенесите его или добавьте Dockerfile. |
| Запускается не тот бинарник | Если есть несколько cmd/<name>/main.go, lizardpack собирает первый по алфавиту. Добавьте Dockerfile, который собирает нужный. |
SQLite не работает с CGO_ENABLED=0 | Сборка отключает cgo, поэтому mattn/go-sqlite3 работать не может. Возьмите драйвер на чистом Go, а лучше Managed Postgres: файлы в контейнере теряются при каждом деплое. |
| Деплой так и не становится работоспособным | Процесс должен слушать PORT (или 8080) на всех интерфейсах. См. сервис так и не становится работоспособным. |
| Нужна более новая версия Go | Измените строку go, например go mod edit -go=1.25, и разверните снова. См. версии рантайма. |
Процесс на Go, который не отдаёт HTTP, например потребитель очереди, работает как фоновый обработчик с --port 0.
См. также
Обновлено