mirror of
https://github.com/StepanovPlaton/HomeServerServices.git
synced 2026-04-03 20:30:44 +04:00
Add matrix, cloud, gitea
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -14,4 +14,9 @@ gitea/data/*
|
|||||||
gitea/db/*
|
gitea/db/*
|
||||||
gitea/config/*
|
gitea/config/*
|
||||||
|
|
||||||
|
matrix/data/*
|
||||||
|
matrix/db
|
||||||
|
|
||||||
|
cloud/filebrowser.db
|
||||||
|
|
||||||
!.keep
|
!.keep
|
||||||
|
|||||||
5
cloud/.env.example
Normal file
5
cloud/.env.example
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
SHARED_FOLDER=/path/to/folder
|
||||||
|
USER_ID=1000
|
||||||
|
GROUP_ID=1000
|
||||||
|
ADMIN_USER=admin
|
||||||
|
ADMIN_PASSWORD=password # Минимальная длинна 12 символов
|
||||||
1
cloud/create-database.sh
Normal file
1
cloud/create-database.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
touch filebrowser.db
|
||||||
32
cloud/docker-compose.yml
Normal file
32
cloud/docker-compose.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
services:
|
||||||
|
filebrowser:
|
||||||
|
image: filebrowser/filebrowser:latest
|
||||||
|
container_name: filebrowser
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
# Папка с вашими файлами (замените /path/to/your/files на реальный путь)
|
||||||
|
- ${SHARED_FOLDER}:/srv
|
||||||
|
# База данных настроек и пользователей
|
||||||
|
- ./filebrowser.db:/database/filebrowser.db
|
||||||
|
# (Опционально) Конфигурационный файл
|
||||||
|
# - ./settings.json:/config/settings.json
|
||||||
|
environment:
|
||||||
|
- PUID=${USER_ID:?}
|
||||||
|
- PGID=${GROUP_ID:?}
|
||||||
|
entrypoint: ["/bin/sh", "-c"]
|
||||||
|
command:
|
||||||
|
- |
|
||||||
|
if [ ! -s /database/filebrowser.db ]; then
|
||||||
|
filebrowser config init --database /database/filebrowser.db
|
||||||
|
filebrowser config set --auth.method=json --database /database/filebrowser.db
|
||||||
|
fi
|
||||||
|
filebrowser config set --root /srv --database /database/filebrowser.db
|
||||||
|
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
|
||||||
|
networks:
|
||||||
|
- cloud_network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
cloud_network:
|
||||||
|
driver: bridge
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
services:
|
services:
|
||||||
gitea:
|
gitea:
|
||||||
image: docker.gitea.com/gitea:1.25.3-rootless
|
image: docker.gitea.com/gitea:1.25.3-rootless
|
||||||
|
container_name: gitea
|
||||||
environment:
|
environment:
|
||||||
- GITEA__database__DB_TYPE=postgres
|
- GITEA__database__DB_TYPE=postgres
|
||||||
- GITEA__database__HOST=db:5432
|
- GITEA__database__HOST=gitea-db:5432
|
||||||
- GITEA__database__NAME=${GITEA_DB:?}
|
- GITEA__database__NAME=${GITEA_DB:?}
|
||||||
- GITEA__database__USER=${GITEA_DB_USER:?}
|
- GITEA__database__USER=${GITEA_DB_USER:?}
|
||||||
- GITEA__database__PASSWD=${GITEA_DB_PASSWORD:?}
|
- GITEA__database__PASSWD=${GITEA_DB_PASSWORD:?}
|
||||||
@@ -13,14 +14,17 @@ services:
|
|||||||
- ./config:/etc/gitea
|
- ./config:/etc/gitea
|
||||||
- /etc/timezone:/etc/timezone:ro
|
- /etc/timezone:/etc/timezone:ro
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
#ports:
|
||||||
- ${GITEA_HTTP_PORT:?}:3000
|
# - ${GITEA_HTTP_PORT:?}:3000
|
||||||
- ${GITEA_SSH_PORT:?}:2222
|
# - ${GITEA_SSH_PORT:?}:2222
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- gitea-db
|
||||||
|
networks:
|
||||||
|
- gitea_network
|
||||||
|
|
||||||
db:
|
gitea-db:
|
||||||
image: docker.io/library/postgres:14
|
image: docker.io/library/postgres:14
|
||||||
|
container_name: gitea-db
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_USER=${GITEA_DB_USER:?}
|
- POSTGRES_USER=${GITEA_DB_USER:?}
|
||||||
@@ -28,3 +32,9 @@ services:
|
|||||||
- POSTGRES_DB=${GITEA_DB:?}
|
- POSTGRES_DB=${GITEA_DB:?}
|
||||||
volumes:
|
volumes:
|
||||||
- ./db:/var/lib/postgresql/data
|
- ./db:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- gitea_network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
gitea_network:
|
||||||
|
driver: bridge
|
||||||
|
|||||||
3
matrix/.env.example
Normal file
3
matrix/.env.example
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
MATRIX_DB=matrix
|
||||||
|
MATRIX_DB_USER=user
|
||||||
|
MATRIX_DB_PASSWORD=password
|
||||||
5
matrix/create_config.sh
Normal file
5
matrix/create_config.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
docker run -it --rm \
|
||||||
|
-v "$(pwd)/synapse_data:/data" \
|
||||||
|
-e SYNAPSE_SERVER_NAME=example.com \
|
||||||
|
-e SYNAPSE_REPORT_STATS=yes \
|
||||||
|
matrixdotorg/synapse:latest generate
|
||||||
2
matrix/create_user.sh
Normal file
2
matrix/create_user.sh
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
docker exec -it matrix-synapse-1 register_new_matrix_user \
|
||||||
|
-c /data/homeserver.yaml http://localhost:8008
|
||||||
38
matrix/docker-compose.yml
Normal file
38
matrix/docker-compose.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
services:
|
||||||
|
matrix-synapse:
|
||||||
|
image: docker.io/matrixdotorg/synapse:latest
|
||||||
|
container_name: matrix-synapse
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
|
environment:
|
||||||
|
- SYNAPSE_CONFIG_PATH=/data/homeserver.yaml
|
||||||
|
depends_on:
|
||||||
|
- matrix-db
|
||||||
|
networks:
|
||||||
|
- matrix_network
|
||||||
|
|
||||||
|
matrix-db:
|
||||||
|
image: docker.io/postgres:14-alpine
|
||||||
|
container_name: matrix-db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=${MATRIX_DB_USER:?}
|
||||||
|
- POSTGRES_PASSWORD=${MATRIX_DB_PASSWORD:?}
|
||||||
|
- POSTGRES_DB=${MATRIX_DB:?}
|
||||||
|
- POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C
|
||||||
|
volumes:
|
||||||
|
- ./db:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- matrix_network
|
||||||
|
|
||||||
|
matrix-element:
|
||||||
|
image: vectorim/element-web:latest
|
||||||
|
container_name: matrix-element
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- matrix_network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
matrix_network:
|
||||||
|
driver: bridge
|
||||||
@@ -1,4 +1,2 @@
|
|||||||
# Используется https://cloud.alviy.com/ddns
|
REGRU_LOGIN=login
|
||||||
|
REGRU_PASSWORD=password
|
||||||
DDNS_TOKEN=token
|
|
||||||
DDNS_DOMAINS=domain.dynnamn.ru
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
docker compose -f init-compose.yml up -d
|
docker compose -f init-compose.yml up -d
|
||||||
|
|
||||||
docker compose run --rm certbot certonly --webroot \
|
docker compose run --rm --entrypoint "certbot" certbot certonly --webroot \
|
||||||
--webroot-path=/var/www/certbot \
|
--webroot-path=/var/www/certbot \
|
||||||
--email your-email@gmail.com \
|
--email your-email@gmail.com \
|
||||||
--agree-tos \
|
--agree-tos \
|
||||||
|
|||||||
10
proxy/ddns/Dockerfile
Normal file
10
proxy/ddns/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
FROM python:3.10-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY ddns_updater.py .
|
||||||
|
|
||||||
|
ENTRYPOINT ["python", "ddns_updater.py"]
|
||||||
170
proxy/ddns/ddns_updater.py
Normal file
170
proxy/ddns/ddns_updater.py
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
import schedule
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="DDNS for reg.ru")
|
||||||
|
parser.add_argument("login", help="Почта на reg.ru")
|
||||||
|
parser.add_argument("password", help="Пароль на reg.ru")
|
||||||
|
parser.add_argument("-d", dest="delay", default=30, type=int,
|
||||||
|
help="Задержка между проверкой ip в минутах")
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format='[%(asctime)s] [%(levelname)s] - %(message)s',
|
||||||
|
datefmt='%d-%b-%y %H:%M:%S',
|
||||||
|
handlers=[
|
||||||
|
logging.FileHandler("logs.txt"),
|
||||||
|
logging.StreamHandler(sys.stdout)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Отключаем лишние логи от requests
|
||||||
|
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
def get_external_ip():
|
||||||
|
"""Пробует получить внешний IP через разные HTTP сервисы"""
|
||||||
|
services = [
|
||||||
|
"https://api.ipify.org",
|
||||||
|
"https://ifconfig.me/ip",
|
||||||
|
"https://ident.me",
|
||||||
|
"https://icanhazip.com"
|
||||||
|
]
|
||||||
|
|
||||||
|
for service in services:
|
||||||
|
try:
|
||||||
|
logging.debug(f"Запрос IP через {service}...")
|
||||||
|
response = requests.get(service, timeout=10)
|
||||||
|
if response.status_code == 200:
|
||||||
|
ip = response.text.strip()
|
||||||
|
if ip:
|
||||||
|
return ip
|
||||||
|
except Exception as e:
|
||||||
|
logging.warning(f"Сервис {service} недоступен: {e}")
|
||||||
|
continue
|
||||||
|
return None
|
||||||
|
|
||||||
|
def cheker():
|
||||||
|
logging.info("--- Проверка внешнего IP ---")
|
||||||
|
cur_ip = get_external_ip()
|
||||||
|
|
||||||
|
if not cur_ip:
|
||||||
|
logging.error("Не удалось определить внешний IP ни через один сервис!")
|
||||||
|
return
|
||||||
|
|
||||||
|
logging.info(f"Ваш текущий IP: {cur_ip}")
|
||||||
|
|
||||||
|
res = update_ip(cur_ip)
|
||||||
|
|
||||||
|
if res is not True:
|
||||||
|
code, message = res
|
||||||
|
logging.error(f"Ошибка API: {code} - {message}")
|
||||||
|
|
||||||
|
def update_ip(ip):
|
||||||
|
try:
|
||||||
|
with open("domains.txt", "r") as file:
|
||||||
|
content = file.read().strip()
|
||||||
|
|
||||||
|
if not content:
|
||||||
|
logging.warning("Файл domains.txt пуст.")
|
||||||
|
return True
|
||||||
|
|
||||||
|
auth_data = {
|
||||||
|
"username": args.login,
|
||||||
|
"password": args.password,
|
||||||
|
"output_content_type": "json"
|
||||||
|
}
|
||||||
|
|
||||||
|
groups = [g for g in content.split("\n\n") if g.strip()]
|
||||||
|
|
||||||
|
for group in groups:
|
||||||
|
lines = [line.strip() for line in group.split("\n") if line.strip()]
|
||||||
|
if len(lines) < 2: continue
|
||||||
|
|
||||||
|
domain_name = lines[0]
|
||||||
|
aliases = lines[1:]
|
||||||
|
|
||||||
|
logging.info(f"Проверка домена {domain_name}...")
|
||||||
|
|
||||||
|
# Получаем текущие записи
|
||||||
|
input_data = {**auth_data, "domains": [{"dname": domain_name}]}
|
||||||
|
params = {"input_data": json.dumps(input_data), "input_format": "json"}
|
||||||
|
|
||||||
|
resp = requests.post("https://api.reg.ru/api/regru2/zone/get_resource_records", data=params).json()
|
||||||
|
|
||||||
|
if resp.get("result") == "error":
|
||||||
|
return resp.get("error_code"), resp.get("error_text")
|
||||||
|
|
||||||
|
current_rrs = resp["answer"]["domains"][0].get("rrs", [])
|
||||||
|
|
||||||
|
for sub in aliases:
|
||||||
|
already_correct = False
|
||||||
|
outdated_records = []
|
||||||
|
|
||||||
|
for rr in current_rrs:
|
||||||
|
if rr.get("rectype") == "A" and rr.get("subname") == sub:
|
||||||
|
if rr.get("content") == ip:
|
||||||
|
already_correct = True
|
||||||
|
else:
|
||||||
|
outdated_records.append(rr)
|
||||||
|
|
||||||
|
if already_correct:
|
||||||
|
logging.info(f" [{sub}.{domain_name}] Пропуск: IP уже актуален ({ip})")
|
||||||
|
else:
|
||||||
|
logging.info(f" [{sub}.{domain_name}] Обновление записи...")
|
||||||
|
# Удаляем старые
|
||||||
|
for old_rr in outdated_records:
|
||||||
|
remove_old_record(auth_data, domain_name, old_rr)
|
||||||
|
# Создаем новую
|
||||||
|
add_new_record(auth_data, domain_name, sub, ip)
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
logging.error("Файл domains.txt не найден!")
|
||||||
|
except Exception as e:
|
||||||
|
return "UNKNOWN_ERROR", str(e)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def remove_old_record(auth, domain, rr):
|
||||||
|
logging.info(f" Удаление старой записи: {rr['subname']} -> {rr['content']}")
|
||||||
|
data = {
|
||||||
|
**auth,
|
||||||
|
"domains": [{"dname": domain}],
|
||||||
|
"subdomain": rr["subname"],
|
||||||
|
"content": rr["content"],
|
||||||
|
"record_type": "A"
|
||||||
|
}
|
||||||
|
requests.post("https://api.reg.ru/api/regru2/zone/remove_record", data={"input_data": json.dumps(data), "input_format": "json"})
|
||||||
|
|
||||||
|
def add_new_record(auth, domain, sub, ip):
|
||||||
|
logging.info(f" Создание новой записи: {sub} -> {ip}")
|
||||||
|
data = {
|
||||||
|
**auth,
|
||||||
|
"domains": [{"dname": domain}],
|
||||||
|
"subdomain": sub,
|
||||||
|
"ipaddr": ip
|
||||||
|
}
|
||||||
|
res = requests.post("https://api.reg.ru/api/regru2/zone/add_alias", data={"input_data": json.dumps(data), "input_format": "json"}).json()
|
||||||
|
if res.get("result") == "error":
|
||||||
|
logging.error(f" Ошибка API при добавлении: {res.get('error_text')}")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
args = parser.parse_args()
|
||||||
|
logging.info("==========================================")
|
||||||
|
logging.info("Запуск контейнера DDNS")
|
||||||
|
logging.info("Ожидание 30 секунд (загрузка сети/роутера)...")
|
||||||
|
logging.info("==========================================")
|
||||||
|
|
||||||
|
time.sleep(30)
|
||||||
|
|
||||||
|
logging.info("Начинаю работу...")
|
||||||
|
|
||||||
|
cheker()
|
||||||
|
|
||||||
|
schedule.every(args.delay).minutes.do(cheker)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
schedule.run_pending()
|
||||||
|
time.sleep(1)
|
||||||
7
proxy/ddns/domains.txt
Normal file
7
proxy/ddns/domains.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
stepanovplaton.ru
|
||||||
|
@
|
||||||
|
www
|
||||||
|
git
|
||||||
|
disk
|
||||||
|
matrix
|
||||||
|
chat
|
||||||
10
proxy/ddns/domains.txt.example
Normal file
10
proxy/ddns/domains.txt.example
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
domain.com
|
||||||
|
@
|
||||||
|
www
|
||||||
|
subdomain1
|
||||||
|
subdomain2
|
||||||
|
|
||||||
|
domain2.com
|
||||||
|
@
|
||||||
|
www
|
||||||
|
subdomain1
|
||||||
2
proxy/ddns/requirements.txt
Normal file
2
proxy/ddns/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
schedule
|
||||||
|
requests
|
||||||
@@ -1,17 +1,4 @@
|
|||||||
services:
|
services:
|
||||||
ddns-updater:
|
|
||||||
image: alpine:latest
|
|
||||||
container_name: ddns-updater
|
|
||||||
env_file: .env
|
|
||||||
volumes:
|
|
||||||
- ./update_dns.sh:/update_dns.sh:ro
|
|
||||||
entrypoint: ["/bin/sh", "-c"]
|
|
||||||
command:
|
|
||||||
- |
|
|
||||||
apk add --no-cache curl bash
|
|
||||||
/bin/bash /update_dns.sh
|
|
||||||
restart: "no"
|
|
||||||
|
|
||||||
nginx-proxy:
|
nginx-proxy:
|
||||||
image: nginx:alpine
|
image: nginx:alpine
|
||||||
container_name: nginx-proxy
|
container_name: nginx-proxy
|
||||||
@@ -26,6 +13,11 @@ services:
|
|||||||
- ./ssl/www:/var/www/certbot:ro
|
- ./ssl/www:/var/www/certbot:ro
|
||||||
# Подхватываем новые ssl сертификаты
|
# Подхватываем новые ssl сертификаты
|
||||||
command: /bin/sh -c "while :; do sleep 24h & wait $${!}; nginx -s reload; done & nginx -g 'daemon off;'"
|
command: /bin/sh -c "while :; do sleep 24h & wait $${!}; nginx -s reload; done & nginx -g 'daemon off;'"
|
||||||
|
networks:
|
||||||
|
- proxy_network
|
||||||
|
- gitea_network
|
||||||
|
- cloud_network
|
||||||
|
- matrix_network
|
||||||
|
|
||||||
certbot:
|
certbot:
|
||||||
image: certbot/certbot
|
image: certbot/certbot
|
||||||
@@ -34,4 +26,31 @@ services:
|
|||||||
- ./ssl/conf:/etc/letsencrypt
|
- ./ssl/conf:/etc/letsencrypt
|
||||||
- ./ssl/www:/var/www/certbot
|
- ./ssl/www:/var/www/certbot
|
||||||
# Проверяет сертификаты дважды в сутки. Если осталось менее 30 дней - обновляем
|
# Проверяет сертификаты дважды в сутки. Если осталось менее 30 дней - обновляем
|
||||||
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
|
entrypoint: "/bin/sh -c 'trap exit TERM; while :; sleep 30s & wait $${!}; do certbot renew; sleep 12h & wait $${!}; done;'"
|
||||||
|
networks:
|
||||||
|
- proxy_network
|
||||||
|
|
||||||
|
ddns:
|
||||||
|
build: ./ddns
|
||||||
|
container_name: ddns
|
||||||
|
restart: always
|
||||||
|
command: ["${REGRU_LOGIN:?}", "${REGRU_PASSWORD:?}"]
|
||||||
|
volumes:
|
||||||
|
- ./ddns/domains.txt:/app/domains.txt
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Samara
|
||||||
|
networks:
|
||||||
|
- proxy_network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy_network:
|
||||||
|
driver: bridge
|
||||||
|
gitea_network:
|
||||||
|
external: true
|
||||||
|
name: gitea_gitea_network
|
||||||
|
cloud_network:
|
||||||
|
external: true
|
||||||
|
name: cloud_cloud_network
|
||||||
|
matrix_network:
|
||||||
|
external: true
|
||||||
|
name: matrix_matrix_network
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
services:
|
services:
|
||||||
ddns-updater:
|
ddns:
|
||||||
image: alpine:latest
|
build: ./ddns
|
||||||
container_name: ddns-updater
|
container_name: ddns
|
||||||
env_file: .env
|
restart: always
|
||||||
|
command: ["${REGRU_LOGIN:?}", "${REGRU_PASSWORD:?}"]
|
||||||
volumes:
|
volumes:
|
||||||
- ./update_dns.sh:/update_dns.sh:ro
|
- ./ddns/domains.txt:/app/domains.txt
|
||||||
entrypoint: ["/bin/sh", "-c"]
|
environment:
|
||||||
command:
|
- TZ=Europe/Samara
|
||||||
- |
|
|
||||||
apk add --no-cache curl bash
|
|
||||||
/bin/bash /update_dns.sh
|
|
||||||
restart: "no"
|
|
||||||
|
|
||||||
nginx-proxy:
|
nginx-proxy:
|
||||||
image: nginx:alpine
|
image: nginx:alpine
|
||||||
@@ -20,4 +17,6 @@ services:
|
|||||||
- 80:80
|
- 80:80
|
||||||
volumes:
|
volumes:
|
||||||
- ./nginx/init:/etc/nginx/conf.d:ro
|
- ./nginx/init:/etc/nginx/conf.d:ro
|
||||||
|
# Папки для SSL сертификатов
|
||||||
|
- ./ssl/conf:/etc/letsencrypt:ro
|
||||||
|
- ./ssl/www:/var/www/certbot:ro
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ server {
|
|||||||
ssl_certificate_key /etc/letsencrypt/live/domain.dynnamn.ru/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/domain.dynnamn.ru/privkey.pem;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
return 200 "Hello world!";
|
charset utf-8;
|
||||||
|
default_type text/plain;
|
||||||
|
return 200 "Hello domain.dynnamn.ru!";
|
||||||
# proxy_pass http://your_app_container:port;
|
# proxy_pass http://your_app_container:port;
|
||||||
# proxy_set_header Host $host;
|
# proxy_set_header Host $host;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name domain.dynnamn.ru domain2.dynnamn.ru;
|
|
||||||
|
|
||||||
location /.well-known/acme-challenge/ {
|
|
||||||
root /var/www/certbot;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
return 200 "Hello HTTP!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Проверяем наличие необходимых переменных
|
|
||||||
if [ -z "$DDNS_TOKEN" ] || [ -z "$DDNS_DOMAINS" ]; then
|
|
||||||
echo "Ошибка: Переменные DDNS_TOKEN или DDNS_DOMAINS не заданы."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
echo "Определяем внешний IPv4..."
|
|
||||||
CURRENT_IP=$(curl -s https://ifconfig.me)
|
|
||||||
|
|
||||||
if [ -z "$CURRENT_IP" ]; then
|
|
||||||
echo "Не удалось получить IP. Повтор через 30 секунд..."
|
|
||||||
sleep 30
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Ваш IP: $CURRENT_IP. Начинаем обновление доменов..."
|
|
||||||
|
|
||||||
ALL_SUCCESS=true
|
|
||||||
|
|
||||||
for DOMAIN in $DDNS_DOMAINS; do
|
|
||||||
echo "Обновляю домен: $DOMAIN"
|
|
||||||
|
|
||||||
# Выполняем запрос PUT согласно вашему формату
|
|
||||||
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
||||||
-X 'PUT' "https://cloud.alviy.com/api/v1/ddns/domain/$DOMAIN" \
|
|
||||||
-H 'accept: application/json' \
|
|
||||||
-H "Authorization: Bearer $DDNS_TOKEN" \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-d "{ \"ipv4\": [ \"$CURRENT_IP\" ] }")
|
|
||||||
|
|
||||||
if [ "$RESPONSE" == "200" ]; then
|
|
||||||
echo "Успешно обновлено: $DOMAIN"
|
|
||||||
else
|
|
||||||
echo "Ошибка обновления $DOMAIN. Код ответа: $RESPONSE"
|
|
||||||
ALL_SUCCESS=false
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$ALL_SUCCESS" = true ]; then
|
|
||||||
echo "Все задачи выполнены успешно. Завершаю работу контейнера."
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
echo "Некоторые домены не обновились. Повторная попытка через 60 секунд..."
|
|
||||||
sleep 60
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
@@ -2,9 +2,6 @@ services:
|
|||||||
transmission:
|
transmission:
|
||||||
image: lscr.io/linuxserver/transmission:latest
|
image: lscr.io/linuxserver/transmission:latest
|
||||||
container_name: transmission
|
container_name: transmission
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
environment:
|
environment:
|
||||||
- PUID=${OWNER_USERID:?}
|
- PUID=${OWNER_USERID:?}
|
||||||
- PGID=${OWNER_GROUPID:?}
|
- PGID=${OWNER_GROUPID:?}
|
||||||
|
|||||||
Reference in New Issue
Block a user