diff --git a/README.md b/README.md index 1ecb864..ad7e9d1 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,26 @@ - [Grafana](./grafana/) - Загруженность сервера - [Prometheus](./grafana/prometheus.yml) - [Node Exporter](./grafana/) +- [Proxy](./proxy/) - Reverse proxy + - [Nginx](./proxy/nginx/) + - [DDNS](./proxy/ddns/) - Автоматическое обновление DNS записей у регистратора [рег.ру](https://www.reg.ru) + - Let's Encrypt - Автоматическое обновление SSL сертификатов на все домены - [Samba](./samba/) - Сетевой диск - [Syncthing](./syncthing/) - Синхронизация данных между устройствами - [Transmission](./transmission/) - BitTorrent клиент - [AutoSSH](./autossh/) - SSH тунель +- [Gitea](./gitea/) - Git-сервер +- [Cloud](./cloud/) - FileBrowser - веб-интерфейс для управления файлами +- [Matrix](./matrix/) - сервер Matrix + - [Synapse](./matrix/create_config.sh) - Matrix сервер Synapse + - [Element](./matrix/docker-compose.yml) - Matrix веб-клиент Element +- [Pi-hole](./pihole/) - DNS фильтр (блокировка рекламы, слежки, защита от атак) ## О проекте: - **Полнофункциональный домашний сервер** - **Все сервисы настроены через Docker Compose** для легкого управления и быстрого запуска -- Мониторинг системы через Grafana с готовыми дашбордами +- **Мониторинг системы через Grafana** с готовыми дашбордами - **Файловый сервер Samba** для доступа к файлам по сети - Открытый диск только на чтение - Доступ на запись только после авторизации @@ -43,29 +53,184 @@ - **BitTorrent клиент Transmission** с веб-интерфейсом - **SSH туннелирование через AutoSSH** - Можно пробросить порт на удалённый VPS, автоматически переподключается при потере соединения +- **Nginx reverse proxy** для маршрутизации трафика к сервисам + - Автоматическое получение и обновление SSL сертификатов через Let's Encrypt + - Автоматическое обновление DNS записей у регистратора [рег.ру](https://www.reg.ru) +- **Git-сервер Gitea** для хостинга собственных репозиториев +- **FileBrowser** - веб-интерфейс для управления файлами через браузер +- **Matrix Synapse** - собственный сервер для мессенджера Matrix с веб-клиентом Element +- Блокировка рекламы, нежелательной слежки, частичная защита от атак с помощью **Pi-hole** - Управление Docker через **Portainer с веб-интерфейсом** -- Скрипт для снижения энергопотребления CPU +- Скрипт для снижения энергопотребления - Все **сервисы используют переменные окружения** для гибкой настройки и примеры конфигураций - Автоматический перезапуск контейнеров при сбоях +## Подготовка: + +- Купить белый IP адрес у провайдера +- В настройках роутера пробросить 80 и 443 порт на сервер +- Купить домен второго уровня у регистратора [рег.ру](https://www.reg.ru) +- [В настройках API рег.ру](https://www.reg.ru/user/account/settings/api/) добавить CIDR вашего провайдера (чтобы при смене IP наш скрипт смог обновить DNS записи) +- В настройках DNS-серверов зоны указать бесплатные DNS-серверы рег.ру: `ns1.reg.ru`, `ns2.reg.ru` + ## Запуск: -1. **Настройте переменные окружения:** - Создайте файл `.env` в директории сервиса с необходимыми переменными по шаблону. +### 1. Portainer - ```bash - cd - cp .env.example .env - ``` +```bash +cd portainer +cp .env.example .env && vim .env +sudo docker compose up -d +``` - Отредактируйте `.env` под свои задачи. +### 2. Grafana -2. **Запустите нужные сервисы:** - ```bash - docker-compose -f portainer/docker-compose.yml up -d - docker-compose -f grafana/docker-compose.yml up -d - docker-compose -f samba/docker-compose.yml up -d - docker-compose -f syncthing/docker-compose.yml up -d - docker-compose -f transmission/docker-compose.yml up -d - docker-compose -f autossh/docker-compose.yml up -d - ``` +```bash +cd grafana +cp .env.example .env && vim .env +sudo docker compose up -d +``` + +### 3. AutoSSH + +```bash +cd autossh +cp .env.example .env && vim .env +sudo docker compose up -d --build +``` + +### 4. Samba + +```bash +cd samba +cp .env.example .env && vim .env +sudo docker compose up -d +``` + +### 5. Transmission + +```bash +cd transmission +cp .env.example .env && vim .env +sudo docker compose up -d +``` + +### 6. Syncthing + +```bash +cd syncthing +cp .env.example .env && vim .env +sudo docker compose up -d +``` + +### 7. Gitea + +```bash +cd gitea +cp .env.example .env && vim .env +sudo docker compose up -d +``` + +> **Примечание:** Конфигурируется позже, уже в веб-форме. + +### 8. Cloud (FileBrowser) + +```bash +cd cloud +cp .env.example .env && vim .env +touch filebrowser.db +sudo docker compose up -d +``` + +### 9. Matrix + +```bash +cd matrix +cp .env.example .env && vim .env +``` + +Создаём конфиг [по примеру](./matrix/create_config.sh): + +```bash +sudo docker compose up -d +``` + +Создаём пользователя [по примеру](./matrix/create_user.sh). + +### 10. Pi-hole + +```bash +cd pihole +cp .env.example .env && vim .env +sudo docker compose up -d +``` + +[Устанавливаем пароль](./pihole/set-password.sh) (оставить пустым для доступа без пароля) + +В разделе Settings > DNS выбираем вышестоящие DNS сервер. Включаем сверху расширенные настройки и в блоке interface settings выбираем пункт `Permit all origins`. В разделе Lists добавляем [списки доменов для блокировки](./pihole/block-lists.txt). Затем обновляем их в Tools > Update Gravity. В настройках ПК (роутера) устанавливаем в качестве DNS наш сервер. + +### 10. Nginx Reverse Proxy (Entrypoint) + +```bash +cd proxy +cp .env.example .env && vim .env +``` + +Создаём конфиг для DynDNS: + +```bash +cp ddns/domains.txt.example ddns/domains.txt && vim ddns/domains.txt +``` + +Нужно указать ресурсные записи `@` и `www` для доступа к домену второго уровня напрямую. Также нужно добавить домены 3-го уровня для: gitea, cloud (filebrowser), matrix server (synapse), matrix client (element). + +В первый раз SSL сертификаты нужно создать вручную. + +Запускаем DDNS скрипт и HTTP сервер для Let's Encrypt: + +```bash +sudo docker compose -f init-compose.yml up -d --build +``` + +Проверяем по логам в portainer и в личном кабинете рег.ру что ресурсные записи обновились. Ожидаем пока DNS обновит информацию о наших поддоменах (занимает от 15 минут до 24 часов). Затем создаём SSL сертификаты на каждый домен(-ы) [по примеру](./proxy/create-first-cert-example.sh). + +Настраиваем Nginx: + +```bash +cd nginx/conf.d +cp default.conf.example default.conf +vim default.conf +``` + +Запускаем основной контейнер: + +```bash +sudo docker compose -f init-compose.yml down +sudo docker compose up -d --build +``` + +## Использование: + +#### После настройки и запуска внутренние сервисы доступны (по умолчанию) по следующим портам: + +- **Grafana** — порт `3000`: + ![](./screenshots/grafana.jpg) + +- **Portainer** — порт `9000`: + ![](./screenshots/portainer.jpg) + +- **Transmission** — порт `9091`: + ![](./screenshots/transmission.png) + +- **Syncthing** — порт `8384`: + ![](./screenshots/syncthing.png) + +#### Внешние сервисы запустятся на указанных в конфиге nginx поддоменах: + +- **Gitea** + ![](./screenshots/gitea.png) +- **Synapse и Element** + |![](./screenshots/synapse.png)|![](./screenshots/element.png)| + |-|-| +- **FileBrowser** + ![](./screenshots/cloud.png) diff --git a/autossh/docker-compose.yml b/autossh/docker-compose.yml index 591d2df..8aa0768 100644 --- a/autossh/docker-compose.yml +++ b/autossh/docker-compose.yml @@ -28,9 +28,17 @@ services: -L 0.0.0.0:${SSH_TUNNEL_TO:?}:localhost:${SSH_TUNNEL_FROM:?} ${SSH_USER:?}@${SSH_HOST:?} -p ${SSH_PORT:-22} + deploy: + resources: + limits: + cpus: '0.1' + memory: 64M + reservations: + memory: 32M networks: - autossh_network networks: autossh_network: + name: autossh_network driver: bridge diff --git a/cloud/docker-compose.yml b/cloud/docker-compose.yml index d135906..b359cc6 100644 --- a/cloud/docker-compose.yml +++ b/cloud/docker-compose.yml @@ -24,9 +24,17 @@ services: filebrowser users add ${ADMIN_USER:?} ${ADMIN_PASSWORD:?} --perm.admin --scope "." --database /database/filebrowser.db || \ filebrowser users update ${ADMIN_USER:?} --password ${ADMIN_PASSWORD:?} --scope "." --database /database/filebrowser.db filebrowser --database /database/filebrowser.db --address 0.0.0.0 --port 80 --root /srv + deploy: + resources: + limits: + cpus: '1.0' + memory: 512M + reservations: + memory: 256M networks: - cloud_network networks: cloud_network: + name: cloud_network driver: bridge diff --git a/gitea/docker-compose.yml b/gitea/docker-compose.yml index 8526865..aaabfb3 100644 --- a/gitea/docker-compose.yml +++ b/gitea/docker-compose.yml @@ -19,6 +19,13 @@ services: # - ${GITEA_SSH_PORT:?}:2222 depends_on: - gitea-db + deploy: + resources: + limits: + cpus: '1.0' + memory: 512M + reservations: + memory: 256M networks: - gitea_network @@ -32,9 +39,17 @@ services: - POSTGRES_DB=${GITEA_DB:?} volumes: - ./db:/var/lib/postgresql/data + deploy: + resources: + limits: + cpus: '1.0' + memory: 512M + reservations: + memory: 256M networks: - gitea_network networks: gitea_network: + name: gitea_network driver: bridge diff --git a/grafana/docker-compose.yml b/grafana/docker-compose.yml index e4b3892..65f7884 100644 --- a/grafana/docker-compose.yml +++ b/grafana/docker-compose.yml @@ -9,6 +9,13 @@ services: command: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.path=/prometheus" + deploy: + resources: + limits: + cpus: '0.5' + memory: 512M + reservations: + memory: 256M networks: - grafana_network @@ -24,6 +31,13 @@ services: environment: - GF_SECURITY_ADMIN_USER=${GRAFANA_USER:?} # Ваш логин - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:?} # Ваш пароль + deploy: + resources: + limits: + cpus: '0.5' + memory: 256M + reservations: + memory: 128M networks: - grafana_network @@ -41,6 +55,13 @@ services: - "--path.sysfs=/host/sys" - "--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)" - "--collector.systemd" + deploy: + resources: + limits: + cpus: '0.1' + memory: 64M + reservations: + memory: 32M networks: - grafana_network @@ -50,4 +71,5 @@ volumes: networks: grafana_network: + name: grafana_network driver: bridge diff --git a/matrix/create_config.sh b/matrix/create_config.sh index 14194c6..4095aed 100644 --- a/matrix/create_config.sh +++ b/matrix/create_config.sh @@ -1,5 +1,5 @@ docker run -it --rm \ - -v "$(pwd)/synapse_data:/data" \ - -e SYNAPSE_SERVER_NAME=example.com \ - -e SYNAPSE_REPORT_STATS=yes \ + -v "$(pwd)/data:/data" \ + -e SYNAPSE_SERVER_NAME=matrix.domain.ru \ + -e SYNAPSE_REPORT_STATS=no \ matrixdotorg/synapse:latest generate diff --git a/matrix/create_user.sh b/matrix/create_user.sh index b4bd3d0..3bdc1ec 100644 --- a/matrix/create_user.sh +++ b/matrix/create_user.sh @@ -1,2 +1,2 @@ -docker exec -it matrix-synapse-1 register_new_matrix_user \ - -c /data/homeserver.yaml http://localhost:8008 +docker exec -it matrix-synapse register_new_matrix_user \ + -c /data/homeserver.yaml https://matrix.domain.ru diff --git a/matrix/docker-compose.yml b/matrix/docker-compose.yml index c66c521..191df26 100644 --- a/matrix/docker-compose.yml +++ b/matrix/docker-compose.yml @@ -9,6 +9,13 @@ services: - SYNAPSE_CONFIG_PATH=/data/homeserver.yaml depends_on: - matrix-db + deploy: + resources: + limits: + cpus: '1.0' + memory: 512M + reservations: + memory: 256M networks: - matrix_network @@ -23,6 +30,13 @@ services: - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C volumes: - ./db:/var/lib/postgresql/data + deploy: + resources: + limits: + cpus: '1.0' + memory: 512M + reservations: + memory: 256M networks: - matrix_network @@ -30,9 +44,17 @@ services: image: vectorim/element-web:latest container_name: matrix-element restart: unless-stopped + deploy: + resources: + limits: + cpus: '1.0' + memory: 256M + reservations: + memory: 128M networks: - matrix_network networks: matrix_network: + name: matrix_network driver: bridge diff --git a/pihole/.env.example b/pihole/.env.example index 0568617..f985156 100644 --- a/pihole/.env.example +++ b/pihole/.env.example @@ -1,3 +1 @@ -PIHOLE_PASSWORD=password -PIHOLE_IP=192.168.32.1 -PIHOLE_DNS=77.88.8.8;8.8.8.8;8.8.4.4 +PIHOLE_IP=192.168.32.1 \ No newline at end of file diff --git a/pihole/block-lists.txt b/pihole/block-lists.txt new file mode 100644 index 0000000..03e436e --- /dev/null +++ b/pihole/block-lists.txt @@ -0,0 +1,10 @@ +https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts +https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/multi.txt +https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt +https://v.firebog.net/hosts/Easyprivacy.txt +https://raw.githubusercontent.com/ElkyBoy/ruadlist-pihole/refs/heads/main/adservers_pihole.txt +https://abp.oisd.nl/basic/ +https://adaway.org/hosts.txt +https://v.firebog.net/hosts/RPiList-Malware.txt +https://raw.githubusercontent.com/anudeepND/blacklist/master/adservers.txt +https://raw.githubusercontent.com/mmotti/pihole-regex/refs/heads/master/regex.list \ No newline at end of file diff --git a/pihole/docker-compose.yml b/pihole/docker-compose.yml index e9c5ee2..4ed09d2 100644 --- a/pihole/docker-compose.yml +++ b/pihole/docker-compose.yml @@ -9,13 +9,25 @@ services: - "53:53/tcp" - "53:53/udp" # - "67:67/udp" # Раскомментируйте, если планируете использовать Pi-hole как DHCP-сервер - - "8080:80/tcp" # Веб-интерфейс будет доступен на порту 8080 (чтобы не занимать 80) + - "8080:80/tcp" # Веб-интерфейс будет доступен на порту 8080 (чтобы не занимать 80) environment: - TZ: 'Europe/Samara' # Укажите ваш часовой пояс - WEBPASSWORD: '${PIHOLE_PASSWORD:?}' # Пароль для входа в админку - FTLCONF_LOCAL_IPV4: '${PIHOLE_IP:?}' # IP-адрес вашего хоста (сервера) - PIHOLE_DNS_: '${PIHOLE_DNS:?}' # Вышестоящие DNS-серверы + TZ: "Europe/Samara" # Укажите ваш часовой пояс + FTLCONF_LOCAL_IPV4: "${PIHOLE_IP:?}" # IP-адрес вашего хоста (сервера) volumes: - - './etc-pihole:/etc/pihole' - - './etc-dnsmasq.d:/etc/dnsmasq.d' + - "./etc-pihole:/etc/pihole" + - "./etc-dnsmasq.d:/etc/dnsmasq.d" restart: unless-stopped + deploy: + resources: + limits: + cpus: "0.25" + memory: 128M + reservations: + memory: 64M + networks: + - pihole_network + +networks: + pihole_network: + name: pihole_network + driver: bridge diff --git a/portainer/docker-compose.yml b/portainer/docker-compose.yml index 245bf25..602b1a9 100644 --- a/portainer/docker-compose.yml +++ b/portainer/docker-compose.yml @@ -12,6 +12,13 @@ services: ports: - "${PORTAINER_PORT:?}:9000" command: -H unix:///var/run/docker.sock + deploy: + resources: + limits: + cpus: '0.25' + memory: 128M + reservations: + memory: 64M networks: - portainer_network @@ -20,4 +27,5 @@ volumes: networks: portainer_network: + name: portainer_network driver: bridge diff --git a/proxy/create-first-cert-example.sh b/proxy/create-first-cert-example.sh index f1df40f..b433db2 100644 --- a/proxy/create-first-cert-example.sh +++ b/proxy/create-first-cert-example.sh @@ -1,8 +1,6 @@ -docker compose -f init-compose.yml up -d - docker compose run --rm --entrypoint "certbot" certbot certonly --webroot \ --webroot-path=/var/www/certbot \ --email your-email@gmail.com \ --agree-tos \ --no-eff-email \ - -d domain.com + -d domain.com -d domain2.com diff --git a/proxy/ddns/domains.txt.example b/proxy/ddns/domains.txt.example index 8f8e037..e2681bb 100644 --- a/proxy/ddns/domains.txt.example +++ b/proxy/ddns/domains.txt.example @@ -1,10 +1,7 @@ -domain.com +domain.ru @ www -subdomain1 -subdomain2 - -domain2.com -@ -www -subdomain1 +git +disk +matrix +chat \ No newline at end of file diff --git a/proxy/docker-compose.yml b/proxy/docker-compose.yml index f5acb22..9638956 100644 --- a/proxy/docker-compose.yml +++ b/proxy/docker-compose.yml @@ -13,6 +13,13 @@ services: - ./ssl/www:/var/www/certbot:ro # Подхватываем новые ssl сертификаты command: /bin/sh -c "while :; do sleep 24h & wait $${!}; nginx -s reload; done & nginx -g 'daemon off;'" + deploy: + resources: + limits: + cpus: '0.25' + memory: 128M + reservations: + memory: 64M networks: - proxy_network - gitea_network @@ -27,6 +34,13 @@ services: - ./ssl/www:/var/www/certbot # Проверяет сертификаты дважды в сутки. Если осталось менее 30 дней - обновляем entrypoint: "/bin/sh -c 'trap exit TERM; while :; sleep 30s & wait $${!}; do certbot renew; sleep 12h & wait $${!}; done;'" + deploy: + resources: + limits: + cpus: '0.25' + memory: 128M + reservations: + memory: 64M networks: - proxy_network @@ -39,18 +53,26 @@ services: - ./ddns/domains.txt:/app/domains.txt environment: - TZ=Europe/Samara + deploy: + resources: + limits: + cpus: '0.25' + memory: 128M + reservations: + memory: 64M networks: - proxy_network networks: proxy_network: + name: proxy_network driver: bridge gitea_network: external: true - name: gitea_gitea_network + name: gitea_network cloud_network: external: true - name: cloud_cloud_network + name: cloud_network matrix_network: external: true - name: matrix_matrix_network + name: matrix_network diff --git a/proxy/init-compose.yml b/proxy/init-compose.yml index 39f5b12..b3290af 100644 --- a/proxy/init-compose.yml +++ b/proxy/init-compose.yml @@ -8,6 +8,13 @@ services: - ./ddns/domains.txt:/app/domains.txt environment: - TZ=Europe/Samara + deploy: + resources: + limits: + cpus: '0.25' + memory: 128M + reservations: + memory: 64M nginx-proxy: image: nginx:alpine @@ -20,3 +27,10 @@ services: # Папки для SSL сертификатов - ./ssl/conf:/etc/letsencrypt:ro - ./ssl/www:/var/www/certbot:ro + deploy: + resources: + limits: + cpus: '0.25' + memory: 128M + reservations: + memory: 64M diff --git a/samba/docker-compose.yml b/samba/docker-compose.yml index e5e50ca..08f22ba 100644 --- a/samba/docker-compose.yml +++ b/samba/docker-compose.yml @@ -20,9 +20,17 @@ services: -g "acl allow execute always = yes" -g "map archive = yes" -g "client max protocol = SMB3" + deploy: + resources: + limits: + cpus: '0.5' + memory: 256M + reservations: + memory: 128M networks: - samba_network networks: samba_network: + name: samba_network driver: bridge diff --git a/screenshots/cloud.png b/screenshots/cloud.png new file mode 100644 index 0000000..a03320a Binary files /dev/null and b/screenshots/cloud.png differ diff --git a/screenshots/element.png b/screenshots/element.png new file mode 100644 index 0000000..c83b91d Binary files /dev/null and b/screenshots/element.png differ diff --git a/screenshots/gitea.png b/screenshots/gitea.png new file mode 100644 index 0000000..315c74e Binary files /dev/null and b/screenshots/gitea.png differ diff --git a/screenshots/grafana.jpg b/screenshots/grafana.jpg index 1c0ae73..db133f2 100644 Binary files a/screenshots/grafana.jpg and b/screenshots/grafana.jpg differ diff --git a/screenshots/portainer.jpg b/screenshots/portainer.jpg index 2594349..88750bf 100644 Binary files a/screenshots/portainer.jpg and b/screenshots/portainer.jpg differ diff --git a/screenshots/synapse.png b/screenshots/synapse.png new file mode 100644 index 0000000..14927ad Binary files /dev/null and b/screenshots/synapse.png differ diff --git a/screenshots/syncthing.png b/screenshots/syncthing.png new file mode 100644 index 0000000..4030218 Binary files /dev/null and b/screenshots/syncthing.png differ diff --git a/screenshots/transmission.png b/screenshots/transmission.png new file mode 100644 index 0000000..f3ba57d Binary files /dev/null and b/screenshots/transmission.png differ diff --git a/syncthing/docker-compose.yml b/syncthing/docker-compose.yml index f9d7554..a327a5d 100644 --- a/syncthing/docker-compose.yml +++ b/syncthing/docker-compose.yml @@ -15,9 +15,17 @@ services: - 22000:22000/tcp # Передача данных - 22000:22000/udp # Передача данных (QUIC) - 21027:21027/udp # Локальный поиск (Discovery) + deploy: + resources: + limits: + cpus: '0.5' + memory: 256M + reservations: + memory: 128M networks: - syncthing_network networks: syncthing_network: + name: syncthing_network driver: bridge diff --git a/transmission/docker-compose.yml b/transmission/docker-compose.yml index d7c1536..bc122c6 100644 --- a/transmission/docker-compose.yml +++ b/transmission/docker-compose.yml @@ -18,9 +18,17 @@ services: - 51413:51413 # Порт для входящих соединений (TCP) - 51413:51413/udp # Порт для входящих соединений (UDP) restart: unless-stopped + deploy: + resources: + limits: + cpus: '0.5' + memory: 256M + reservations: + memory: 128M networks: - transmission_network networks: transmission_network: + name: transmission_network driver: bridge