1
Fork 0
crypto_bot_training/Session_06/Notebooks/method_nohup.ipynb
2025-06-28 16:08:28 +02:00

455 lines
No EOL
11 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Running Your Trading Bot 24/7 with nohup\n",
"\n",
"## Option 1: nohup (No Hang Up) - Simplest Method\n",
"\n",
"**Best for:** Beginners, single bot deployment, simple setups\n",
"\n",
"**What nohup does:**\n",
"- Runs your process immune to hangups (SIGHUP signals)\n",
"- Continues running even after you close SSH connection\n",
"- Redirects output to files for logging\n",
"- Simple and lightweight solution"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 1: Basic nohup Usage\n",
"\n",
"**⚠️ Run these commands on your server via SSH, not in Jupyter!**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"# Basic nohup command\n",
"# This runs your bot in background and logs output to nohup.out\n",
"nohup python3 main.py &\n",
"\n",
"# Better version - custom log file\n",
"nohup python3 main.py > bot.log 2>&1 &\n",
"\n",
"# Even better - with timestamp in log filename\n",
"nohup python3 main.py > bot_$(date +%Y%m%d_%H%M%S).log 2>&1 &"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Command Breakdown:\n",
"- `nohup` - Makes process immune to hangup signals\n",
"- `python3 main.py` - Your bot command\n",
"- `> bot.log` - Redirect stdout (normal output) to bot.log\n",
"- `2>&1` - Redirect stderr (errors) to same file as stdout\n",
"- `&` - Run in background"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 2: Using PID Files for Better Management"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"# Start bot and save Process ID (PID) to file\n",
"nohup python3 main.py > bot.log 2>&1 &\n",
"echo $! > bot.pid\n",
"\n",
"# Check what PID was saved\n",
"cat bot.pid\n",
"\n",
"# Verify the process is running\n",
"ps aux | grep $(cat bot.pid)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 3: Managing Your Bot"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"# Check if bot is running\n",
"if kill -0 $(cat bot.pid) 2>/dev/null; then\n",
" echo \"Bot is running with PID $(cat bot.pid)\"\n",
"else\n",
" echo \"Bot is not running\"\n",
"fi\n",
"\n",
"# View live logs\n",
"tail -f bot.log\n",
"\n",
"# View last 50 lines of logs\n",
"tail -n 50 bot.log\n",
"\n",
"# Search for errors in logs\n",
"grep -i error bot.log"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 4: Stopping Your Bot"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"# Graceful stop (recommended)\n",
"kill -TERM $(cat bot.pid)\n",
"\n",
"# Force stop if graceful doesn't work\n",
"kill -KILL $(cat bot.pid)\n",
"\n",
"# Clean up PID file\n",
"rm bot.pid\n",
"\n",
"# One-liner to stop and cleanup\n",
"kill $(cat bot.pid) && rm bot.pid"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 5: Create Start/Stop Scripts\n",
"\n",
"### Create start_bot.sh script"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"# Create start script\n",
"nano start_bot.sh"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Contents of start_bot.sh:**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"#!/bin/bash\n",
"\n",
"# Check if bot is already running\n",
"if [ -f bot.pid ] && kill -0 $(cat bot.pid) 2>/dev/null; then\n",
" echo \"Bot is already running with PID $(cat bot.pid)\"\n",
" exit 1\n",
"fi\n",
"\n",
"# Start the bot\n",
"echo \"Starting trading bot...\"\n",
"cd /root/trading-bot\n",
"nohup python3 main.py > bot_$(date +%Y%m%d_%H%M%S).log 2>&1 &\n",
"echo $! > bot.pid\n",
"\n",
"echo \"Bot started with PID $(cat bot.pid)\"\n",
"echo \"Log file: bot_$(date +%Y%m%d_%H%M%S).log\"\n",
"echo \"To view logs: tail -f bot_$(date +%Y%m%d_%H%M%S).log\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create stop_bot.sh script"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"# Create stop script\n",
"nano stop_bot.sh"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Contents of stop_bot.sh:**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"#!/bin/bash\n",
"\n",
"# Check if PID file exists\n",
"if [ ! -f bot.pid ]; then\n",
" echo \"No PID file found. Bot may not be running.\"\n",
" exit 1\n",
"fi\n",
"\n",
"# Get PID\n",
"PID=$(cat bot.pid)\n",
"\n",
"# Check if process is running\n",
"if ! kill -0 $PID 2>/dev/null; then\n",
" echo \"Process $PID is not running. Cleaning up PID file.\"\n",
" rm bot.pid\n",
" exit 1\n",
"fi\n",
"\n",
"# Stop the bot\n",
"echo \"Stopping trading bot (PID: $PID)...\"\n",
"kill -TERM $PID\n",
"\n",
"# Wait for graceful shutdown\n",
"sleep 5\n",
"\n",
"# Check if still running\n",
"if kill -0 $PID 2>/dev/null; then\n",
" echo \"Process still running. Force killing...\"\n",
" kill -KILL $PID\n",
"fi\n",
"\n",
"# Clean up\n",
"rm bot.pid\n",
"echo \"Bot stopped successfully.\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Make scripts executable"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"chmod +x start_bot.sh\n",
"chmod +x stop_bot.sh\n",
"\n",
"# Now you can use:\n",
"./start_bot.sh\n",
"./stop_bot.sh"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 6: Enhanced Python Bot with PID Management\n",
"\n",
"**Add this to your main.py to handle PID files properly:**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"import os\n",
"import sys\n",
"import atexit\n",
"import signal\n",
"from datetime import datetime\n",
"\n",
"# PID file management\n",
"PID_FILE = 'bot.pid'\n",
"\n",
"def write_pid_file():\n",
" \"\"\"Write current process PID to file\"\"\"\n",
" with open(PID_FILE, 'w') as f:\n",
" f.write(str(os.getpid()))\n",
" print(f\"PID {os.getpid()} written to {PID_FILE}\")\n",
"\n",
"def cleanup_pid_file():\n",
" \"\"\"Remove PID file on exit\"\"\"\n",
" if os.path.exists(PID_FILE):\n",
" os.remove(PID_FILE)\n",
" print(f\"Cleaned up {PID_FILE}\")\n",
"\n",
"def signal_handler(signum, frame):\n",
" \"\"\"Handle termination signals gracefully\"\"\"\n",
" print(f\"\\nReceived signal {signum}. Shutting down gracefully...\")\n",
" cleanup_pid_file()\n",
" sys.exit(0)\n",
"\n",
"# Set up signal handlers for graceful shutdown\n",
"signal.signal(signal.SIGTERM, signal_handler)\n",
"signal.signal(signal.SIGINT, signal_handler)\n",
"\n",
"# Register cleanup function\n",
"atexit.register(cleanup_pid_file)\n",
"\n",
"# Write PID file when starting\n",
"write_pid_file()\n",
"\n",
"# Your trading bot code here\n",
"def main():\n",
" print(f\"Trading bot started at {datetime.now()}\")\n",
" \n",
" while True:\n",
" try:\n",
" # Your trading logic here\n",
" print(f\"Bot running... {datetime.now()}\")\n",
" time.sleep(60) # Sleep for 1 minute\n",
" \n",
" except KeyboardInterrupt:\n",
" print(\"\\nKeyboard interrupt received. Shutting down...\")\n",
" break\n",
" except Exception as e:\n",
" print(f\"Error occurred: {e}\")\n",
" time.sleep(10) # Wait before retrying\n",
"\n",
"if __name__ == \"__main__\":\n",
" main()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 7: Monitoring and Troubleshooting"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"source": [
"# Check all your Python processes\n",
"ps aux | grep python3\n",
"\n",
"# Monitor system resources\n",
"top\n",
"# or\n",
"htop\n",
"\n",
"# Check disk space (logs can grow large)\n",
"df -h\n",
"\n",
"# Check memory usage\n",
"free -h\n",
"\n",
"# Find large log files\n",
"find . -name \"*.log\" -size +10M\n",
"\n",
"# Rotate logs (keep last 100 lines)\n",
"tail -n 100 bot.log > bot.log.tmp && mv bot.log.tmp bot.log"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Common Issues and Solutions\n",
"\n",
"### Issue 1: \"Bot.pid file exists but process not running\"\n",
"**Solution:** Clean up stale PID file\n",
"```bash\n",
"rm bot.pid\n",
"./start_bot.sh\n",
"```\n",
"\n",
"### Issue 2: \"Permission denied\"\n",
"**Solution:** Check file permissions\n",
"```bash\n",
"chmod +x start_bot.sh stop_bot.sh\n",
"chmod 755 main.py\n",
"```\n",
"\n",
"### Issue 3: \"Module not found errors\"\n",
"**Solution:** Install missing packages\n",
"```bash\n",
"pip3 install package_name\n",
"```\n",
"\n",
"### Issue 4: \"Log files growing too large\"\n",
"**Solution:** Implement log rotation\n",
"```bash\n",
"# Add to crontab for daily log rotation\n",
"0 0 * * * /root/trading-bot/rotate_logs.sh\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Pros and Cons Summary\n",
"\n",
"### ✅ Pros:\n",
"- **Simple to use** - just one command\n",
"- **Lightweight** - minimal system overhead\n",
"- **Built-in** - available on all Unix/Linux systems\n",
"- **Perfect for single bot** deployments\n",
"- **Easy debugging** - direct log file access\n",
"\n",
"### ❌ Cons:\n",
"- **No automatic restart** on crash\n",
"- **Manual management** - need scripts for start/stop\n",
"- **No built-in monitoring** - need external tools\n",
"- **PID file management** - manual cleanup needed\n",
"- **Not suitable for multiple bots** - becomes complex\n",
"\n",
"### 🎯 Best Use Cases:\n",
"- Learning and development\n",
"- Single trading bot deployment\n",
"- Short to medium-term trading strategies\n",
"- When you want full control over the process"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}