Compare commits

...

9 Commits

Author SHA1 Message Date
forust b9c11b8eab Merge branch 'main' into optimize/userbot
Deploy to Server / deploy (push) Has been cancelled
2026-05-25 01:48:31 +02:00
forust 6dac841b2c updated traefik to v3.7,
Deploy to Server / deploy (push) Has been cancelled
resolved maxResponseBodySize not set
2026-05-25 01:47:59 +02:00
forust 526a2b617a refactor: update .dockerignore
pull_policy never to use local images
2026-05-25 01:43:46 +02:00
forust 1e08391e0e refactor: improved error handling, timeouts and use temp files 2026-05-21 22:14:29 +02:00
forust 0a31601b77 refactor: imporved layer caching for dockerfile
using existing built image for account 2
2026-05-21 22:12:33 +02:00
forust 25eb89c902 feat: add searxng service (metasearch engine) 2026-05-21 21:34:40 +02:00
forust d988b0f7db refactor: change Cloudlfare DDNS config to env-based
Deploy to Server / deploy (push) Failing after 14m7s
2026-05-08 17:38:41 +02:00
forust e873f37159 refactor: nextcloud now requires mounting /dev/dri inside the container.
Deploy to Server / deploy (push) Failing after 0s
Changed network name for nextcloud
2026-05-08 16:39:09 +02:00
forust 8362f45bdc upd: updated image tags for services:
- gitea 1.25.1 --> 1.26
- portainer-ce latest --> 2.41.0
- traefik latest --> 3.6.15
2026-05-08 16:37:26 +02:00
19 changed files with 169 additions and 41 deletions
+2 -1
View File
@@ -5,7 +5,7 @@ sync.ffs_lock
# Copyparty
*.hist/
# Volumes and data directories
# Volumes, configs and data directories
gitea/gitea-db/
gitea/gitea-data/*
n8n/n8n-data/*
@@ -21,6 +21,7 @@ checkmk/checkmk/*
downtify/Downtify_downloads
headscale/config/*
headscale/data/*
searxng/core-config/settings.yml
# Steaming services files
streaming/jellyfin/*
+15
View File
@@ -0,0 +1,15 @@
CLOUDFLARE_API_TOKEN=YOUR_CLOUDFLARE_API_TOKEN
DOMAINS=example.com,dns.example.com,mc.example.com,auth.example.com,ssh.example.com
IP4_DOMAINS=
IP6_DOMAINS=
IP4_PROVIDER=cloudflare.trace
IP6_PROVIDER=none # change if you want to update AAAA
UPDATE_CRON=@every 5m
UPDATE_ON_START=true
DELETE_ON_STOP=false
DELETE_ON_FAILURE=true
TTL=1
PROXIED=!is(dns.example.com) && !is(mc.example.com) && !is(ssh.example.com)
EMOJI=true
UPTIMEKUMA=https://uptime-kuma.example.com/api/push/AsaSDFGFkfklaFALSKffkfFKfkfkfkFK?status=up&msg=OK&ping=
REJECT_CLOUDFLARE_IPS=true
+21 -4
View File
@@ -6,8 +6,25 @@ services:
security_opt:
- no-new-privileges:true
network_mode: 'host'
# https://github.com/timothymiller/cloudflare-ddns#-quick-start
environment:
- PUID=1000
- PGID=1000
volumes:
- ./config.json:/config.json
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN:?Cloudflare API token is required}
- DOMAINS=${DOMAINS:-}
- IP4_DOMAINS=${IP4_DOMAINS:-}
- IP6_DOMAINS=${IP6_DOMAINS:-}
- IP4_PROVIDER=${IP4_PROVIDER:-cloudflare.trace}
- IP6_PROVIDER=${IP6_PROVIDER:-none}
- UPDATE_CRON=${UPDATE_CRON:-@every 5m}
- UPDATE_ON_START=${UPDATE_ON_START:-true}
- DELETE_ON_STOP=${DELETE_ON_STOP:-false}
- DELETE_ON_FAILURE=${DELETE_ON_FAILURE:-true}
- TTL=${TTL:-1} # 1=auto
# to proxy only "dns.example.com" and "wfs.example.com" use "!is(dns.domain.com) && !is (wfs.domain.com)"
- PROXIED=${PROXIED:-true}
- EMOJI=${EMOJI:-true}
- UPTIMEKUMA=${UPTIMEKUMA:-}
- HEALTHCHECKS=${HEALTHCHECKS:-}
- REJECT_CLOUDFLARE_IPS=${REJECT_CLOUDFLARE_IPS:-true}
# volumes:
# Prefer using environment variables for configuration, config.json legacy support
# - ./config.json:/config.json
+1 -1
View File
@@ -1,6 +1,6 @@
services:
server:
image: docker.gitea.com/gitea:1.25.1
image: docker.gitea.com/gitea:1.26
container_name: gitea
restart: always
environment:
+1 -1
View File
@@ -1,6 +1,6 @@
services:
kener:
image: rajnandan1/kener:v4.0.23
image: rajnandan1/kener:4.0.23
container_name: kener
restart: unless-stopped
# ports:
+3 -1
View File
@@ -7,6 +7,7 @@ services:
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config # Do not change (backup)
- /var/run/docker.sock:/var/run/docker.sock:ro
- /dev/dri:/dev/dri
networks:
- nextcloud-aio
- proxy # Optional: Connects the mastercontainer to the proxy network in order to make the built-in reverse proxy detection work. See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md
@@ -57,7 +58,7 @@ services:
NEXTCLOUD_STARTUP_APPS: deck twofactor_totp tasks calendar contacts notes # Allows to modify the Nextcloud apps that are installed on starting AIO the first time. See https://github.com/nextcloud/all-in-one#how-to-change-the-nextcloud-apps-that-are-installed-on-the-first-startup
NEXTCLOUD_ADDITIONAL_APKS: imagemagick # This allows to add additional packages to the Nextcloud container permanently. Default is imagemagick but can be overwritten by modifying this value. See https://github.com/nextcloud/all-in-one#how-to-add-os-packages-permanently-to-the-nextcloud-container
NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS: imagick # dditional php extensions to the Nextcloud container permanently. Default is imagick but can be overwritten by modifying this value. See https://github.com/nextcloud/all-in-one#how-to-add-php-extensions-permanently-to-the-nextcloud-container
NEXTCLOUD_ENABLE_DRI_DEVICE: true # This allows to enable the /dev/dri device for containers that profit from it. ⚠️⚠️⚠️ Warning: this only works if the '/dev/dri' device is present on the host! If it should not exist on your host, don't set this to true as otherwise the Nextcloud container will fail to start! See https://github.com/nextcloud/all-in-one#how-to-enable-hardware-acceleration-for-nextcloud
# NEXTCLOUD_ENABLE_DRI_DEVICE: true # This allows to enable the /dev/dri device for containers that profit from it. ⚠️⚠️⚠️ Warning: this only works if the '/dev/dri' device is present on the host! If it should not exist on your host, don't set this to true as otherwise the Nextcloud container will fail to start! See https://github.com/nextcloud/all-in-one#how-to-enable-hardware-acceleration-for-nextcloud
# NEXTCLOUD_KEEP_DISABLED_APPS: false # Setting this to true will keep Nextcloud apps that are disabled in the AIO interface and not uninstall them if they should be installed. See https://github.com/nextcloud/all-in-one#how-to-keep-disabled-apps
SKIP_DOMAIN_VALIDATION: true # This should only be set to true if things are correctly configured. See https://github.com/nextcloud/all-in-one?tab=readme-ov-file#how-to-skip-the-domain-validation
# TALK_PORT: 3478 # This a-llows to adjust the port that the talk container is using which is exposed on the host. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-talk-port
@@ -67,6 +68,7 @@ networks:
proxy:
external: true
nextcloud-aio:
name: nextcloud-aio
driver: bridge
external: false
volumes:
+1 -1
View File
@@ -1,6 +1,6 @@
services:
portainer:
image: portainer/portainer-ce:latest
image: portainer/portainer-ce:2.41.0
container_name: portainer
restart: always
volumes:
+15
View File
@@ -0,0 +1,15 @@
# Read the documentation before using the `docker-compose.yml` file:
# https://docs.searxng.org/admin/installation-docker.html
#
# Additional ENVs:
# https://docs.searxng.org/admin/settings/settings_general.html#settings-general
# https://docs.searxng.org/admin/settings/settings_server.html#settings-server
# Use a specific version tag. E.g. "latest" or "2026.3.25-541c6c3cb".
#SEARXNG_VERSION=latest
# Listen to a specific address.
#SEARXNG_HOST=[::]
# Listen to a specific port.
SEARXNG_PORT=8080
+45
View File
@@ -0,0 +1,45 @@
# Read the documentation before using the `docker-compose.yml` file:
# https://docs.searxng.org/admin/installation-docker.html
services:
core:
container_name: searxng-core
image: docker.io/searxng/searxng:${SEARXNG_VERSION:-latest}
restart: unless-stopped
# ports:
# - ${SEARXNG_PORT:-8080}
env_file: .env
labels:
- "traefik.enable=true"
- "traefik.http.services.searxng.loadbalancer.server.port=8080"
# Prod Router
- "traefik.http.routers.searxng.rule=Host(`s.forust.xyz` || `searxng.forust.xyz`)"
- "traefik.http.routers.searxng.entrypoints=websecure"
- "traefik.http.routers.searxng.tls=true"
# Local Router
- "traefik.http.routers.searxng-local.rule=Host(`s.workstation.internal` || `searxng.workstation.internal`)"
- "traefik.http.routers.searxng-local.entrypoints=websecure"
- "traefik.http.routers.searxng-local.tls=true"
# Dev Router
- "traefik.http.routers.searxng-dev.rule=Host(`searxng.gigaforust.internal`)"
- "traefik.http.routers.searxng-dev.entrypoints=websecure"
- "traefik.http.routers.searxng-dev.tls=true"
networks:
- proxy
volumes:
- ./core-config/:/etc/searxng/:Z
- core-data:/var/cache/searxng/
valkey:
container_name: searxng-valkey
image: docker.io/valkey/valkey:9-alpine
command: valkey-server --save 30 1 --loglevel warning
restart: unless-stopped
volumes:
- valkey-data:/data/
volumes:
core-data:
valkey-data:
networks:
proxy:
external: true
+1 -1
View File
@@ -1,6 +1,6 @@
services:
traefik:
image: traefik:latest
image: traefik:v3.7
container_name: traefik
restart: unless-stopped
command:
+1
View File
@@ -35,6 +35,7 @@ http:
forwardAuth:
address: "http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
trustForwardHeader: true
maxResponseBodySize: 1048576
authResponseHeaders:
- X-authentik-username
- X-authentik-groups
+11
View File
@@ -1 +1,12 @@
.unused
Downloads
.venv
volumes
.env
.env.*
my_account.session
.gitignore
README.md
.git
uv.lock
.deepsource.toml
+16 -8
View File
@@ -1,10 +1,18 @@
FROM python:3.11
FROM python:3.11-slim
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
git wget ffmpeg mediainfo && \
rm -rf /var/lib/apt/lists/*
COPY requirements.txt /app/
RUN python -m pip install --no-cache-dir --upgrade pip && \
python -m pip install --no-cache-dir -r /app/requirements.txt
COPY . /app
RUN apt-get -qq update && apt-get -qq install -y git wget ffmpeg mediainfo\
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN python -m venv --copies /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "main.py"]
ENV PYTHONUNBUFFERED=1
CMD ["python", "-u", "main.py"]
+6 -3
View File
@@ -3,6 +3,8 @@ services:
build:
context: .
dockerfile: Dockerfile
image: userbot:latest
pull_policy: never
restart: unless-stopped
env_file:
- .env
@@ -16,9 +18,10 @@ services:
- 1.1.1.1
anna:
build:
context: .
dockerfile: Dockerfile
image: userbot:latest
pull_policy: never
depends_on:
- forust
restart: unless-stopped
env_file:
- .env
+13 -5
View File
@@ -90,11 +90,19 @@ def load_missing_modules():
os.makedirs(custom_modules_path, exist_ok=True)
try:
f = requests.get(
"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/full.txt"
).text
except Exception:
logging.error("Failed to fetch custom modules list")
resp = requests.get(
"https://raw.githubusercontent.com/The-MoonTg-project/custom_modules/main/full.txt",
timeout=10,
)
if not resp.ok:
logging.error(
"Failed to fetch custom modules list: HTTP %s",
resp.status_code,
)
return
f = resp.text
except Exception as e:
logging.error("Failed to fetch custom modules list: %s", e)
return
modules_dict = {
line.split("/")[-1].split()[0]: line.strip() for line in f.splitlines()
+1 -1
View File
@@ -3,7 +3,7 @@ name = "userbot"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
requires-python = ">=3.11"
dependencies = [
"aiofiles>=25.1.0",
"aiohttp>=3.13.2",
+2
View File
@@ -18,3 +18,5 @@ aiohttp
aiofiles
pySmartDL
qrcode
bottle
dulwich
+1 -1
View File
@@ -1,8 +1,8 @@
import os
import environs
try:
env = environs.Env()
try:
env.read_env("./.env")
except FileNotFoundError:
print("No .env file found, using os.environ.")
+11 -11
View File
@@ -22,6 +22,7 @@ import re
import shlex
import subprocess
import sys
import tempfile
import time
import traceback
from PIL import Image
@@ -85,13 +86,17 @@ async def edit_or_send_as_file(
return
if len(tex) > 1024:
await message.edit("<code>OutPut is Too Large, Sending As File!</code>")
file_names = f"{file_name}.txt"
with open(file_names, "w") as fn:
with tempfile.NamedTemporaryFile(
"w", delete=False, suffix=".txt", prefix=f"{file_name}_"
) as fn:
fn.write(tex)
await client.send_document(message.chat.id, file_names, caption=caption)
temp_path = fn.name
try:
await client.send_document(message.chat.id, temp_path, caption=caption)
await message.delete()
if os.path.exists(file_names):
os.remove(file_names)
finally:
if os.path.exists(temp_path):
os.remove(temp_path)
return
return await message.edit(tex)
@@ -249,12 +254,7 @@ def is_admin(func):
chat_member = await client.get_chat_member(
message.chat.id, message.from_user.id
)
chat_admins = []
async for member in client.get_chat_members(
message.chat.id, filter=ChatMembersFilter.ADMINISTRATORS
):
chat_admins.append(member)
if chat_member in chat_admins:
if chat_member.status in ("administrator", "creator"):
return await func(client, message)
await message.edit("You need to be an admin to perform this action.")
except UserNotParticipant: