Как запустить сайт на Golang

Хостинг - как запустить сайт на golang

В хостинге некоторые решения могут показаться вам нестандартными.
Поэтому перед началом работы мы бы рекомендовали ознакомиться с вводной статьей.

В рамках облачного хостинга возможно разместить сайты, написанные на множестве языков программирования.

Ваш сайт может быть написан на C, C++, golang или другом языке программирования.

В рамках этой статьи мы, в качестве примера, запустим простой сайт на golang.

Скачать golang можно на официальном сайте.

Предположим у нас уже есть приложение, которое при запуске прикрепляется (bind) к порту 80.

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r * http.Request) {
        fmt.Fprintf(w, "Welcome to the Internet! Please follow me.\n")
    })

    http.ListenAndServe(":80", nil)
}

При обращении к сайту приложение выводит лишь одну строку текста Welcome to the Internet! Please follow me.

# curl  0.0.0.0:80
Welcome to the Internet! Please follow me.

Если бы мы захотели разместить это приложение на хостинге, то нам бы потребовалось немного его изменить. Прежде всего, на хостинге мы не можем прикрепляется (bind) к порту 80, поскольку он уже занят вебсервером nginx.

Поэтому приложению потребуется прикрепиться на IP и порт, указанные в переменных окружения APP_IP и APP_PORT.

Изменим код нашего приложения таким образом, чтобы прикрепляться к APP_IP и APP_PORT. Переменные окружения мы будем получать при помощи модуля os, встроенного в golang.

package main

import (
    "os"
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Welcome to the Internet! Please follow me.\n")
    })

    // создадим переменные APP_IP и APP_PORT, а их значения возьмем из одноименных переменных окружения
    APP_IP := os.Getenv("APP_IP")
    APP_PORT := os.Getenv("APP_PORT")

    fmt.Println(APP_IP+":"+APP_PORT)
    http.ListenAndServe(APP_IP+":"+APP_PORT, nil)
}

Сохраним этот код в файл welcome.go.

# ls -l
total 4
-rw-r--r-- 1 root root 629 Sep  4 10:23 welcome.go

Скомпилируем его

# go build welcome.go
# ls -l
total 5564
-rwxr-xr-x 1 root root 5689373 Sep  4 10:25 welcome
-rw-r--r-- 1 root root     629 Sep  4 10:23 welcome.go

Полученный файл welcome осталось загрузить на хостинг.

Создадим новый сайт на хостинге.

При создании сайта в качестве конфигурации выберите “EXE”:

Настройки

Для загрузки файла подключитесь к хостингу через FileZilla.

Загрузите файл welcome в каталог sitename/app.

После загрузки файла, в FileZilla кликните правой кнопкой на файл и выберите “Права доступа к файлу”. В поле “Числовое значение” укажите 755.

Далее откроем панель управления и перейдем в созданный сайт. Откроем вкладку Python AsyncIO и в строке “APP_PATH” укажем полный путь до файла. Например /home/c0000/mydomain-async.com/app/welcome.

Осталось со своего компьютера проверить все ли работает корректно:

user@local-pc:~$ curl http://mydomain-async.com/
Welcome to the Internet! Please follow me.
user@local-pc:~$

Готово!

Если вы планируете отлаживать работу сайта локально, и только потом загружать на хостинг, то достаточно локально создать переменные APP_IP и APP_PORT.

user@local-pc:~$ export APP_PORT=8081
user@local-pc:~$ export APP_IP=127.0.0.1
user@local-pc:~$ env | grep 'APP_'
APP_PORT=8081
APP_IP=127.0.0.1
user@local-pc:~$ ./welcome
127.0.0.1:8081

После этого

user@local-pc:~$ curl 127.0.0.1:8081
Welcome to the Internet! Please follow me.



Cборка приложения без использования динамически подключаемых библиотек

Одна из сложностей при сборке приложений заключается в том, что приложение успешно собранное и работающее на вашем компьютере может не работать на других. Например приложение собранное в Ubuntu 22.04 из-за разницы в версиях библиотеки glibc может не работать в Debian 9 Stretch. Один из способов позволить приложению корректно запуститься в окружении сервера хостинга - это скомпилировать приложение без использования внешних библиотек.

Рассмотрим детальней полученный на прошлом этапе исполняемый файл

user@local-pc:~$ file welcome
welcome: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=9rzcu_tW7FPaZZ6_MEWj/X7Isq3NKMxj4D8uz87yS/MSlxJelyutuv2Dc8p77R/X1S-Kc6BRngxA1qRrSZG, not stripped

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

С помощью утилиты ldd можно увидеть какие библиотеки требуются для работы исполняемого файла

user@local-pc:~$ ldd welcome
    linux-vdso.so.1 (0x00007f42eb35e000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f42eb152000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f42eb360000)

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

user@local-pc:~$ go build -tags 'netgo' -ldflags "-s -w -extldflags -static" welcome.go
user@local-pc:~$ file welcome
welcome: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=mfZp2e-AVBGm2ZZWRoD5/wtGxpCfPjcRqCSYJu823/qKgNidYPsL4IF139tWFE/vOqs3bU0lFwPVnIGzzUL, stripped

Из вывода утилиты file следует, что исполняемый файл собран статически, а это значит, что независимо от окружения в котором он собирался, независимо от версий библиотек, он успешно запустится на сервере хостинга.



Сборка приложения в docker-контейнере

Альтернативой сборке статического приложения стоит рассмотреть сборку приложения в docker-контейнере. Идея такого способа в том, что сборка приложения будет производиться в окружении максимально близком к окружению сервера хостинга, что позволит при сборке приложения использовать те же версии библиотек. Данная глава подразуемает, что у вас в системе уже установлен Docker и у вашего пользователя есть возможность запускать контейнеры без использования утилиты sudo

Для начала нужно определиться в каком окружении будет запускаться ваше приложение. Это можно узнать подключившись к вашему контейнеру по SSH и выполнив команду cat /etc/debian_version

c0000@h0:~$ cat /etc/debian_version 
10.12
c1111@h1:~$ cat /etc/debian_version 
9.13

Такой вывод говорит о том, что контейнер c0000 использует окружение Debian 10 Buster, а контейнер c1111 Debian 9 Stretch.

Сейчас необходимо перейти в каталог с исходным кодом вашего приложения и выполнить следующие команды

Команда для сборки приложения в контейнере с окружением Debian 9 Stretch:

user@local-pc:~$ docker run --rm -e GO111MODULE=off -v "$PWD":/usr/src/welcome -w /usr/src/welcome netangels/golang-1.18:stretch go build -v 

Команда для сборки приложения в контейнере с окружением Debian 10 Buster:

user@local-pc:~$ docker run --rm -e GO111MODULE=off -v "$PWD":/usr/src/welcome -w /usr/src/welcome netangels/golang-1.18:buster go build -v 

После этого в каталоге вашего приложения появится исполняемый файл, который вы сможете загрузить в ваш контейнер

user@local-pc:~$ file welcome
welcome: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=irT9CJLwkq1tFmj-BrTH/L-3o73raCE4WYXPHmNCi/lBNEacOmp4jIpOC06D7R/6h30njUA-Xokp6hVEF5P, not stripped
user@local-pc:~$ ldd welcome
    linux-vdso.so.1 (0x00007ffe5a55e000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f24ad0c0000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f24acecc000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f24ad0d9000)



Больше информации об хостинге.

Хостинг
Хостинг
Хостинг
Создавайте неограниченное количество сайтов в изолированных контейнерах
С 2003 года
Надежность.
Нам доверяют десятки тысяч компаний и разработчиков
20 лет
Предоставляем услуги профессионального хостинга
35 000
Клиентов доверяют нам размещение своих сайтов
99.99%
Подтвержденный uptime
наших серверов хостинга
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
Наши клиенты
ВК49865