Эта статья может быть полезна желающим хостить проекты подешевле, когда есть только мобильный интернет, нет требований к быстрой работе, высокой нагрузке и маленькому даунтайму.
Введение (можно пропустить)
Расстался я со своей прекрасной работой разработчика, отдохнул пару месяцев, погулял по лесу, потрогал траву, послушал птиц и посмотрел на солнце.
Сижу и вспоминаю, что давно хотел сильно уменьшить плату за облака, где крутятся петпроекты и несколько проектов клиентов. У всего этого добра запросов мало, но не мало оперативной памяти требуется. На все вместе тратится около 2,5к рублей в месяц, за год набегает 30к, которые могли бы и в кармашке остаться.
Задавшись целью экономии приступил к изучению. Ничего страшного, если иногда сервисы будут недолго лежать. RPS высокого нет.
Возможности и исследование
Как полагается, у меня есть несколько компьютеров. 1 рабочий и остальные, которые почти не используются. Собственно, давно зрел вопрос: Зачем мне арендовать сервер, если можно крутить все на не используемом добре?
Вариант 1
Вариант напрямую развернуть у себя обращаться к своему ip сразу отпал почти сразу. Интернет у меня мобильный, ни один из опрошенных провайдеров белый ip не дает. Провести проводной в съемной квартире нельзя. Вдобавок не откажусь от возможность если что сорваться с места и быстро развернуть все в новом гнездышке.
Вариант 2
Ладно, я начал искать решение как можно хостить у себя сервер с динамическим ip. Нашел идеи с DDNS (Dynamic DNS).
Для работы сайта требуется:
Зарегистрироваться на ресурсе, предоставляющим DDNS.
Сделать через api или инструменты ресурса постоянное обновление IP.
Настроить домены свои или использовать домены ресурса для хостинга.
Сделать SSL сайту такими методами самому не получится или сложно или использовать тот, что предлагает сам провайдер DDNS. IP же динамический, SSL для такого тоже придется регулярно обновлять.
В итоге оказалось, что несмотря на описанную в документации возможность, мой роутер с симкой отдавать наружу ни один порт, кроме своего собственного с админкой не может. Несколько вечеров было потрачено в пустую.
Ресурсы с DDNS https://www.noip.com/ — тут была проблема с хостом, они предлагали свой, их не много, да и у меня свои нормальные, домен третьего уровня не нужен. https://www.cloudflare.com — вроде может быть рабочим решением, я в него не копал ввиду того, что роутер не открывается наружу.
Решение (в моем случае)
Вариант 3 (Рабочий)
Вспомнил, что тоннели можно прокладывать не только с сервера к себе локально, но и с локали на сервер. И вроде это защищенное, надежное соединение.
Бинго.
Низкая скорость, да и фиг с ней. Главное, что обрабатывается вообще. А несколько запросов в секунду меня не волнуют.
Облако в итоге таки понадобится, но стоить все будет сильно дешевле.
Такой скрипт позволяет прокинуть порт 18001 с локальной машинки на сервер, где он превратится в порт 18002.
ssh-R 18002:localhost:18001root@11.22.33.444 -N -v -f Так можно прокинуть порт напрямую. ssh-R 18001:localhost:18001root@11.22.33.444 -N -v -f
Дальше дело за малым. Сделать так, чтобы снаружи можно было обратиться на внутренний (уже) порт на сервере с белым ip. Тут поможет NGINX. proxy_pass может передать запрос дальше куда нужно.
upstream11.22.33.444:8001 {
server localhost:8001 fail_timeout=0;
}
server {
listen8001 default_server;
server_name _;
location / {
proxy_pass http://localhost:18001/; # эта строчка стучится к локальному серверу
}
}
в server и upstream может быть ваш хост example.com порт от тоннеля сайта localhost и порт внешний лучше использовать разные.
Сайт доступен по адресу 11.22.33.444:8001
NGINX позволяет сделать сайту SSL сертификат и иметь https соединение. Делается это с помощью Lets encrypt и Certbot, а разрешается самим NGINX. Можно даже на ip сервера сделать сертификат, но он не особо котируется браузерами так как найдеными методами он выдан сам себе, а не солидной организацией.
Дальше оказалось, что такой тоннель может не жить долго. Моргает сеть, что-то тупит, зависает, что угодно. Понадобилось периодически его заново запускать или перезапускать. Для такого был сделан скрипт ниже. Он ищет ssh процессы с нужным портом, убивает его, а после запускает тоннель заново.
От такого сайт может на пару секунд прилечь с ошибкой NGINX 502 Bad Gateway, но это в моем случае ок.
Автоматизация
Тоннель может отвалиться, сеть может моргнуть, все это может зависнуть. С этим нужно что-то сделать, не мониторить и не запускать же это все заново.
Решил сделать другой процесс на CRON (а точнее Celery Beat), который будет крутиться и периодически перезапускать все мои тоннели. Так же он может пинговать работу сайта и вдруг чего снова прокинуть тоннель.
Для этого использовал проект на питоне и модуль subprocess
Скрипт берет список команд и запускает их последовательно. Команды можно форматировать (f-string). Если нужно запустить несколько разом - можно сделать это всякими методами bash , например сделать ' | '.join([...]) и прогнать как одну команду.
Все это у меня вылилось в очередной маленький проект на Django с админкой подобных команд.
Он сам убивает и запускает тоннели, сам делает database dump у проектов, складывает нужные файлики в облачное хранилище и прочие автоматизации, чтоб не задумываться регулярно и не запускать все ручками.
А потом я наткнулся на проект https://pico.sh если хочется меньше заморачиваться с тоннелями, то можно использовать его и подобных.
Заключение
Мое решение не убирает полностью затраты на сервер. Мне все еще нужно арендовывать облако с белым ip, но делается это теперь за 150р, а не за 2,5к. Да и под вопросом сколько тратится электричества на то, чтобы сайты постоянно крутились. Возможно держать в облаке в итоге дешевле выйдет.
Пока в планах запустить эту связку на каком-нибудь микроконтроллере (Raspberry Pi, Оrange Pi и т.п.), но его еще нужно выбрать и купить.
Этот же механизм с тоннелями можно использовать, когда нужно прокинуть локальный сайт с компа backender-а на комп frontender-а. Прокинуть порт со своего компа после утверждения, что "на моем работает". Или просто показать клиенту прототип без раскатывания на другой машинке.