Ubuntu (No Custom Domain)

This tutorial covers how to install openalgo in Ubuntu server without any custom domain configurtion

Prerequisites

System Requirements

  • Ubuntu Server (22.04 LTS or later recommended)

  • Minimum 0.5GB RAM

  • Clean installation recommended

# Example - ip address is xx.xx.xx.xx and broker is flattrade

http://xx.xx.xx.xx/flattrade/callback

Broker Setup (Required)

  • Obtain your broker's API credentials as per the openalgo documentation:

    • API Key

    • API Secret

  • Prepare the Redirection URL as per your ip address and broker name

Login to the Ubuntu Server

# Connect to your Ubuntu server via SSH
# example ssh [email protected]

ssh user@your_server_ip

Open the Nano Editor

nano install.sh

Save this file under Install.sh

#!/bin/bash

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# OpenAlgo Installation Banner
echo -e "${BLUE}"
echo "  ██████╗ ██████╗ ███████╗███╗   ██╗ █████╗ ██╗      ██████╗  ██████╗ "
echo " ██╔═══██╗██╔══██╗██╔════╝████╗  ██║██╔══██╗██║     ██╔════╝ ██╔═══██╗"
echo " ██║   ██║██████╔╝███████╗██╔██╗ ██║███████║██║     ██║  ███╗██║   ██║"
echo " ██║   ██║██╔═══╝ ██╔══╝  ██║╚██╗██║██╔══██║██║     ██║   ██║██║   ██║"
echo " ╚██████╔╝██╗     ███████╗██║ ╚████║██║  ██║███████╗╚██████╔╝╚██████╔╝"
echo "  ╚═════╝ ╚═╝     ╚══════╝╚═╝  ╚═══╝╚═╝  ╚═╝╚══════╝ ╚═════╝  ╚═════╝ "      
echo "                                                                        "
echo -e "${NC}"
echo -e "${YELLOW}Simple HTTP Installation (No Nginx)${NC}"
echo ""

# Create logs directory
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
LOGS_DIR="$SCRIPT_DIR/logs"
mkdir -p "$LOGS_DIR"

# Log file
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="$LOGS_DIR/install_${TIMESTAMP}.log"

# Function to log messages
log_message() {
    local message="$1"
    local color="$2"
    echo -e "${color}${message}${NC}" | tee -a "$LOG_FILE"
}

# Function to check status
check_status() {
    if [ $? -ne 0 ]; then
        log_message "Error: $1" "$RED"
        exit 1
    fi
}

# Function to generate random hex
generate_hex() {
    python3 -c "import secrets; print(secrets.token_hex(32))"
}

# Function to validate broker
validate_broker() {
    local broker=$1
    local valid_brokers="fivepaisa,fivepaisaxts,aliceblue,angel,compositedge,dhan,dhan_sandbox,firstock,flattrade,fyers,groww,iifl,kotak,jainam,jainampro,paytm,pocketful,shoonya,tradejini,upstox,wisdom,zebu,zerodha"
    if [[ $valid_brokers == *"$broker"* ]]; then
        return 0
    else
        return 1
    fi
}

# Function to check XTS broker
is_xts_broker() {
    local broker=$1
    local xts_brokers="fivepaisaxts,compositedge,iifl,jainam,jainampro,wisdom"
    if [[ $xts_brokers == *"$broker"* ]]; then
        return 0
    else
        return 1
    fi
}

# Function to wait for apt locks to be released
wait_for_apt() {
    while sudo fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1 || sudo fuser /var/lib/apt/lists/lock >/dev/null 2>&1; do
        log_message "Waiting for other package managers to finish..." "$YELLOW"
        sleep 5
    done
}

# Function to check timezone
check_timezone() {
    current_tz=$(timedatectl | grep "Time zone" | awk '{print $3}')
    log_message "Current timezone: $current_tz" "$BLUE"
    
    if [[ "$current_tz" == "Asia/Kolkata" ]]; then
        log_message "Server is already set to IST timezone." "$GREEN"
        return 0
    fi
    
    log_message "Server is not set to IST timezone." "$YELLOW"
    read -p "Would you like to change the timezone to IST? (y/n): " change_tz
    if [[ $change_tz =~ ^[Yy]$ ]]; then
        log_message "Changing timezone to IST..." "$BLUE"
        sudo timedatectl set-timezone Asia/Kolkata
        check_status "Failed to change timezone"
        log_message "Timezone successfully changed to IST" "$GREEN"
    else
        log_message "Keeping current timezone: $current_tz" "$YELLOW"
    fi
}

# Get server IP
SERVER_IP=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -n1)
if [ -z "$SERVER_IP" ]; then
    log_message "Could not detect server IP automatically" "$YELLOW"
    read -p "Please enter your server IP address: " SERVER_IP
fi

# Start logging
log_message "Starting OpenAlgo Simple HTTP installation" "$BLUE"
log_message "Server IP: $SERVER_IP" "$BLUE"
log_message "----------------------------------------" "$BLUE"

# Check timezone before proceeding
check_timezone

# Get broker configuration FIRST
log_message "\nOpenAlgo Configuration" "$BLUE"
log_message "----------------------------------------" "$BLUE"

# Get broker name
while true; do
    log_message "\nValid brokers: fivepaisa,fivepaisaxts,aliceblue,angel,compositedge,dhan,dhan_sandbox,firstock,flattrade,fyers,groww,iifl,kotak,jainam,jainampro,paytm,pocketful,shoonya,tradejini,upstox,wisdom,zebu,zerodha" "$BLUE"
    read -p "Enter your broker name: " BROKER_NAME
    if validate_broker "$BROKER_NAME"; then
        break
    else
        log_message "Invalid broker name. Please choose from the list above." "$RED"
    fi
done

# Show redirect URL
log_message "\nRedirect URL for broker developer portal:" "$YELLOW"
log_message "http://$SERVER_IP/$BROKER_NAME/callback" "$GREEN"
log_message "\nPlease use this URL in your broker's developer portal to generate API credentials." "$BLUE"
log_message "Once you have the credentials, you can proceed with the installation." "$BLUE"
echo ""

# Get API credentials
read -p "Enter your broker API key: " BROKER_API_KEY
read -p "Enter your broker API secret: " BROKER_API_SECRET

if [ -z "$BROKER_API_KEY" ] || [ -z "$BROKER_API_SECRET" ]; then
    log_message "Error: Broker API credentials are required" "$RED"
    exit 1
fi

# Check for XTS broker
BROKER_API_KEY_MARKET=""
BROKER_API_SECRET_MARKET=""
if is_xts_broker "$BROKER_NAME"; then
    log_message "\nThis broker ($BROKER_NAME) is XTS API-based and requires additional market data credentials." "$YELLOW"
    read -p "Enter your broker market data API key: " BROKER_API_KEY_MARKET
    read -p "Enter your broker market data API secret: " BROKER_API_SECRET_MARKET
    
    if [ -z "$BROKER_API_KEY_MARKET" ] || [ -z "$BROKER_API_SECRET_MARKET" ]; then
        log_message "Error: Market data API credentials are required for XTS-based brokers" "$RED"
        exit 1
    fi
fi

# Generate keys
APP_KEY=$(generate_hex)
API_KEY_PEPPER=$(generate_hex)

# Now proceed with installation
log_message "\nStarting OpenAlgo installation..." "$YELLOW"

# Basic security setup
log_message "\nApplying basic security settings..." "$BLUE"

# Wait for any running package managers to finish
wait_for_apt

# Update system
log_message "Updating system packages..." "$BLUE"
sudo apt-get update && sudo apt-get upgrade -y
check_status "Failed to update system"

# Install essential packages
log_message "Installing essential packages..." "$BLUE"
wait_for_apt
sudo apt-get install -y python3 python3-venv python3-pip python3-full git ufw fail2ban snapd software-properties-common
check_status "Failed to install packages"

# Install uv using snap for faster package installation
log_message "Installing uv package manager..." "$BLUE"
wait_for_apt
sudo snap install astral-uv --classic
check_status "Failed to install uv"

# Configure UFW firewall
log_message "Setting up firewall..." "$BLUE"
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw --force enable
check_status "Failed to configure firewall"

# Basic fail2ban configuration
log_message "Configuring fail2ban..." "$BLUE"
cat << EOF | sudo tee /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
EOF

sudo systemctl restart fail2ban
check_status "Failed to configure fail2ban"

# Installation paths
BASE_PATH="/var/python/openalgo"
VENV_PATH="$BASE_PATH/venv"
SERVICE_NAME="openalgo"

# Check existing installation
if [ -d "$BASE_PATH" ]; then
    log_message "Warning: OpenAlgo already installed at $BASE_PATH" "$YELLOW"
    read -p "Remove existing installation? (y/n): " remove_choice
    if [[ $remove_choice =~ ^[Yy]$ ]]; then
        log_message "Removing existing installation..." "$BLUE"
        sudo systemctl stop $SERVICE_NAME 2>/dev/null
        sudo systemctl disable $SERVICE_NAME 2>/dev/null
        sudo rm -rf "$BASE_PATH"
    else
        log_message "Installation aborted" "$RED"
        exit 1
    fi
fi

# Create directory structure
log_message "\nCreating installation directory..." "$BLUE"
sudo mkdir -p /var/python
sudo mkdir -p $BASE_PATH
check_status "Failed to create directory"

# Clone repository
log_message "Cloning OpenAlgo repository..." "$BLUE"
sudo git clone https://github.com/marketcalls/openalgo.git $BASE_PATH
check_status "Failed to clone repository"

# Create virtual environment using uv
log_message "Creating Python virtual environment with uv..." "$BLUE"
sudo uv venv $VENV_PATH
check_status "Failed to create virtual environment"

# Install dependencies using uv (much faster)
log_message "Installing Python dependencies with uv..." "$BLUE"
ACTIVATE_CMD="source $VENV_PATH/bin/activate"
sudo bash -c "$ACTIVATE_CMD && uv pip install -r $BASE_PATH/requirements-nginx.txt"
check_status "Failed to install dependencies"

# Ensure gunicorn and eventlet are installed
log_message "Ensuring gunicorn and eventlet are installed..." "$BLUE"
sudo bash -c "$ACTIVATE_CMD && uv pip install gunicorn eventlet"
check_status "Failed to install gunicorn/eventlet"

# Configure .env file
log_message "Configuring environment..." "$BLUE"
sudo cp $BASE_PATH/.sample.env $BASE_PATH/.env
sudo sed -i "s|YOUR_BROKER_API_KEY|$BROKER_API_KEY|g" $BASE_PATH/.env
sudo sed -i "s|YOUR_BROKER_API_SECRET|$BROKER_API_SECRET|g" $BASE_PATH/.env

# Update market data credentials for XTS
if is_xts_broker "$BROKER_NAME"; then
    sudo sed -i "s|YOUR_BROKER_MARKET_API_KEY|$BROKER_API_KEY_MARKET|g" $BASE_PATH/.env
    sudo sed -i "s|YOUR_BROKER_MARKET_API_SECRET|$BROKER_API_SECRET_MARKET|g" $BASE_PATH/.env
fi

sudo sed -i "s|http://127.0.0.1:5000|http://$SERVER_IP|g" $BASE_PATH/.env
sudo sed -i "s|<broker>|$BROKER_NAME|g" $BASE_PATH/.env
sudo sed -i "s|3daa0403ce2501ee7432b75bf100048e3cf510d63d2754f952e93d88bf07ea84|$APP_KEY|g" $BASE_PATH/.env
sudo sed -i "s|a25d94718479b170c16278e321ea6c989358bf499a658fd20c90033cef8ce772|$API_KEY_PEPPER|g" $BASE_PATH/.env
check_status "Failed to configure environment"

# Create systemd service
log_message "Creating systemd service..." "$BLUE"
sudo tee /etc/systemd/system/$SERVICE_NAME.service > /dev/null << EOL
[Unit]
Description=OpenAlgo Trading Platform
After=network.target

[Service]
Type=exec
User=www-data
Group=www-data
WorkingDirectory=$BASE_PATH
Environment="PATH=$VENV_PATH/bin"
ExecStart=$VENV_PATH/bin/gunicorn --worker-class eventlet -w 1 --bind 0.0.0.0:80 --timeout 120 app:app
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOL
check_status "Failed to create service"

# Create required directories
log_message "Creating required directories..." "$BLUE"
sudo mkdir -p $BASE_PATH/db
sudo mkdir -p $BASE_PATH/tmp

# Set correct permissions
log_message "Setting permissions..." "$BLUE"

# Set ownership to www-data (web server user)
sudo chown -R www-data:www-data $BASE_PATH
sudo chmod -R 755 $BASE_PATH

# Ensure virtual environment has correct permissions
sudo chown -R www-data:www-data $VENV_PATH
sudo chmod -R 755 $VENV_PATH

# Grant capability to bind to port 80
log_message "Granting permission to bind to port 80..." "$BLUE"
# Find the real python executable (not symlink)
REAL_PYTHON=$(readlink -f $VENV_PATH/bin/python3)
sudo setcap 'cap_net_bind_service=+ep' $REAL_PYTHON
check_status "Failed to set port binding capability"

# Verify permissions
log_message "Verifying permissions..." "$BLUE"
ls -la $BASE_PATH
check_status "Failed to set permissions"

# Start service
log_message "Starting OpenAlgo service..." "$BLUE"
sudo systemctl daemon-reload
sudo systemctl enable $SERVICE_NAME
sudo systemctl start $SERVICE_NAME
check_status "Failed to start service"

# Wait for service to start
sleep 3

# Check if service is running
if sudo systemctl is-active --quiet $SERVICE_NAME; then
    log_message "\nOpenAlgo is running successfully!" "$GREEN"
else
    log_message "\nWarning: Service may not have started properly" "$YELLOW"
    log_message "Check logs with: sudo journalctl -u $SERVICE_NAME -n 50" "$YELLOW"
fi

# Installation complete
log_message "\n========================================" "$GREEN"
log_message "Installation Complete!" "$GREEN"
log_message "========================================" "$GREEN"

log_message "\nAccess Details:" "$YELLOW"
log_message "URL: http://$SERVER_IP" "$GREEN"
log_message "Broker: $BROKER_NAME" "$GREEN"
log_message "Installation: $BASE_PATH" "$GREEN"

log_message "\nSecurity Status:" "$YELLOW"
log_message "✓ Firewall: Enabled (SSH + HTTP)" "$GREEN"
log_message "✓ Fail2ban: Active (SSH protection)" "$GREEN"
log_message "✓ Service: Running as isolated systemd unit" "$GREEN"

log_message "\nUseful Commands:" "$YELLOW"
log_message "View logs: sudo journalctl -u $SERVICE_NAME -f" "$BLUE"
log_message "Restart: sudo systemctl restart $SERVICE_NAME" "$BLUE"
log_message "Status: sudo systemctl status $SERVICE_NAME" "$BLUE"
log_message "Firewall: sudo ufw status" "$BLUE"
log_message "Fail2ban: sudo fail2ban-client status sshd" "$BLUE"

log_message "\nRecommendations:" "$YELLOW"
log_message "1. Test the installation by visiting http://$SERVER_IP" "$BLUE"
log_message "2. Monitor logs for any errors" "$BLUE"
log_message "3. Consider using a reverse proxy for production" "$BLUE"
log_message "4. Set up regular backups of $BASE_PATH/db" "$BLUE"

log_message "\nLog saved to: $LOG_FILE" "$GREEN"

Installation Steps

# Make the script executable
chmod +x install.sh

# Execute the installation script
sudo ./install.sh

The script will interactively prompt you for:

  • Broker selection

  • Broker API credentials

The installation process will:

  • Install required packages

  • Configure Nginx

  • Set up the OpenAlgo application

  • Create systemd service with unique name based on domain and broker

Last updated