A web-based tool to manage multiple OpenSPP Docker test deployments, allowing testers to easily deploy, configure, and manage OpenSPP instances with different versions and configurations.
This application has NO AUTHENTICATION and should NEVER be exposed to the public internet!
- The admin UI allows full control over Docker deployments without any login
- Anyone with access can create, modify, and delete deployments
- This tool is designed for:
- Internal use behind a VPN
- Local development environments
- Private networks with restricted access
- DO NOT deploy this on a public-facing server
- DO NOT expose port 8501 (Streamlit) to the internet
For production use, ensure this application is only accessible through:
- Corporate VPN
- Private network with firewall rules
- Local development machine
- β Easy Deployment: Deploy multiple isolated OpenSPP instances with a few clicks
- π Version Management: Select specific OpenSPP versions and dependency branches
- π Domain Mapping: Automatic subdomain configuration (e.g., tester1-dev.test.openspp.org)
- β‘ Task Execution: Execute invoke tasks through the web UI
- π Monitoring: Real-time container status and resource usage
- π Log Streaming: View logs from any service
- π§ Lifecycle Management: Start, stop, update, and delete deployments
- π§Ή Automatic Cleanup: Clean up old deployments and Docker resources
- Python 3.11+ with
uv
package manager - Docker and Docker Compose
- Git
- Nginx (for domain routing)
- Sudo access (for Nginx configuration)
- OpenSPP Docker repository access
git clone https://github.com/OpenSPP/openspp-deployment-manager.git
cd openspp-deployment-manager
# Using uv (recommended)
uv sync
# Or using pip
pip install -r requirements.txt
# Copy example environment file
cp .env.example .env
# Edit .env with your settings
nano .env
Key configuration options:
DEPLOYMENT_BASE_PATH
: Where to store deployments (default:./deployments
)BASE_DOMAIN
: Your base domain for subdomains (default:test.openspp.org
)PORT_RANGE_START/END
: Port range for deployments (default: 18000-19000)
python -m src.database init
# Using streamlit directly
streamlit run app.py
# Or using uv
uv run streamlit run app.py
The application will be available at http://localhost:8501
IMPORTANT: Do not expose port 8501 to the internet. Use VPN or firewall rules to restrict access.
- Click "β New Deployment" button
- Fill in the required fields:
- Tester Email: Email of the person creating the deployment
- Deployment Name: Unique name (3-20 chars, alphanumeric + hyphens)
- Environment: Choose between devel, test, or prod
- OpenSPP Version: Select from available versions
- Optionally override dependency versions in Advanced Options
- Click "π Create Deployment" The system will:
- Clone openspp-docker repository
- Configure versions in repos.yaml
- Generate environment variables
- Build and start all services
- Configure Nginx for subdomain access
Each deployment card shows:
- Status indicator (π’ Running, π΄ Stopped, etc.)
- Version information
- Resource usage (CPU/Memory)
- Quick action buttons
Available actions:
βΆοΈ Start: Start stopped deployment- βΉοΈ Stop: Stop running deployment
- π Logs: View recent logs
- βοΈ Manage: Open management panel
- ποΈ Delete: Remove deployment
In the management panel, you can execute various invoke tasks:
- Lifecycle: start, stop, restart
- Database: resetdb, snapshot, restore-snapshot
- Development: logs, install, update, test
- Git: git-aggregate
- Click the π button or go to the management panel
- Select service (all, odoo, db, smtp)
- Choose number of lines (50-500)
- Click "π Refresh Logs" to update
Main application configuration:
deployment:
base_path: "./deployments"
max_per_tester: 3
docker:
resource_limits:
cpu: "2"
memory: "4GB"
ports:
range_start: 18000
range_end: 19000
domain:
base: "test.openspp.org"
Each deployment gets a port range:
- Base port (e.g., 18000)
- SMTP: base + 25
- PGWeb: base + 81
- Debugger: base + 84
The system automatically generates Nginx configurations for each deployment:
server {
listen 80;
server_name tester1-dev.test.openspp.org;
location / {
proxy_pass http://localhost:18000;
# ... proxy settings
}
}
To manually regenerate all Nginx configs:
python -m src.domain_manager generate-nginx
sudo nginx -s reload
The deployment manager includes an optimized Git caching system that significantly reduces disk usage and speeds up deployments. The Odoo repository, which normally takes 13GB+, is automatically shallow-cloned to under 1.5GB.
# Analyze cache usage and statistics
uv run python manage_git_cache.py analyze
# Optimize cache (garbage collection)
uv run python manage_git_cache.py optimize
# Aggressive optimization (converts large repos to shallow clones)
uv run python manage_git_cache.py optimize --aggressive
# Clean up old repositories (default: 30 days)
uv run python manage_git_cache.py cleanup --max-age 7
# Optimize Odoo repository specifically
uv run python manage_git_cache.py odoo
# Clear entire cache (requires confirmation)
uv run python manage_git_cache.py clear
- Automatic Shallow Cloning: Large repositories (Odoo, OCA/OCB) are automatically shallow-cloned with depth=1
- Space Savings: Reduces Odoo from ~13GB to ~1GB (90%+ reduction)
- Smart Caching: 5-minute TTL prevents unnecessary fetches
- Branch-Specific Fetching: Only fetches required branches
- Automatic Cleanup: Remove repositories not accessed in X days
- Repository Statistics: Track sizes and optimization potential
In config.yaml
:
git_cache_path: "./.git_cache" # Where to store cached repositories
The cache manager automatically:
- Detects and optimizes large repositories
- Maintains shallow clones for space efficiency
- Provides detailed statistics on cache usage
- Cleans up unused repositories
- Streamlit UI (
app.py
): Web interface - Deployment Manager (
src/deployment_manager.py
): Core orchestration - Docker Handler (
src/docker_handler.py
): Container management - Database (
src/database.py
): SQLite persistence - Domain Manager (
src/domain_manager.py
): Nginx configuration - Git Cache Manager (
src/git_cache.py
): Optimized repository caching
- User creates deployment via UI
- Manager allocates resources (ports, subdomain)
- Git clones openspp-docker
- Updates configuration (repos.yaml, .env)
- Executes invoke tasks (build, start)
- Configures Nginx
- Monitors container status
Port allocation failed
- Check if ports 18000-19000 are available
- Increase port range in config.yaml
Docker build errors
- Ensure Docker daemon is running
- Check Docker disk space
- Verify openspp-docker repository access
Nginx configuration failed
- Ensure sudo access is configured
- Check Nginx is installed
- Verify sites-available/enabled paths
Services not starting
- Check logs:
docker compose logs -f odoo
- Verify .env file is correct
- Ensure sufficient system resources
Sync deployment states
# From UI: Click "π Sync States" in sidebar
Clean up Docker resources
# From UI: Click "π§Ή Cleanup Resources"
# Or manually:
docker system prune -a
Remove old deployments
# Automatic cleanup configured in config.yaml
# cleanup.stopped_deployment_days: 7
openspp-deployment-manager/
βββ app.py # Streamlit application
βββ manage_git_cache.py # Git cache management utility
βββ src/
β βββ deployment_manager.py # Core logic
β βββ docker_handler.py # Docker operations
β βββ database.py # SQLite operations
β βββ domain_manager.py # Nginx management
β βββ git_cache.py # Git repository caching
β βββ models.py # Data models
β βββ utils.py # Utilities
βββ deployments/ # Deployment storage
βββ .git_cache/ # Cached git repositories
βββ config.yaml # Configuration
βββ requirements.txt # Dependencies
Edit ALLOWED_INVOKE_TASKS
in app.py
:
ALLOWED_INVOKE_TASKS = {
"new-task": {
"params": ["param1", "param2"],
"description": "Task description",
"icon": "βοΈ"
}
}
SQLite tables:
deployments
: Deployment metadataport_allocations
: Port range tracking
- MUST run behind VPN or private network - NEVER expose to public internet
- The admin UI (port 8501) provides unrestricted access to:
- Create/delete Docker deployments
- Execute system commands via invoke tasks
- Access deployment logs and configurations
- Manage system resources
- Nginx configurations use security headers for deployed instances
- Environment variables contain sensitive data (database passwords, etc.)
- Database is local SQLite file with no access control
- Docker containers run with resource limits but still have system access
Recommended Security Measures:
- Run only on internal networks or behind VPN
- Use firewall rules to restrict access to port 8501
- Monitor access logs regularly
- Consider adding a reverse proxy with authentication if broader access is needed
- Regularly audit deployed instances and remove unused ones
The project includes a comprehensive test suite:
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=src --cov-report=html
# Run specific test file
uv run pytest tests/test_deployment_manager.py -v
We welcome contributions! Please see CONTRIBUTING.md for guidelines on:
- Development setup
- Code style and standards
- Testing requirements
- Pull request process
- Security considerations
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
For issues and questions:
- Check the troubleshooting guide above
- Review logs in
logs/
directory - Open a GitHub issue with details
- For OpenSPP-specific questions, visit OpenSPP documentation