Modern ERP Reports Application with microservices architecture Tech Stack: - Backend: FastAPI + python-oracledb (Oracle DB integration) - Frontend: Vue.js 3 + PrimeVue + Vite - Telegram Bot: python-telegram-bot + SQLite - Infrastructure: Shared database pool, JWT authentication, SSH tunnel Features: - FastAPI backend with async Oracle connection pool - Vue.js 3 responsive frontend with PrimeVue components - Telegram bot alternative interface - Microservices architecture with shared components - Complete deployment support (Linux Docker + Windows IIS) - Comprehensive testing (Playwright E2E + pytest) Repository Structure: - reports-app/ - Main application (backend, frontend, telegram-bot) - shared/ - Shared components (database pool, auth, utils) - deployment/ - Deployment scripts (Linux & Windows) - docs/ - Project documentation - security/ - Security scanning and git hooks
144 lines
4.2 KiB
Bash
144 lines
4.2 KiB
Bash
#!/bin/bash
|
|
# SSH Tunnel Docker Container Script
|
|
# Maintains SSH tunnel to Oracle database
|
|
|
|
set -e
|
|
|
|
# Configuration from environment variables
|
|
SSH_SERVER="${SSH_SERVER:-83.103.197.79}"
|
|
SSH_PORT="${SSH_PORT:-22122}"
|
|
SSH_USER="${SSH_USER:-roa2web}"
|
|
SSH_KEY_PATH="${SSH_KEY_PATH:-/home/tunnel/.ssh/roa_oracle_server}"
|
|
LOCAL_PORT="${LOCAL_PORT:-1521}"
|
|
REMOTE_HOST="${REMOTE_HOST:-10.0.20.36}"
|
|
REMOTE_PORT="${REMOTE_PORT:-1521}"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
log() {
|
|
echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
|
|
}
|
|
|
|
log "${BLUE}🚀 Starting SSH tunnel container...${NC}"
|
|
log "${BLUE}Tunnel: localhost:${LOCAL_PORT} -> ${SSH_SERVER}:${SSH_PORT} -> ${REMOTE_HOST}:${REMOTE_PORT}${NC}"
|
|
|
|
# Check if SSH key exists
|
|
if [ ! -f "$SSH_KEY_PATH" ]; then
|
|
log "${RED}❌ SSH private key not found at $SSH_KEY_PATH${NC}"
|
|
log "${YELLOW}Please mount your SSH key as a volume:${NC}"
|
|
log "${YELLOW} -v ~/.ssh/roa_oracle_server:/home/tunnel/.ssh/roa_oracle_server:ro${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Set proper permissions for SSH key (skip if operation not permitted)
|
|
chmod 600 "$SSH_KEY_PATH" 2>/dev/null || log "${YELLOW}⚠️ Could not set SSH key permissions (continuing anyway)${NC}"
|
|
|
|
# Create SSH config for better connection handling
|
|
mkdir -p /home/tunnel/.ssh
|
|
cat > /home/tunnel/.ssh/config << EOF
|
|
Host tunnel-server
|
|
HostName ${SSH_SERVER}
|
|
Port ${SSH_PORT}
|
|
User ${SSH_USER}
|
|
IdentityFile ${SSH_KEY_PATH}
|
|
StrictHostKeyChecking no
|
|
UserKnownHostsFile /dev/null
|
|
ServerAliveInterval 30
|
|
ServerAliveCountMax 3
|
|
TCPKeepAlive yes
|
|
ExitOnForwardFailure yes
|
|
BatchMode yes
|
|
EOF
|
|
|
|
chmod 600 /home/tunnel/.ssh/config
|
|
|
|
# Function to establish tunnel
|
|
establish_tunnel() {
|
|
log "${YELLOW}🔗 Establishing SSH tunnel...${NC}"
|
|
|
|
ssh -N -T \
|
|
-o ConnectTimeout=30 \
|
|
-o ServerAliveInterval=30 \
|
|
-o ServerAliveCountMax=3 \
|
|
-o ExitOnForwardFailure=yes \
|
|
-o GatewayPorts=yes \
|
|
-L "0.0.0.0:${LOCAL_PORT}:${REMOTE_HOST}:${REMOTE_PORT}" \
|
|
tunnel-server &
|
|
|
|
SSH_PID=$!
|
|
echo $SSH_PID > /tmp/ssh_tunnel.pid
|
|
|
|
# Wait a moment for tunnel to establish
|
|
sleep 5
|
|
|
|
# Test tunnel
|
|
if nc -z localhost "$LOCAL_PORT" >/dev/null 2>&1; then
|
|
log "${GREEN}✅ SSH tunnel established successfully (PID: $SSH_PID)${NC}"
|
|
return 0
|
|
else
|
|
log "${RED}❌ Failed to establish SSH tunnel${NC}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to monitor tunnel
|
|
monitor_tunnel() {
|
|
while true; do
|
|
if [ -f /tmp/ssh_tunnel.pid ]; then
|
|
local pid=$(cat /tmp/ssh_tunnel.pid)
|
|
|
|
# Check if process is still running
|
|
if ! ps -p "$pid" > /dev/null 2>&1; then
|
|
log "${YELLOW}⚠️ SSH tunnel process died, restarting...${NC}"
|
|
establish_tunnel
|
|
fi
|
|
|
|
# Check if port is still accessible
|
|
if ! nc -z localhost "$LOCAL_PORT" >/dev/null 2>&1; then
|
|
log "${YELLOW}⚠️ SSH tunnel port not accessible, restarting...${NC}"
|
|
if [ -f /tmp/ssh_tunnel.pid ]; then
|
|
kill $(cat /tmp/ssh_tunnel.pid) 2>/dev/null || true
|
|
rm -f /tmp/ssh_tunnel.pid
|
|
fi
|
|
establish_tunnel
|
|
fi
|
|
else
|
|
log "${YELLOW}⚠️ SSH tunnel not running, starting...${NC}"
|
|
establish_tunnel
|
|
fi
|
|
|
|
sleep 30
|
|
done
|
|
}
|
|
|
|
# Function to handle shutdown gracefully
|
|
cleanup() {
|
|
log "${YELLOW}📋 Shutting down SSH tunnel...${NC}"
|
|
if [ -f /tmp/ssh_tunnel.pid ]; then
|
|
local pid=$(cat /tmp/ssh_tunnel.pid)
|
|
kill "$pid" 2>/dev/null || true
|
|
rm -f /tmp/ssh_tunnel.pid
|
|
fi
|
|
log "${GREEN}✅ SSH tunnel stopped${NC}"
|
|
exit 0
|
|
}
|
|
|
|
# Set up signal handlers
|
|
trap cleanup SIGTERM SIGINT
|
|
|
|
# Initial tunnel establishment
|
|
if establish_tunnel; then
|
|
log "${GREEN}🎉 SSH tunnel container ready!${NC}"
|
|
log "${BLUE}Oracle database accessible at localhost:${LOCAL_PORT}${NC}"
|
|
|
|
# Start monitoring
|
|
monitor_tunnel
|
|
else
|
|
log "${RED}💥 Failed to establish initial SSH tunnel${NC}"
|
|
exit 1
|
|
fi |