Release 0.9.0

This commit is contained in:
2025-11-21 07:26:02 +01:00
committed by ecv
commit 472f0812e7
240 changed files with 20033 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
# chrani-bot-tng Environment Configuration
# Copy this file to .env and adjust the values for your setup
# ============================================================================
# Application Settings
# ============================================================================
# Set to 'true' when running under gunicorn or other WSGI servers
RUNNING_UNDER_WSGI=true
# Flask secret key - CHANGE THIS to a random string in production!
FLASK_SECRET_KEY=change-this-to-a-random-secret-key
# ============================================================================
# Server Configuration
# ============================================================================
# Host to bind to (use 0.0.0.0 for all interfaces, 127.0.0.1 for localhost only)
HOST=0.0.0.0
# Port to run on
PORT=5000
# ============================================================================
# 7 Days to Die Server Settings
# ============================================================================
# Telnet connection settings for the game server
TELNET_HOST=localhost
TELNET_PORT=8081
TELNET_PASSWORD=your-telnet-password
# ============================================================================
# Logging
# ============================================================================
# Log level: DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_LEVEL=INFO
# ============================================================================
# Development Settings
# ============================================================================
# Enable Flask debug mode (DO NOT use in production!)
FLASK_DEBUG=false
# Enable SocketIO debug mode
SOCKETIO_DEBUG=false
# Enable engineio logger
ENGINEIO_LOGGER=false
# ============================================================================
# Production Settings
# ============================================================================
# Number of gunicorn workers (for WebSocket use 1 worker with gevent)
GUNICORN_WORKERS=1
# Gunicorn worker class (use 'gevent' for WebSocket support)
GUNICORN_WORKER_CLASS=gevent
# Maximum number of concurrent connections per worker
GUNICORN_WORKER_CONNECTIONS=1000
# Request timeout in seconds
GUNICORN_TIMEOUT=120
# ============================================================================
# Database/Storage (if applicable)
# ============================================================================
# Add any database connection strings or storage paths here
# DATA_DIR=/var/lib/chrani-bot-tng

View File

@@ -0,0 +1,51 @@
[Unit]
Description=chrani-bot-tng - 7 Days to Die Server Management Bot
After=network.target
[Service]
Type=notify
# The specific user that our service will run as
# CHANGE THIS to your actual username
User=your-username
Group=your-username
# Set working directory
WorkingDirectory=/path/to/chrani-bot-tng
# Environment variables
Environment="PATH=/path/to/chrani-bot-tng/venv/bin"
Environment="RUNNING_UNDER_WSGI=true"
# If you're using a .env file for configuration
# EnvironmentFile=/path/to/chrani-bot-tng/.env
# The command to start the service
ExecStart=/path/to/chrani-bot-tng/venv/bin/gunicorn -c gunicorn.conf.py wsgi:application
# Restart policy
Restart=always
RestartSec=10
# Performance and security settings
RuntimeDirectory=chrani-bot-tng
RuntimeDirectoryMode=755
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=chrani-bot-tng
# Security hardening (optional but recommended)
NoNewPrivileges=true
PrivateTmp=true
# Resource limits (adjust as needed)
LimitNOFILE=65536
LimitNPROC=512
# Timeout for start/stop
TimeoutStartSec=300
TimeoutStopSec=300
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,146 @@
# -*- coding: utf-8 -*-
"""
Gunicorn Configuration File for chrani-bot-tng
This configuration is optimized for running the bot with Flask-SocketIO and gevent.
"""
import multiprocessing
import os
# Server Socket
bind = "0.0.0.0:5000"
backlog = 2048
# Worker Processes
# For WebSocket support with gevent, use only 1 worker
# Multiple workers don't work well with socket.io state
workers = 1
worker_class = "gevent"
worker_connections = 1000
max_requests = 0 # Disable automatic worker restart
max_requests_jitter = 0
timeout = 120
keepalive = 5
# Logging
accesslog = "-" # Log to stdout
errorlog = "-" # Log to stderr
loglevel = "info"
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
# Process Naming
proc_name = "chrani-bot-tng"
# Server Mechanics
daemon = False
pidfile = None
umask = 0
user = None
group = None
tmp_upload_dir = None
# SSL (uncomment and configure if using HTTPS directly with gunicorn)
# keyfile = "/path/to/keyfile"
# certfile = "/path/to/certfile"
# ca_certs = "/path/to/ca_certs"
# cert_reqs = 0
# ssl_version = 2
# ciphers = None
# Server Hooks
def on_starting(server):
"""
Called just before the master process is initialized.
"""
print("=" * 60)
print("chrani-bot-tng is starting...")
print("=" * 60)
def on_reload(server):
"""
Called to recycle workers during a reload via SIGHUP.
"""
print("Reloading workers...")
def when_ready(server):
"""
Called just after the server is started.
"""
print("=" * 60)
print("chrani-bot-tng is ready to accept connections")
print(f"Listening on: {bind}")
print("=" * 60)
def pre_fork(server, worker):
"""
Called just before a worker is forked.
"""
pass
def post_fork(server, worker):
"""
Called just after a worker has been forked.
"""
print(f"Worker spawned (pid: {worker.pid})")
def post_worker_init(worker):
"""
Called just after a worker has initialized the application.
"""
print(f"Worker initialized (pid: {worker.pid})")
def worker_int(worker):
"""
Called just after a worker received the SIGINT or SIGQUIT signal.
"""
print(f"Worker received INT or QUIT signal (pid: {worker.pid})")
def worker_abort(worker):
"""
Called when a worker received the SIGABRT signal.
"""
print(f"Worker received SIGABRT signal (pid: {worker.pid})")
def pre_exec(server):
"""
Called just before a new master process is forked.
"""
print("Forking new master process...")
def pre_request(worker, req):
"""
Called just before a worker processes the request.
"""
worker.log.debug(f"{req.method} {req.path}")
def post_request(worker, req, environ, resp):
"""
Called after a worker processes the request.
"""
pass
def child_exit(server, worker):
"""
Called just after a worker has been exited.
"""
print(f"Worker exited (pid: {worker.pid})")
def worker_exit(server, worker):
"""
Called just after a worker has been exited.
"""
print(f"Worker process exiting (pid: {worker.pid})")
def nworkers_changed(server, new_value, old_value):
"""
Called just after num_workers has been changed.
"""
print(f"Number of workers changed from {old_value} to {new_value}")
def on_exit(server):
"""
Called just before exiting gunicorn.
"""
print("=" * 60)
print("chrani-bot-tng is shutting down...")
print("=" * 60)

View File

@@ -0,0 +1,156 @@
# nginx configuration for chrani-bot-tng
#
# INSTALLATION:
# 1. Copy this file to /etc/nginx/sites-available/chrani-bot-tng
# 2. Update the server_name to match your domain
# 3. Update the paths to SSL certificates if using HTTPS
# 4. Create a symlink: sudo ln -s /etc/nginx/sites-available/chrani-bot-tng /etc/nginx/sites-enabled/
# 5. Test config: sudo nginx -t
# 6. Reload nginx: sudo systemctl reload nginx
# Upstream configuration for gunicorn
upstream chrani_bot_app {
# Use Unix socket for better performance (recommended)
# Make sure this matches the bind setting in gunicorn.conf.py
server 127.0.0.1:5000 fail_timeout=0;
# Alternative: Unix socket (requires changing gunicorn bind setting)
# server unix:/var/run/chrani-bot-tng/gunicorn.sock fail_timeout=0;
}
# HTTP Server (redirects to HTTPS)
server {
listen 80;
listen [::]:80;
server_name your-domain.com www.your-domain.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://$server_name$request_uri;
}
# HTTPS Server
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your-domain.com www.your-domain.com;
# SSL Configuration
# Update these paths with your actual certificate paths
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# SSL Security Settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Logging
access_log /var/log/nginx/chrani-bot-tng-access.log;
error_log /var/log/nginx/chrani-bot-tng-error.log;
# Max upload size (adjust as needed)
client_max_body_size 4M;
# Security Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Main location block - proxy to gunicorn
location / {
proxy_pass http://chrani_bot_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Disable buffering for better real-time response
proxy_buffering off;
proxy_redirect off;
}
# WebSocket support for Socket.IO
location /socket.io/ {
proxy_pass http://chrani_bot_app/socket.io/;
proxy_http_version 1.1;
# WebSocket specific headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Standard proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts for WebSocket
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
# Disable buffering for WebSocket
proxy_buffering off;
}
# Static files (if you have any)
location /static/ {
alias /path/to/chrani-bot-tng/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Favicon
location = /favicon.ico {
access_log off;
log_not_found off;
}
# Robots.txt
location = /robots.txt {
access_log off;
log_not_found off;
}
}
# Alternative: HTTP-only configuration (for local/dev use)
# Uncomment this and comment out the HTTPS server above if not using SSL
#
# server {
# listen 80;
# listen [::]:80;
# server_name your-domain.com www.your-domain.com;
#
# access_log /var/log/nginx/chrani-bot-tng-access.log;
# error_log /var/log/nginx/chrani-bot-tng-error.log;
#
# client_max_body_size 4M;
#
# location / {
# proxy_pass http://chrani_bot_app;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_buffering off;
# proxy_redirect off;
# }
#
# location /socket.io/ {
# proxy_pass http://chrani_bot_app/socket.io/;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_buffering off;
# }
# }