Development setup
Contents
Development setup#
For: developers
This guide walks you through setting up a local OpenSPP development environment. OpenSPP V2 runs on Odoo 19 (OCA/OCB) inside Docker — the container ships with Python 3.13. The only Python you install on your host is for the spp CLI (3.12+).
Prerequisites#
Before you begin, make sure you have:
Tool |
Version |
Purpose |
|---|---|---|
20.10+ |
Container runtime |
|
V2+ |
Multi-container orchestration |
|
2.30+ |
Source control |
|
Python |
3.12+ |
Running the |
Clone the repository#
git clone git@github.com:OpenSPP/OpenSPP2.git
cd OpenSPP2
The spp CLI#
OpenSPP includes a developer CLI that wraps common Docker Compose operations. Activate it by sourcing the activate script:
. ./activate
This adds spp to your PATH and enables tab completion (bash/zsh). You can verify your setup with:
spp doctor
Command reference#
Command |
Alias |
Purpose |
|---|---|---|
|
|
Start the development server |
|
— |
Stop all services |
|
|
Restart the Odoo container |
|
|
Run module tests |
|
|
Update changed modules |
|
|
View container logs |
|
|
Open Odoo interactive shell |
|
— |
Open PostgreSQL shell or run SQL |
|
— |
Show or open the dev server URL |
|
— |
Run linters on files |
|
|
Build Docker images |
|
|
Show service status |
|
— |
Check prerequisites |
Configuration#
You can create a ~/.spp.toml file to set your defaults:
default_demo = "mis"
default_profile = "dev"
default_db = "openspp"
Start the development server#
spp start --demo mis
This command:
Builds the Docker image if needed (checks dependency freshness on each run)
Starts PostgreSQL 18 with PostGIS
Starts the Odoo server with the MIS demo modules installed
Starts the job worker for background tasks
The --demo flag specifies which demo data to load:
Profile |
Module |
Description |
|---|---|---|
|
|
Full social protection MIS |
|
|
Disaster relief (Sri Lanka config) |
|
|
Grievance redress mechanism |
You can also pass a module name directly: spp start --demo spp_base_common.
Access the application#
By default, the dev profile uses a dynamic port to avoid conflicts. Find the assigned port with:
spp url
Or open it directly in your browser:
spp url --open
If you need a fixed port (for example, when connecting external tools), use the ui profile:
spp start --demo mis --profile ui
This binds Odoo to http://localhost:8069.
Default credentials: admin / admin
Docker Compose profiles#
Under the hood, spp start runs Docker Compose with profiles:
Profile |
Purpose |
|---|---|
|
Development server with dynamic port (default) |
|
Fixed port 8069 for UI development |
|
End-to-end testing environment with Playwright |
You can also use Docker Compose directly:
docker compose --profile dev up -d
docker compose --profile dev ps # Shows assigned port
Services#
The development environment runs these services:
Service |
Image |
Purpose |
|---|---|---|
|
|
PostgreSQL 18 with PostGIS |
|
Built from |
Odoo web server |
|
Same image |
Background job queue processor |
Common development tasks#
View logs#
spp logs # All services
spp logs openspp -f --tail=100 # Follow Odoo logs
Auto-reload#
The dev profile enables auto-reload by default (--dev=reload,qweb,xml). This means most Python code changes are picked up automatically without restarting the container. You will see a "Watching for file changes" message in the logs.
To disable auto-reload:
spp start --demo mis --no-watch
Restart Odoo#
Some changes require a manual restart (e.g., adding new files, changing __init__.py imports, modifying __manifest__.py dependencies):
spp restart
Update modules#
When you change module files (models, views, data), update the affected modules:
spp update
This auto-detects which modules have changed by comparing checksums.
Open a shell#
spp shell # Odoo interactive shell
spp sql # PostgreSQL shell (psql)
spp sql "SELECT id, name FROM spp_program LIMIT 5;"
Install a new module#
If you're developing a new module and want to install it, you can either:
Via the CLI — restart with the module specified:
spp stop ODOO_INIT_MODULES=spp_my_module spp start
Via the Odoo UI — go to Apps, click Update Apps List, search for your module, and click Install.
Reset the database#
spp resetdb --demo mis
This drops the current database and recreates it with the specified demo data. You will be prompted to confirm.
Alternatively, you can wipe everything and start fresh in one step:
spp start --demo mis --wipe
Stop the environment#
spp stop
To also remove volumes (full cleanup):
docker compose --profile dev down -v
Running tests#
Run tests for a specific module in an isolated database:
spp test spp_registry
This creates a temporary test database, runs the tests, and reports results. Your development database is not affected.
Run with specific test tags:
spp test spp_programs --tags=post_install
Test output is displayed in your terminal. Detailed logs are also saved inside the container at /tmp/openspp-test-logs/.
Code quality tools#
Pre-commit hooks#
OpenSPP uses pre-commit hooks to enforce code standards. Install them with:
pip install pre-commit
pre-commit install
The hooks run automatically on git commit and include:
Ruff — Python linting and formatting (line length: 120, target: Python 3.12+)
Prettier — Formatting for CSS, HTML, JSON, YAML, XML
ESLint — JavaScript validation
Pylint-Odoo — Odoo-specific checks (valid versions: 19.0)
Gitleaks — Secret detection
Bandit — Python security scanning
Semgrep — Static analysis with OpenSPP custom rules
OpenSPP custom linting — Naming conventions, PII-in-logs detection, API security, Odoo 19 compatibility
Run linters manually#
spp lint # Lint changed files (default)
spp lint spp_programs/models/programs.py # Lint specific files
You can also run pre-commit directly for more control:
pre-commit run --all-files # All hooks on all files
pre-commit run ruff --all-files # Specific hook on all files
Key code style settings#
Setting |
Value |
|---|---|
Line length |
120 |
Python target |
3.12+ |
Indent (Python, XML) |
4 spaces |
Indent (JSON, YAML) |
2 spaces |
Line endings |
LF |
Import order |
future, stdlib, third-party, odoo, odoo-addons, first-party, local-folder |
Environment variables#
These environment variables configure the Odoo container:
Required#
Variable |
Default |
Description |
|---|---|---|
|
— |
PostgreSQL hostname |
|
|
PostgreSQL port |
|
— |
Database user |
|
— |
Database password |
|
|
Database name |
|
— |
Admin user password |
Optional#
Variable |
Default |
Description |
|---|---|---|
|
— |
Full connection URL (overrides individual |
|
— |
Comma-separated modules to install on startup |
|
— |
Comma-separated modules to update on startup |
|
|
Number of worker processes |
|
|
Log level: |
|
|
Enable when behind a reverse proxy |
Note
When using the spp CLI, these variables are managed automatically. You only need to set them when running Docker Compose directly or deploying to production.
Project structure#
OpenSPP2/
├── spp_base_common/ # Core foundation module
├── spp_registry/ # Registrant management
├── spp_programs/ # Program management
├── spp_* # Other OpenSPP modules (~110 total)
├── docker/
│ ├── Dockerfile # Multi-stage build (builder → runtime → dev → production)
│ ├── entrypoint.sh # Container startup and DB initialization
│ ├── odoo.conf.template # Odoo configuration template
│ ├── requirements.txt # Additional Python dependencies
│ └── requirements-dev.txt # Dev-only tools (debugpy, pudb, watchdog)
├── scripts/
│ └── test_single_module.sh # Test runner script
├── docker-compose.yml # Development Docker Compose
├── spp # Developer CLI
├── activate # CLI activation script
├── requirements.txt # Core Python dependencies (from manifests)
├── pyproject.toml # Project configuration
├── .pre-commit-config.yaml # Pre-commit hook configuration
├── .ruff.toml # Ruff linter configuration
├── .pylintrc # Pylint configuration (optional checks)
├── .pylintrc-mandatory # Pylint configuration (blocking checks)
└── .editorconfig # Editor settings
IDE configuration#
VS Code#
Recommended extensions for OpenSPP development:
Python (ms-python.python)
Pylance (ms-python.vscode-pylance)
Ruff (charliermarsh.ruff)
XML (redhat.vscode-xml)
Remote debugging#
The dev Docker image includes debugpy for remote debugging. Configure your IDE to attach to the debugger on the standard port.
Are you stuck?#
Docker image won't build? Run
spp doctorto check prerequisites.Module not found? Make sure it's in the addons path. OpenSPP modules are mounted at
/mnt/extra-addons/opensppinside the container.Database errors after code changes? Try
spp updateto apply pending migrations, orspp resetdb --demo misfor a clean slate.Port conflict? The
devprofile uses a dynamic port. Usespp urlto find the assigned port, or switch to--profile uifor a fixed port.Pre-commit hooks failing? Run
pre-commit run --all-filesto identify issues, orpre-commit run ruff --all-filesto auto-fix Python formatting.
openspp.org