Go выкладывается в сеть проще многих языков: весь проект компилируется в один статический бинарник, которому на сервере не нужны ни интерпретатор, ни виртуальная машина, ни пачка библиотек. Но обвязка вокруг бинарника — обратный прокси, сертификат, автозапуск, перезапуск после падения — остаётся точно такой же, как для Python или PHP. Единственное, что действительно требуется от самого кода: слушать адрес 0.0.0.0 и порт, который приходит в переменной PORT. Ниже — путь от папки с исходниками до рабочей HTTPS-ссылки на Dockbox и то, где Go-проекты спотыкаются чаще всего.
Почему Go-проект по умолчанию тащат на VPS
Привычный сценарий начинается с аренды сервера: поставить тулчейн, собрать проект, поставить перед ним nginx, выпустить сертификат и придумать, как поднимать процесс после перезагрузки. Go удобен тем, что компилируется в один файл, но вокруг файла всё то же самое, и обычно это ложится на вас.
Тулчейн и его версия. Go живёт на сервере, пока вы его не снесёте. Обновление тулчейна под новую зависимость может сломать сборку, а разбираться придётся на живой машине.
Сборка на сервере. go build ест CPU и память, и на слабом VPS сборка с большим числом зависимостей быстро упирается в потолок.
Обратный прокси и сертификат. Без nginx приложение не отдаёт HTTPS, а сертификат нужно продлевать каждые три месяца.
Автозапуск и перезапуск. Чтобы бинарник вернулся в строй после падения и после перезагрузки, нужен systemd-юнит или супервизор — и отдельный навык его отладки.
Оплата сервера независимо от нагрузки. Машина стоит денег все 30 дней, даже если сервис дёргают раз в сутки.
Платформа деплоя снимает эту часть: вы отдаёте папку с исходниками, она находит go.mod, ставит тулчейн, собирает проект и отдаёт публичную HTTPS-ссылку. Ни сервера, ни nginx, ни ручного сертификата.
Шаг 1. Проверьте go.mod в корне проекта
Файл go.mod в корне проекта перечисляет зависимости и служит признаком того, что перед нами Go-приложение. Рядом обычно лежит go.sum — его тоже оставьте: он фиксирует контрольные суммы версий, и сборка совпадёт с той, которую вы тестировали локально.
Папку vendor класть не нужно: зависимости платформа подтянет сама из go.mod. И следите за вложенностью — складывайте архив так, чтобы go.mod оказался в корне, а не внутри лишней папки-обёртки. Если файла нет вовсе, инициализируйте модуль у себя перед загрузкой:
go mod init example.com/myapp && go mod tidy
Шаг 2. Читайте порт из PORT и слушайте 0.0.0.0
Порт задаёт платформа, а не вы. Значение приходит в переменной PORT, и его нужно читать в рантайме. Слушать нужно адрес 0.0.0.0, а не 127.0.0.1: иначе приложение отвечает только внутри контейнера, и ссылка остаётся пустой. Жёстко вписанный порт — причина номер один, по которой публикация не открывается.
Плохой вариант — адрес и порт зафиксированы числами:
http.ListenAndServe("127.0.0.1:8080", mux)
Правильный — значения берутся из окружения:
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
addr := "0.0.0.0:" + port
log.Fatal(http.ListenAndServe(addr, mux))
Фреймворк роли не играет: у Gin, Echo, Chi и Fiber порт подставляется в финальный вызов из окружения, а не константой. У Fiber это app.Listen("0.0.0.0:" + port), у Echo — e.Start(addr). Требование одно: слушать 0.0.0.0 и порт из PORT.
Шаг 3. Секреты — в переменные окружения
Ключи API, токены и строку подключения к базе читайте через os.Getenv, а не держите константами в коде. Код вы почти наверняка зальёте в Git или кому-то покажете, и секреты уедут вместе с ним.
dbURL := os.Getenv("DATABASE_URL")
if dbURL == "" {
log.Fatal("DATABASE_URL is not set")
}
В настройках проекта Dockbox такие значения задаются отдельно и передаются в контейнер в зашифрованном виде, поэтому в архиве и в репозитории они не появляются. Файл .env при этом включать не нужно.
Шаг 4. Отдайте исходники, а не собранный бинарник
Сборка идёт на нашей стороне, поэтому нужен исходный код: go.mod, go.sum, папка с пакетами и остальные файлы проекта. Готовый бинарник не нужен, и это не формальность: файл, скомпилированный на вашем ноутбуке, обычно собран под macOS или Windows и на Linux-сервере не запустится. Кросс-компиляция через GOOS=linux тоже не требуется — платформа соберёт всё сама под нужную архитектуру.
Не тащите в архив кеш сборки из GOCACHE и локальные артефакты — они только раздуют загрузку. Исходников вместе с go.mod достаточно.
Шаг 5. Загрузите код и дождитесь сборки
Проект попадает на платформу архивом или импортом репозитория GitHub, в том числе приватного. Дальше ничего делать не нужно: Go компилируется быстро, и первая сборка обычно занимает меньше времени, чем у Rust или Java. Статус и живые логи в панели показывают, что происходит: ошибка компиляции видна там сразу.
Когда всё готово, вы получаете публичную HTTPS-ссылку — её можно открыть и отправить кому угодно. Новая версия уезжает тем же путём: свежий архив или обновление из GitHub, а адрес остаётся прежним.
Сколько памяти нужно Go-сервису и сколько это стоит
Go компилируется в статический бинарник без интерпретатора, поэтому в простое веб-сервис на net/http, Gin или Echo ест десятки мегабайт, а не сотни, и стартует почти мгновенно. Горутины дешёвые, поэтому держать много одновременных соединений не страшно. Основной аппетит приходится на линковку бинарника, и он скромнее, чем у языков с тяжёлым тулчейном.
Ни администрировать сервер, ни следить за процессом не нужно: контейнеры работают постоянно, без ограничения по часам и без «засыпания». Упавший контейнер платформа перезапускает сама.
Starter — 990 ₽/мес. 1 vCPU, 2 GB RAM, один проект. Первый месяц бесплатный. Для одного Go-сервиса этого достаточно с большим запасом, и лимита по времени работы у тарифа нет.
Pro — 2 490 ₽/мес. 2 vCPU, 4 GB RAM, до пяти проектов — вариант, если сборка упирается в память или приложений несколько.
Team — 4 990 ₽/мес — для команд, которым нужен запас ресурсов и SLA.
Свой Dockerfile поддерживается, но не обязателен: язык платформа определяет по коду сама. Если Dockerfile нужен, берите многоступенчатую сборку — статический бинарник Go позволяет уместить финальный образ в десятки мегабайт:
FROM golang:1.23 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app .
FROM alpine:3.20
COPY --from=build /app /app
CMD ["/app"]
Частые вопросы
Нужно ли собирать бинарник на Linux перед загрузкой?
Нет, загружайте исходники вместе с go.mod и go.sum. Сборка происходит на нашей стороне, поэтому Go и тулчейн локально не нужны. Бинарник, собранный на macOS или Windows, на сервере всё равно не запустится.
Какая команда запуска используется для Go-проекта?
Если в корне лежит один main-пакет, платформа собирает его сама. Если пакетов несколько, держите main там, где Go найдёт его без подсказок. Чем проще структура, тем предсказуемее сборка.
Читаю порт из PORT, но ссылка не открывается. Что проверить?
Сначала адрес привязки: приложение должно слушать 0.0.0.0, а не 127.0.0.1, иначе оно отвечает только внутри контейнера. Вторая частая причина — падение сразу после старта, например из-за отсутствующего ключа или недоступной базы. И то и другое видно в логах панели вместе с текстом ошибки.
Годится ли Go для Telegram-бота или небольшого API?
Да, и это, пожалуй, самый выгодный для языка сценарий: статический бинарник ест мало памяти и стартует мгновенно, поэтому один контейнер спокойно тянет и бота на длинном опросе, и вебхук, и небольшой REST API. Отдельный сервер под это арендовать не нужно.
Что делать, если приложение ходит в базу или внешний сервис?
Строку подключения и ключи передайте через переменные окружения, а не через код или файл .env в архиве. Проверьте, что база доступна с нашей стороны: если она живёт на вашем VPS или домашней машине, соединение придётся разрешить в её настройках. Ошибка подключения видна в логах сразу после старта.