Рассмотрим варианты хостинга Golang приложения и развернем код с помощью команды git push в привязанный Git-репозиторий.

Хостинг Go

  1. Heroku - иностранный сервис c нативной поддержкой Golang-окружения. Сделайте git push в привязанный Git-репозиторий, и сервис развернет ваш Go проект автоматически на сервере. Стоимость сервиса начинается от 5$ (от 25$, если вы хотите получить гарантии непрерывной работы и выделенного ресурса).

  1. Amvera Cloud - российский сервис c функционалом Heroku. Поддерживает развертывание и обновление через push в привязанный Git-репозиторий. Если вы не работали с Git, можно воспользоваться загрузкой через интерфейс. Есть нативная поддержка как Golang, так и других окружений, достаточно в интерфейсе выбрать нужную конфигурацию. Стоимость начинается от 170 руб. в месяц, и есть стартовый баланс для бесплатного начала использования. Можно оплачивать РФ картой.

  1. Сервис приложений от Digital Ocean. Позволяет легко развернуть ваше go - приложение в инфраструктуре данного провайдера.

Деплой приложения на Go c SQLite3

В статье мы рассмотрим способ развертывания приложения на Golang с использованием встроенной БД SQLite3. Точнее, мы развернем эхо телеграм-бота и подключим БД для сохранения данных в облаке.

Мы будем использовать:

●  Git

●  Visual Studio Code (подойдет любой другой IDE)

●  Telego

●  SQLite3

Видеопример развертывания Go проекта на сервере

Подробная инструкция по деплою

Сначала создадим проект в Amvera

Для этого нам нужно предварительно зарегистрироваться или войти в существующий аккаунт.

Находясь в главном меню, нажимаем кнопку "Cоздать".

Далее вводим любое название проекта, выбираем тип сервиса "Приложение" и выбираем удобный для вас тарифный план.

Нажимаем «Далее» и переходим к загрузке данных проекта.

Существует два варианта загрузить проект: непосредственно командами git или через интерфейс сервиса. Мы рассмотрим оба варианта загрузки проекта.

Подключение к репозиторию через Git

1. Вызываем терминал в IDE, где открыто приложение, или открываем папку проекта в терминале

2. Инициализируем локальный гит репозиторий командой

git init

3. Добавляем удаленный репозиторий нашего проекта (url вашего репозитория будет отличаться. Во избежание синтаксических ошибок, скопируйте ссылку на втором шаге создания проекта)

git remote add amvera https://git.amvera.ru/имя_пользователя/имя_проекта

4. Добавляем файлы и делаем первый коммит

git add .
git commit -m "init"

5. Пушим наш код в репозиторий проекта

git push amvera master

Инициализация через интерфейс

Для добавления файлов этим способом нам потребуется просто перетащить файлы проекта в область на сайте

После добавления файлов создаем конфигурационный файл

Для этого переходим по ссылке и генерируем файл

Среди окружений выбираем Go. Остальные конфигурации оставляем по умолчанию (изменяйте, если вам это требуется)

После этого нажимаем кнопку "Generate YAML", после чего сохраняется конфигурационный файл amvera.yml

Этот файл мы загружаем в репозиторий проекта.

Важно: Файл amvera.yml появился в удаленном репозитории, но локально его у нас пока нет. Добавьте yml файл в репозиторий, чтобы при будущих обновлениях нашего приложения Git не выдавал ошибку.

Перейдите в терминал IDE.

Введите:

git pull amvera master

Подключаем SQLite

Так как SQLite - встроенная база данных, много изменений делать нам не придется.

Заходим в код приложения. Создание БД будет выглядеть примерно так:

package main
 
import (
	"database/sql"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
)
 
func main() {
	// Открываем соединение с базой данных
	db, err := sql.Open("sqlite3", "example.db")
	if err != nil {
    	fmt.Println("Ошибка при открытии базы данных:", err)
    	return
	}
	defer db.Close()
 
	// Проверяем, что соединение действительно открыто
	err = db.Ping()
	if err != nil {
    	fmt.Println("Ошибка при проверке соединения с базой данных:", err)
    	return
	}
	fmt.Println("Соединение с базой данных установлено успешно")
}

Меняем путь сохранения файла БД. Для этого пишем вместо (на моем примере) "example.db" - "/data/example.db".

Теперь наша БД будет сохраняться в /data.

Проверяем работоспособность проекта

Для этого переходим в проект, нажимаем на кнопку "Пересобрать проект" в панели кнопок.

Панель кнопок

Далее нажимаем "Перезапустить проект".

После того, как мы перезапустили проект, какое-то время мы будем видеть статус "Выполняется запуск", после чего, если все выполнено верно, покажется статус "Успешно развернуто".

Возможные проблемы

●  Бесконечный статус "Выполняется запуск"

Если вы наблюдаете неизменяемый статус, значит, у вас проблема с конфигурационным файлом (amvera.yml). Попробуйте пересоздать файл по предложенному ранее способу. Также вы можете создать конфигурационный файл через вкладку "Конфигурация". 

Также данная ошибка может быть вызвана тем, что вы загружаете большой проект или выбрали недостаточный тариф для своего проекта. Чтобы исправить, выберите тариф выше текущего во вкладе "Настройки". 

●  "Ошибка работы приложения"

Данная ошибка может появиться перед статусом "Приложение запущено", в этом нет ничего страшного. Когда код только запустился, облако еще не может определить статус работы проекта.

Также, если данная ошибка не исчезает, возможно, вы допустили ошибку в коде проекта или неправильно настроили конфигурационный файл.

Важно: все статические файлы и файлы баз данных (SQLite) нужно загружать в постоянное хранилище /data. Это поможет сохранить их при пересборке и успешно запустить проект.

Описание других возможных ошибок вы можете прочитать в документации по ссылке.

Код проекта из примера
package main

import (
    "database/sql"
    "fmt"
    _ "github.com/mattn/go-sqlite3"
)

func main() {
    // Открываем соединение с базой данных
    db, err := sql.Open("sqlite3", "example.db")
    if err != nil {
        fmt.Println("Ошибка при открытии базы данных:", err)
        return
    }
    defer db.Close()

    // Проверяем, что соединение действительно открыто
    err = db.Ping()
    if err != nil {
        fmt.Println("Ошибка при проверке соединения с базой данных:", err)
        return
    }
    fmt.Println("Соединение с базой данных установлено успешно")
}

Результат: мы успешно развернули на сервере Go приложение с SQLite, таким образом, что обновлять его можно простой командой в терминале - git push.

Комментарии (11)


  1. kirillkosolapov
    26.04.2024 09:33

    А куда лучше сохранять статические файлы в данном случае?


    1. ovchinnikovproger Автор
      26.04.2024 09:33
      +1

      Для данного примера лучше все статические файлы, как и файлы базы данных сохранять в директорию постоянного хранилища. Она задается в конфиге, но по умолчанию /data. И путь в коде соответственно будет /data/имя_файла


      1. ovchinnikovproger Автор
        26.04.2024 09:33

        Кирилл, в продолжении комментария, спасибо, добавил информацию в статью. P.S. Тут можно править статьи, не обязательно в комментариях раскрывать уточнения)


    1. gudvinr
      26.04.2024 09:33
      +1

      Если у вас веб морда сайта в статике - можете через go:embed в приложение встроить


    1. gudvinr
      26.04.2024 09:33
      +2

      CEO Amvera

      Могли бы и в рабочем чате спросить у коллеги


  1. alexdora
    26.04.2024 09:33

    Интересная идея, развертка не виртуалок, а go приложений. Остался главный вопрос у меня, почему так дорого. За 170₽ в месяц можно купить на самом нищенском сервисе виртуалку с безумным оверсейлом и все равно отдадут мощностей больше. Или я неправильно посчитал?


    1. ovchinnikovproger Автор
      26.04.2024 09:33

      Тут зависит за что платить, в том же Heroku это стоит 7-25$ (а не 170 руб.) и люди им платят. И тут вопрос, что VPS, что подобный GitOps сервис будут стоить примерно одинаково, разница в условные 20 рублей не в счет. Но на VPS часть ресурса будет отъедать операционка, что в сухом остатке оставит примерно столько же ресурса. И обновлять через одну команду git push намного проще, чем возиться с VPS каждый раз. Если бы это не имело смысла, несколько миллионов разработчиков по всему не пользовались бы сервисами с данной механикой


      1. alexdora
        26.04.2024 09:33

        Вы что-то странное пишите, что я не понимаю. Я постараюсь ответить:

        1. Начнем с простого, сидеть сравнивать цены с неким сервисом: вот там платят столько-то – неверно. Я плачу за колокейшен 1U сервер в России около 3000р, в амстердаме за сервер на круг электричество/место/интернет 1U у меня - 400евро, в США обходится около $300.

        2. Часть ресурса отъедает операционка. Давайте изучим, есть: ESXI 7, 340 VPS (там и линуксы, и вин стоят и все включены), сервер является резервным поэтому VPS просто включены и не выполняют никакой работы...ждут так сказать сигнала перехватить нагрузку на себя. Специально для вас зашел в Vcenter:

        1.03 GHz used

        79.9 GHz capacity

        Прям так отжирает, что вешаться хочется. Поэтому для меня это чистая байка, о том что ОС VPS что-то там отжирает. С точки зрения затрат продать мощность эффективнее.

        3. "И обновлять через одну команду git push " я в каком-то зазеркалье живу, вот все виртуалки о которых я сказал выше, используют git и сами все пакеты обновляют. На настройку я потратил... скажем 10 секунд. Это скрипт SH c 8 строками.

        "Если бы это не имело смысла, несколько миллионов разработчиков по всему не пользовались бы сервисами с данной механикой"

        Простите, это гнилой аргумент. Несколько сот миллионов человек ежедневно делают дичь, но это никак не превращает безумные вещи в нормальные.


      1. alexdora
        26.04.2024 09:33

        Еще раз повторю. Сама идея она прикольная, я не буду спорить с этим.
        Например, у меня ожидания от такой идеи даже вопрос не стоимости, а конкретных потребленных ресурсов как на AWS c почасовой/поминутной тарификацией.

        У AWS к примеру при покупке мощности ты можешь заплатить овердохрена денег просто за простой. Тут само приложение включилось и считается. И самое интересное, что многие бы этим пользовались. Кинул 100₽ на счет, включил приложение – считается, оно спит списывываются какие-то микрокопейки и слава богу. Зато у тебя под рукой есть всегда возможность нажать кнопку и включить: бота, резерв и прочее.

        Жаль что я увидел совсем другое. Но мои ожидания – мои ожидания.


  1. gudvinr
    26.04.2024 09:33

    Heroku - иностранный сервис c нативной поддержкой Golang-окружения.

    Что такое Golang окружение? Go приложения линкуются статически и им кроме glibc не надо ничего для запуска. Это же не ruby, php или python

    А в некоторых случаях можно и без glibc собрать.

    0,1 Гб оперативной памяти, 0,1 Гб хранилища и до 0,1 vCPU

    Это шутка какая-то? За 190р в ruvds можно арендовать впс с 512Мб ОЗУ И 10Гб SSD.

    Причем деплой будет выглядеть не сложнее go build && rsync

    Подозреваю, что в лимиты на дисках не входят данные в БД, но на сайте ничего нет об этом. Зато есть предупреждение:

    Внимание

    Стабильная работа возможна на тарифах не ниже «Начальный».

    А на тарифе за 170р, видимо, работает как повезёт


    1. ovchinnikovproger Автор
      26.04.2024 09:33

      Запуск в контейнере и на виртуальной машине немного разные вещи. В ВМ - часть ресурса съест ОС, тут - это чисто для приложения. В Heroku столько-же ресурса при непрерывной работе будет 7$ - и как и писал выше, ими многие (более миллиона пользователей) пользуются, так-как если вам нужно хостить часто обновляемый проект - это просто удобно. Т.е. это не лучше и не хуже VPS, просто другое, немного для других сценариев. В одном случае одно удобно, в другом - другое