Два года я исправно заносил деньги хостерам. Сначала это были копейки за пару vps, потом захотелось управляемую базу данных, потом s3 для бекапов, и вот я уже смотрю на счет в 40 долларов ежемесячно за проекты, которыми пользуюсь я и полтора моих друга.
В какой-то момент жаба победила. Я посмотрел на полку, где пылился списанный корпоративный ноутбук с мертвой батареей, и решил: пора.
Если вы думаете, что это история про успешный успех и экономию - вы ошибаетесь. Это история про боль, перегрев и Docker на bare metal, но я ни о чем не жалею.
Вводные данные были так себе.
Ноутбук 2015 года. Core i5, 8 ГБ памяти, ssd на 256. Экран разбит, клавиатура залита кофе еще прошлым владельцем.
Главный плюс ноутбука в качестве домашнего сервера - встроенный ups. Батарея держала минут 15, но этого хватало, чтобы пережить мигание света в подъезде и корректно погасить базу, если электричество отрубили надолго.
Я накатил туда ubuntu server, кинул ноутбук под шкаф в прихожей и подключил витую пару. Сразу совет: не используйте wifi для сервера, даже если роутер стоит в метре. Пакеты будут теряться, а вы будете терять нервы при дебаге, почему ssh отваливается каждые полчаса.
Главная проблема домашнего хостинга - белый ip. Провайдер просил за статику лишние деньги, а я встал на путь принципиальной экономии. DynDNS - решение из нулевых, которое работает криво.
Я пошел другим путем - Cloudflare Tunnel.
Штука гениальная. Ставите демона cloudflared на свой локальный сервер, он открывает исходящий канал до серверов Cloudflare, и весь трафик идет через их сеть прямо к вам под шкаф.
Никаких открытых портов на роутере. Никаких попыток брутфорса вашего ssh китайскими ботами. Снаружи торчит только 443 порт клаудфлера.
Внутри все завернуто в docker-compose.
Traefik в качестве прокси. Он сам получает сертификаты, сам роутит поддомены. Настраивается через лейблы в том же docker-compose файле.
Если вы до сих пор пишите конфиги для nginx руками - бросайте это дело.
Сразу к делу. Чтобы не быть голословным, вот кусок моего docker-compose.yml.
Самое важное тут - сервис cloudflared. Ему нужен только токен, который вы получаете в админке CF при создании туннеля. Никаких пробросов портов наружу, никакой возни с iptables.
Трафик попадает в туннель, вылезает внутри контейнера и отдается Traefik-у, который уже раскидывает его по сервисам (в примере ниже - тестовый whoami) на основе лейблов.
YAML
version: '3.8'
services:
# Тот самый туннель. Весит копейки, работает стабильно
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared-tunnel
restart: unless-stopped
command: tunnel run
environment:
- TUNNEL_TOKEN=${TUNNEL_TOKEN} # Токен лежит в .env файле рядом
# Прокси, который делает магию
traefik:
image: traefik:v2.10
container_name: traefik
restart: unless-stopped
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
# Тестовый сервис, чтобы проверить, что все живое
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.mydomain.com`)"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
Обратите внимание: 443 порт и ssl сертификаты тут не нужны. Cloudflare шифрует трафик до своего края, а внутри туннеля он уже летит в защищенном виде. Traefik просто слушает 80 порт внутри докер-сети. Это дико упрощает конфиг.
Где я облажался
Первая проблема пришла откуда не ждали. Ноутбук закрыт. Крышка плотно прилегает к корпусу. Через неделю аптайма кулер начал выть как турбина самолета.
Оказалось, что старые ноуты часть тепла отводят через клавиатуру. Закрывая крышку, я устроил внутри сауну.
Решение - напечатанные на 3d-принтере (читай: подложенные пробки от вина) ножки, чтобы приподнять крышку на пару сантиметров. Температура упала на 10 градусов.
Вторая проблема - база данных.
Пока проекты жили в облаке, я не думал о бекапах. Облако надежное, там репликация (нет).
Когда данные живут на старом ssd, который пережил три падения, паранойя выходит на новый уровень.
Я написал скрипт на bash (да, можно было взять готовое, но мы же инженеры), который каждую ночь дампит postgres, шифрует архив через gpg и пуляет его в бесплатный тир Google Drive через rclone.
Дешево, сердито, и я сплю спокойно.
Скрипт я набросал на коленке за 10 минут. Он тупой как пробка, поэтому и не ломается.
Логика простая:
Сделать дамп.
Зашифровать (потому что хранить базу в облаке в открытом виде - моветон).
Отправить через rclone.
Удалить старое локально.
Rclone предварительно настроен через rclone config, там все интерактивно, справится даже ребенок.
Bash
#!/bin/bash
# Настройки
BACKUP_DIR="/home/user/backups"
DATE=$(date +"%Y-%m-%d_%H-%M")
DB_CONTAINER="postgres_db_1"
DB_USER="myuser"
RCLONE_REMOTE="gdrive:backups/server"
# Создаем папку, если ее нет
mkdir -p $BACKUP_DIR
# 1. Дампим базу прямо из контейнера
echo "Starting dump..."
docker exec -t $DB_CONTAINER pg_dump -U $DB_USER mydb > $BACKUP_DIR/db_$DATE.sql
# 2. Шифруем архивом с паролем (gpg для эстетов, zip проще)
# Пароль берем из переменной окружения или файла, чтобы не светить в скрипте
echo "Encrypting..."
zip -P "SuperSecretPassword123" $BACKUP_DIR/db_$DATE.zip $BACKUP_DIR/db_$DATE.sql
# 3. Отправляем в облако
echo "Uploading..."
rclone copy $BACKUP_DIR/db_$DATE.zip $RCLONE_REMOTE
# 4. Убираем мусор за собой
rm $BACKUP_DIR/db_$DATE.sql
rm $BACKUP_DIR/db_$DATE.zip
# Очистка старых бекапов в облаке (храним 30 дней)
rclone delete $RCLONE_REMOTE --min-age 30d
echo "Done. Sleep tight."
Засунул это в crontab на 3 часа ночи - и забыл. Раз в месяц захожу проверить, что файлы на месте. Пока сбоев не было.
Экономика вопроса
Раньше: 40-50 долларов в месяц.
Сейчас: 0 долларов, плюс немного за электричество (ноут ест ватт 15-20 в простое).
Но есть нюанс.
За настройку всего этого я заплатил своим временем. Два выходных ушли на то, чтобы разобраться с туннелями, настроить мониторинг (Prometheus + Grafana, чтобы видеть красивые графики потребления памяти) и перенести данные.
Стоит ли оно того?
Если ваш час стоит 50 баксов - нет, проще заплатить амазону.
Но если вам нужен полигон, где можно сломать всё, поднять свой gitlab, nextcloud для фоток с телефона и медиасервер, и при этом не трястись над лимитами cpu - это идеальный вариант.
Плюс, чувство контроля над своим железом вызывает странную, почти забытую ностальгию. Теперь, когда я слышу, как под шкафом шумит кулер, я знаю: мой код работает.
Комментарии (4)

krendelbok
26.11.2025 08:26Спасибо за идею с Cloudflare, даже не думал об этом. Все тоже самое, но на NanoPi R76S и вместо гитлаба - forgejo, один бинарник и никаких руби зависимостей. + pihole для роутера, miniflux для rss, и synchting для важных файлов локально, типа базы паролей для keepassxc. А для бекапа у меня микросд + внешний ssd, что-нибудь да останется, если вдруг платка накроется. Кстати взял её в алюминиевом корпусе, чтобы не грелась особо. Пока за пару месяцев полёт отличный.

apcs660
26.11.2025 08:26спасибо за статью - для демок самое то. Если нужен GPU, то можно мелкий комп вроде minisforum + oculink использовать - у меня такая конфигурация нормально работает с docker+nvidia cuda - когда не используется карта, вентиляторы на ней не крутятся, шума нет, а при использовании охлаждение отличное (она открыта, на воздухе).
Сервер лучше всего делать бесшумным, если дома использовать с небольшой нагрузкой, чтобы вообще ничего не жужжало - лежит маломощный бесшумный мини комп с пассивным охлаждением N100, с питанием 12В (роутер как бы) - на нем попробую вашу конфигурацию. Использовал его для gitlab, репозитория maven + docker и прочего для локальной разработки.
Как совсем мини компактный вариант, можно еще NanoPi R5C Rockchip попробовать - от USB 2A работает, для него есть Ubuntu, но могут быть проблемы с пакетами и тд, не самый популярный cpu.

select26
26.11.2025 08:26Главная проблема домашнего хостинга - белый ip. Провайдер просил за статику лишние деньги, а я встал на путь принципиальной экономии.
Вы путаете public/private IP и механизм его выдачи. Это вообще разные понятия и технологии. Вы можете иметь публичный IP, который назначается динамически или приватный IP, назначаемый ISP статически. Если у вас есть публичный IP, то вы можете принимать входящие сосединения. DynDNS решений сейчас просто море.
DynDNS - решение из нулевых, которое работает криво.
Непонято в чем его кривизна? В том что оно из нулевых? Так DNS сам по себе вообще из 70-x. Прошлого века. Как и Интернет.
Хотя решение с CF tunnel красивое! И с traefik тоже красиво получилось.
Посдскажите пожалуйста, а умеет traefik также управлять внешними роутами, не внутри одного контейнера?
MxMaks
Хотелось бы уже, чтобы и свои ИИ ядра были. Поэтому у меня мини-пк с ИИ ядрами и 64гб, чтобы размещать мини llm. Миник без нижней крышки установлен на 14 см кулер с питанием от его же usb. Тишина и холод на максималках.