Release 0.9.0
This commit is contained in:
74
bot/resources/configs/.env.example
Normal file
74
bot/resources/configs/.env.example
Normal 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
|
||||
51
bot/resources/configs/chrani-bot-tng.service
Normal file
51
bot/resources/configs/chrani-bot-tng.service
Normal 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
|
||||
146
bot/resources/configs/gunicorn.conf.py
Normal file
146
bot/resources/configs/gunicorn.conf.py
Normal 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)
|
||||
156
bot/resources/configs/nginx.conf.example
Normal file
156
bot/resources/configs/nginx.conf.example
Normal 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;
|
||||
# }
|
||||
# }
|
||||
Reference in New Issue
Block a user