Хостим в облаке вебсайт с гостевой книгой бесплатно


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


Предлагаю вам разобрать то, как можно создать гостевую книгу на ASP.NET Core (с reCAPTCHA) и захостить ее бесплатно на довольно известном облачном хостинге (да, с ограничениями, но для персонального вебсайта с не особо большим трафиком годится вполне)


В качестве базы данных мне по душе пришлась MongoDB от Atlas. Ее тоже можно "заюзать" бесплатно.
Альтернативно есть еще неплохие варианты в виде DynamoDB с какими-то бесплатными лимитами и Firebase Firestore.


Приложение будет докеризированно. Но так как "присутствует отсутствие желания" устанавливать докер локально, то настроим pipeline для автоматической сборки и публикации образа Docker-а (само-собой тоже бесплатно)


Сам исходник гостевой книги вы можете найти на github
Рассматривать код подробно не буду. Вкратце только рассмотрю добавление reCAPTCHA v3. Recaptcha для гостевой книги это Must. Причем, Recaptcha 3-ей версии не напрягает пользователя вводом символов.


Использование reCAPTCHA


Завести аккаунт и получить SiteKey и SecretKey можно в консоли админа Google reCAPTCHA.
Не забудьте добавить localhost (временно на время разработки) и url вашего вебсайта в список доменов (он находится в сеттингах)


Админка reCAPTCHA


Цепляем скрипт с ключиком взятым из сеттингов приложения в качестве параметра:


<script src="https://www.google.com/recaptcha/api.js?render=@Configuration["ReCaptcha:SiteKey"]" async defer></script>

И в событии отправки содержимого формы добавляем токен reCAPTCHA (отправляем без использования jQuery “ортодоксальным” XMLHttpRequest)


grecaptcha.ready(function() {
  grecaptcha.execute('@Configuration["ReCaptcha:SiteKey"]', {action: 'homepage'}).then(function(token) {
    xhttp.open('POST', '@Url.Action("AddMessage", "Home")', true);
    xhttp.setRequestHeader("RequestVerificationToken", 
    document.getElementById('RequestVerificationToken').value);
    var formData = new FormData(document.forms.message);
    formData.append("Token", token)
    xhttp.send(formData);
  });
});

В качестве заголовка устанавливается AntiForgeryToken. Это другой токен, без которого тоже никак.
Для того чтобы убедиться, что запрос не был отправлен роботом или спамером, необходимо отправить токен полученный от reCAPTCHA и секретный ключ на адрес www.google.com/recaptcha/api/siteverify


Для этого нам понадобится HttpClient. Создавать HttpClient используя конструкцию using совсем не в концепте ASP.NET Core. В Core принято создавать фабрику HttpClientFactory. Создается она просто. В Startup.cs добавляется строчка


services.AddHttpClient();

И затем уже в конструкторах контроллеров мы можем извлекать/создавать из DI экземпляры клиентов. Например, так:


private readonly HttpClient _httpClient;
public HomeController(IHttpClientFactory httpClientFactory)
{
  _httpClient = httpClientFactory.CreateClient("defaultClient");
}

Проверяем reCAPTCHA так:


var parameters = new Dictionary<string, string> {
                { "secret", _configuration["ReCaptcha:SecretKey"] },
                { "response", model.Token } };
var encodedContent = new FormUrlEncodedContent(parameters);
var response = await _httpClient.PostAsync("https://www.google.com/recaptcha/api/siteverify", encodedContent);
var result = JsonConvert.DeserializeObject<ReCaptchaResponse>(await response.Content.ReadAsStringAsync());

При этом сам класс ReCaptchaResponse:


public class ReCaptchaResponse
{
    public bool success { get; set; }
    public double score { get; set; }
    public string action { get; set; }
    public string hostname { get; set; }
    public string challenge_ts { get; set; }
}

Создание бесплатной облачной базы данных


При регистрации аккаунта в MongoDB Atlas.
Необходимо ввести номер телефона и еще какие-то персональные данные. Бесплатный Starter cluster предназначен для изучения MongoDB и для небольших приложений. Интересно то, что вы можете выбрать не только регион, но провайдера облачного хостинга вашей базы на свой вкус из трех самых крупных


Выбор региона и провайдера в MondoDB Atlas


После создания кластера вам необходимо будет создать пользователя


Создание пользователя


и придется добавить все IP с список разрешенных (к сожалению, бесплатный план хостинга Heroku не предоставляет статического IP).


Удар по безопасности в виде разрешения доступа со всех IP


Теперь нам остается только создать базу данных и коллекцию


Главный экран админки


Кликаем на COLLECTIONS и далее на Add my own data


Окно из которого можно создать коллекцию


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


Создание коллекции


Кликнув на Connect и выбрав Connect Your Application


Получение строки подключения


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


Получение строки подключения


Создание приложения Heroku


Создание приложения на Heroku


Там все реально просто. Даже кредитку можно не привязывать при регистрации аккаунта.


Создание pipeline для публикации образа в Docker Hub


В проекте создадим Dockerfile с довольно обычным содержимым (приведен пример файла для версии .NET Core 2.2)


FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 64498
EXPOSE 44396

FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src

COPY Guestbook.csproj Guestbook.csproj
RUN dotnet restore
COPY . .
WORKDIR /src
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Guestbook.dll"]

Для того, чтобы Heroku смог запустить образ, последнюю строчку необходимо будет изменить на


CMD ASPNETCORE_URLS=http://*:$PORT dotnet Guestbook.dll

Исходный код необходимо запушить в какую-нибудь систему контроля версий. Я запушил в GitHub.
После того как код помещен в GitHub для сборки образа докера становится возможным использовать Azure Devops. Эту часть статьи вы можете промотать, установить Docker локально и пересобирать все каждый раз вручную.


Создание проекта опишу скринами


Создание проекта в Azure DevOps


После того как создадите сам проект необходимо создать новую pipeline


Создание Pipeline


и выбрать систему контроля версий которую вы используете


Выбор системы контроля версий


Теперь можно выбрать репозиторий


Выбор репозитория


Далее необходимо будет авторизовать DevOps для доступа к репозиторию.
И можно будет выбрать тип конфигурации (yaml файл определенного типа будет создан автоматически)


Выбор типа конфигурации


Наш вариант это Docker.
В открывшемся окошке нужно указать путь к Docker файлу:


Путь к докер файлу


На следующем шаге вам будет отображено содержимое yaml файла.


Можете подумать и поколдовать над ним сами, но проще скопировать следующий код и заменить в нем некоторые значения (Внимание! Пробелы в yaml очень важны):


variables:
  dockerId: your-docker-login  # Replace with your Docker ID for Docker Hub or the admin user name for the Azure Container Registry
  imageName: mongodb-guestbook  # Replace with the name of the image you want to publish

steps:
- script: |
    docker build -t $(dockerId)/$(imageName) .
    docker login -u $(dockerId) -p $(dockerPassword)
    docker push $(dockerId)/$(imageName)

    docker login --username=_ --password=$(token) registry.heroku.com

    docker build -t registry.heroku.com/myfreeguestbook/web .
    docker push registry.heroku.com/myfreeguestbook/web

your-docker-login вам нужно заменить на ID вашего аккаунта докера
mongodb-guestbook меняйте на имя вашего образа
вместо myfreeguestbook вставьте имя вашего приложения на Heroku


Останется ввести значения переменных dockerPassword и token. Для этого нужно нажать Variables


Кнопка Variables


Ну и ввести пароль от аккаунта докера. И токен..


Окно Variables


Если где взять пароль от аккаунта докера понятно, то для того чтобы получить токен нам понадобится Heroku CLI
Скачать ее можно по следующей ссылке: Download and install
Можно установить standalone/portable версию.


Вход осуществляется с помощью одной из следующих команд: heroku login (эта команда откроет окно браузера для логина) или heroku login -I (эта команда запросит пароль в консоли)


Токен получается с помощью команды


heroku auth:token


Также желательно изменить тип приложения Heroku на container. Делается это командой:


heroku stack:set container -a myfreeguestbook


Не забудьте изменить myfreeguestbook на имя вашего приложения.


После того как pipeline отработает и создаст образ докера необходимо выполнить команду публикующую ваше приложение:


heroku container:release -a myfreeguestbook


Если вы правильный разработчик и храните все сеттинги в файле appsettings.Development.json, то проект у вас не поднимется. Для того чтобы все заработало необходимо добавить сеттинги в Heroku


Значения конфигурации приложения Heroku


Дочерние элементы json отделяются двойными подчеркиваниями __


Настройка домена и SSL


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


Команда:


heroku domains:add www.example.ru


Выдаст вам что-то вроде:


Adding www.example.ru to ? example-app… done
? Configure your app's DNS provider to point to the DNS Target
? whispering-willow-5678.herokudns.com.
? For help, see https://devcenter.heroku.com/articles/custom-domains
Ее необходимо повторить для вашего root домена (например, для example.ru)

Псевдонимы CNAME необходимо сохранить и добавить в качестве CNAME на портале регистратора вашего доменного имени


www whispering-willow-erkie5ugksj4fo.herokudns.com


@ mighty-horse-dvkerbibi34biufbwiieuf.herokudns.com


Можно добавить их сразу в редактор произвольных записей DNS:


www.example.ru. IN CNAME whispering-willow-erkie5ugksj4fo.herokudns.com.


@.example.ru IN CNAME mighty-horse-dvkerbibi34biufbwiieuf.herokudns.com.


Можно сделать так.


Но мне больше по душе вариант завести бесплатный аккаунт в cloudflare. Ведь Cloudflare предоставляет бесплатный SSL сертификат. В качестве Content необходимо указать CNAME значения полученные от Heroku. У меня еще, как видите, добавлена и бесплатная Яндекс почта для домена.


Настройка CloudFlare


Ну а то, что будет указано в значениях Cloudflare nameservers вам нужно будет указать в виде DNS серверов на сайте вашего доменного регистратора.


В результате получится, что CloudFlare является посредником между вашим DNS провайдером и Heroku.

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


  1. jehy
    16.10.2019 00:00
    +6

    Раз пять пытался придумать смешной комментарий про то, что даже сам термин "гостевой книги" ушёл в небытие уже лет 10 как… Но смешнее, чем заголовок поста в сочетании с тегами и 2019 годом — не выходит.


    1. PaulAtreides
      16.10.2019 12:03

      Гостевой книги на asp


  1. Coocos
    16.10.2019 00:36
    +2

    Странно в 2019 году изобретать схемы халявного размещения сайта. Ну только ради спортивного интереса. Полно хостингов и VDS с ценниками до 100 рублей в месяц.


    1. ctacka
      16.10.2019 02:44
      +1

      У бесплатного хостинга все же то преимущество, что захостил и забыл.


    1. asommer Автор
      16.10.2019 08:22

      Хостинг + база данных + SSL. Далеко не 100 получится. Но да, и спортивный интерес и желание не парится особо по поводу ежегодных оплат.


      1. Coocos
        16.10.2019 08:23

        Базу данных обычно предоставляют в рамках хостинга.


      1. pae174
        16.10.2019 11:54

        > Хостинг + база данных + SSL. Далеко не 100 получится.

        Бюджетный VDS за 100 рублей в месяц вполне себе получится. SSL бесплатно выдаст Cloud Flare — он же и защитит от всяких мелких пакостей.


      1. altervision
        17.10.2019 07:49

        Полностью согласен, получится далеко не 100. Сотки тут много, я в 72 рубля умещаюсь (€1) в месяц. VDS от ArubaCloud со связкой Debian + NGinx + PHP-FPM + MariaDB. Но объёмы куда более скромные: всего два десятка сайтов на WordPress (и не только) объёмом чуть больше 13 ГБ файлов и порядка 2 ГБ данных, в общей сложности около 35 тысяч страниц с небольшой общей суточной посещаемостью порядка 500 уников (не считая ботов). Очень дорого выходит, евро же на пять копеек подорожал.


  1. symbix
    16.10.2019 03:31

    О, я когда-то делал свой сайт с гостевой книгой на перле, на бесплатном хостинге. В 2001 году, кажется.


    Есть же GitHub pages, зачем такие сложности? Даже домен можно не покупать.


    1. xenon
      16.10.2019 16:29

      .tk бесплатно. Только надо переодически продлять (кнопки жать). (сорри, не прочитал пару строк ниже)


  1. ValdikSS
    16.10.2019 04:40

    Аналогичное можно сделать на netlify, даже домен не нужен.


  1. APXEOLOG
    16.10.2019 07:56

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

    Более того, даже доменное имя не нужно. Например AWS S3 hosted bucket сам вам публичный адрес сгенерирует


    1. asommer Автор
      16.10.2019 10:03

      Перефразировал


  1. pae174
    16.10.2019 08:01
    +1

    > достаточно купить доменное имя
    Бесплатно можно взять на freenom.com в зонах tk, ml, gq, ga, cf.
    Только для регистрации нужен адрес электронной почты и бесплатные адреса вроде mail.ru там не срабатывают.


    1. asommer Автор
      16.10.2019 08:15

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


      1. pae174
        16.10.2019 11:29

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


        1. 0NotNull
          16.10.2019 16:27

          Мне предлагали купить, бесплатно только первый год.


          1. xenon
            16.10.2019 16:39

            Не совсем так. Они просто пытаются монетизироваться, поэтому «подталкивают» к этому. Платный домен — можно на много лет вперед оплатить. Бесплатный — только на год (а через год — надо продлить. Если забыть и забить — он проэкспарится). В общем-то как и с обычным доменом. Единственное ограничение — продлевается бесплатно домен только на год за раз, не более. Хотя мне даже помнится, что даже на еще более короткий срок может быть.


            1. pae174
              16.10.2019 17:25

              > даже на еще более короткий срок может быть

              От одного месяца до 12 месяцев.
              Продление возможно за 2 недели до истечения срока регистрации.


  1. PaulAtreides
    16.10.2019 12:03

    Что, как там дела в 1999?

    Хотите спойлер?
    Ельцин уйдёт в отставку 31 декабря


  1. Alexus819
    16.10.2019 12:53

    свой домен первого уровня

    может и корневой DNS сразу до кучи? и тоже в облаке…


  1. Chugumoto
    16.10.2019 13:35

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

    простите какого-какого уровня?


  1. Brain_Overload
    16.10.2019 17:53
    +1

    статья, как не надо делать в 2019) (про домен первого уровня спасибо, посмеялся)