Manage Projects
Feature ID: PROJ-001
Category: Projects
API Endpoints: /api/v1/projects
Overview
Projects are the core organizational unit in OEC.SH, representing individual Odoo applications that can be deployed across multiple environments. Each project acts as a container for:
- Multiple environments (development, staging, production)
- Deployment configurations (Odoo version, Docker images, resource allocations)
- Git repository connections (GitHub, GitLab, Bitbucket)
- Custom addon repositories and module selections
- Project-level access control (project members with granular roles)
What makes projects unique in OEC.SH:
- Multi-environment architecture: Each project can have multiple isolated environments deployed to different servers
- Environment-first design: Projects define the blueprint; environments are the actual deployments
- Flexible server allocation: Each environment within a project can run on a different VM/server
- Quota enforcement: Resource allocation tracked at the organization level across all project environments
Architecture
Organizational Hierarchy
Organization
├─ Projects (1:N)
│ ├─ Environments (1:N)
│ │ └─ VM/Server Assignment (1:1)
│ ├─ Git Repository
│ ├─ Odoo Version Config
│ └─ Project Members
└─ Resource Quota LimitsKey Concepts
Project vs Environment:
- Project: Blueprint and configuration container (no actual deployment)
- Environment: Actual running Odoo instance with dedicated containers, database, and resources
- Deployment: Process of deploying or updating an environment
Resource Model:
- Projects define default resource limits (CPU, RAM)
- Environments override with actual resource allocations
- Only active environments (
is_active = true) count toward quota
Prerequisites
Required Permissions
| Action | Permission Code | Default Roles |
|---|---|---|
| Create project | org.projects.create | Org Owner, Org Admin |
| List projects | org.projects.list | All organization members |
| View project | project.view | All project members |
| Update project | org.projects.update | Org Owner, Org Admin, Project Admin |
| Delete project | org.projects.delete | Org Owner, Org Admin |
Organization Setup
Before creating your first project:
- Active organization membership: Join or create an organization
- Resource quota: Ensure organization has available quota (check Settings → Billing)
- Server infrastructure: At least one server configured (optional for initial creation, required for deployment)
- Git connection (optional): Connect GitHub/GitLab for auto-deploy webhooks
Create Project
Step 1: Navigate to Project Creation
- Go to Dashboard → Projects
- Click New Project button (top-right)
- You will be redirected to
/projects/new
Step 2: Configure Basic Information
Project Name
- Field: Project Name (required)
- Format: Human-readable name for your project
- Example: "ACME ERP System", "Customer Portal v2"
- Validation: 1-255 characters
- Auto-generation: Slug is automatically created from the name
Project Slug
- Field: URL Slug (auto-generated, editable)
- Format: Lowercase letters, numbers, and hyphens only
- Pattern: Auto-generated as
^[a-z0-9-]+$ - Example:
acme-erp-system,customer-portal-v2 - Uniqueness: Must be unique within your organization
- Usage: Used in URLs, environment names, and container identifiers
Description
- Field: Description (optional)
- Format: Multi-line text
- Purpose: Document project purpose, customer info, or special notes
- Max Length: No hard limit, recommended < 1000 characters
Step 3: Select Odoo Version
Odoo Version Selection
- Field: Odoo Version (required dropdown)
- Available Options:
- Odoo 14.0
- Odoo 15.0
- Odoo 16.0
- Odoo 17.0
- Odoo 18.0
- Odoo 19.0
Version Selection Criteria:
- New projects: Use latest stable version (Odoo 19.0)
- Legacy migrations: Match your current Odoo version
- Enterprise features: Ensure your license supports the version
- Module compatibility: Verify third-party modules support the version
Version Restrictions:
- Only
ACTIVEandBETAversions are shown in the dropdown - Deprecated versions (
DEPRECATEDstatus) are hidden from new projects - Existing projects on deprecated versions continue to work
Step 4: Configure Git Repository (Optional)
Connect your project to a Git repository for version control and auto-deployment.
Repository URL
- Field: Repository URL (optional)
- Format: Full Git clone URL
- Supported Formats:
- HTTPS:
https://github.com/username/repo.git - SSH:
git@github.com:username/repo.git
- HTTPS:
- Private Repositories: Requires Git connection with access token (configured in Settings → Git Connections)
Git Provider
- Field: Git Provider (auto-detected from URL)
- Options:
- GitHub
- GitLab
- Bitbucket
- Webhook Registration: If you have an active OAuth connection, webhooks are auto-registered for push events
Webhook Behavior:
- Auto-registration: If repository URL + OAuth token available → webhook created automatically
- Manual setup: If no OAuth token → you'll need to configure webhook manually after project creation
- Webhook URL:
https://app.oec.sh/api/v1/webhooks/{github|gitlab} - Secret: Unique webhook secret generated per project (shown in project settings)
Important Notes:
- Git branch is NOT configured at project level
- Each environment configures its own branch (e.g.,
mainfor production,developfor staging) - This allows different environments to track different branches
Step 5: Custom Docker Image (Advanced)
By default, OEC.SH uses official Odoo Docker images. For custom builds:
- Click Advanced Settings → Custom Docker Image
- Configure image source:
Image Source Type
- Default:
docker_hub(officialodooimage) - Custom Options:
docker_hub_private: Private Docker Hub repositoryaws_ecr: AWS Elastic Container Registrygcp_gcr: Google Container Registrygcp_ar: Google Artifact Registryazure_acr: Azure Container Registrygitlab_registry: GitLab Container Registrygithub_registry: GitHub Container Registry (ghcr.io)self_hosted: Custom private registry
Custom Image Configuration
- Image Name: Docker image name (e.g.,
mycompany/odoo-custom) - Image Tag: Tag override (defaults to Odoo version if not set)
- Registry URL: Custom registry URL (e.g.,
registry.gitlab.com/mycompany) - Registry Credentials: Select stored credentials (configured in Settings → Registry Credentials)
- Image Digest: SHA256 digest for immutable deployments (optional)
Step 6: Organization Assignment
Organization Selection
- Field: Organization (auto-detected for most users)
- Default Behavior:
- If you belong to one organization → auto-selected
- If you belong to multiple organizations → dropdown shown
- If you belong to no organizations → default organization created automatically
- Validation: You must be an active member of the selected organization
Step 7: Review and Create
- Review all settings in the summary panel (right sidebar)
- Quota Check: System validates:
- Organization project limit (based on billing plan)
- Available quota for future environment deployments
- Click Create Project
Success Actions:
- Project created with status
PENDING - Creator automatically added as Project Admin
- Default addon repositories auto-selected (platform + org repos with
default_selected = true) - Webhook registered (if Git repository + OAuth connection configured)
- Redirected to project detail page
List Projects
UI Navigation
- Go to Dashboard → Projects
- All projects you have access to are displayed in a table
Filter Options
Organization Filter
- Dropdown: Organization selector (top-left)
- Behavior: Shows only projects from selected organization
- Default: Shows all projects from all your organizations
Status Filter
- Dropdown: Status selector
- Options:
- All Statuses (default)
pending: Project created, no environments deployedcreating: Initial setup in progressactive: At least one environment runningdeploying: Deployment in progress for one or more environmentsrunning: Legacy alias foractivestopped: All environments stoppederror: One or more environments in error statearchived: Project archived (inactive)
Search
- Field: Search box (top-right)
- Searches: Project name, slug, description
- Behavior: Real-time filtering as you type
Sorting
Click column headers to sort by:
- Name: Alphabetical
- Status: Status priority (error → deploying → running → stopped → pending)
- Created: Most recent first (default)
- Environments: Number of active environments
Pagination
- Default: 100 projects per page
- API Parameters:
skipandlimitquery parameters - UI: Pagination controls at bottom of table
View Project Details
Navigation
- From projects list, click on any project row
- Or navigate directly to
/projects/{project-id}
Project Overview
The project detail page shows:
Header Section
- Project Name and slug
- Status Badge: Color-coded status indicator
- Quick Actions:
- Edit Project (pencil icon)
- Delete Project (trash icon, requires confirmation)
- Regenerate Webhook Secret
Configuration Tab
Displays current project settings:
Basic Information:
- Name, slug, description
- Organization
- Odoo version
- Created date and creator
- Last updated date
Git Configuration:
- Repository URL
- Git provider
- Webhook URL and secret (for manual setup)
- Webhook registration status
Docker Image:
- Image source type
- Full image reference (registry/name:tag)
- Registry credentials (if private)
Environments Tab
Lists all environments for this project:
| Column | Description |
|---|---|
| Name | Environment identifier |
| Type | Development / Staging / Production |
| Server | VM/server name and IP |
| Status | Current deployment status |
| URL | Primary accessible URL |
| Resources | CPU / RAM / Disk allocation |
| Actions | Deploy, Stop, Clone, Delete |
Deployments Tab
Shows deployment history across all environments:
- Deployment ID and timestamp
- Environment name
- Status (pending, running, completed, failed)
- Triggered by (user or webhook)
- Duration
- Logs (click to view)
Members Tab
Lists project-level members (separate from org members):
- User name and email
- Role (Admin, Developer, Viewer)
- Invited by
- Added date
- Actions (Change Role, Remove)
Add Project Member:
- Click Add Member
- Enter email address
- Select role (Admin / Developer / Viewer)
- User receives invitation email
Edit Project
Editable Fields
Basic Information
- Project Name: Update display name
- Description: Update or add description
- Note: Slug cannot be changed after creation (prevents breaking references)
Git Repository
- Repository URL: Change repository URL
- Git Provider: Auto-updated based on URL
- Behavior: Changing repository URL does not automatically re-register webhook
- Action Required: Manually update webhook in your Git provider settings
Custom Docker Image
- Image Source Type: Switch between Docker Hub, private registries, etc.
- Image Name/Tag: Update custom image reference
- Registry Credentials: Select different credentials
- Impact: Next deployment will use the new image
Project Settings
- JSON Object: Advanced settings (JSONB field)
- Use Cases: Store custom metadata, feature flags, integration keys
How to Edit
- Navigate to project detail page (
/projects/{project-id}) - Click Edit Project button (top-right, pencil icon)
- Update fields in the modal form
- Click Save Changes
Security Validation:
- Permission check:
org.projects.update - Organization membership verified
- Cross-organization protection (cannot edit projects from other orgs)
Audit Trail:
- All changes logged to audit table
- Includes: changed fields, old values, new values, user who made the change
- Visible in Settings → Audit Log
Regenerate Webhook Secret
If your webhook secret is compromised:
- Navigate to project detail page
- Click Settings tab
- Find Webhook Configuration section
- Click Regenerate Secret
- Copy new secret
- Update webhook configuration in GitHub/GitLab settings
Important: Old webhook deliveries will fail after regeneration.
Delete Project
Deletion Behavior
Soft Delete vs Hard Delete:
- OEC.SH uses hard delete for projects
- All related resources are permanently deleted (cascade)
- Cannot be undone - ensure backups are taken before deletion
Cascading Deletions: When you delete a project, the following are also deleted:
- All project environments (dev, staging, production)
- All deployments and deployment history
- All addon selections
- All project members
- All project domains
- Docker containers on remote servers (stopped and removed)
- PostgreSQL databases (dropped)
- Filestore data (deleted from servers)
Webhook Cleanup:
- If project has a registered webhook, it's automatically deleted from Git provider
- Requires valid OAuth token for the user performing deletion
- If deletion fails, webhook may remain (manual cleanup required)
Prerequisites
Before Deleting:
- Backup critical data: Create manual backups of production environments
- Export databases: Use Backups → Create Backup for each environment
- Download logs: Save deployment logs if needed for auditing
- Notify team: Inform project members about deletion
- Check dependencies: Ensure no external systems depend on webhook endpoints
How to Delete
UI Method (Recommended)
- Navigate to Dashboard → Projects
- Find the project to delete
- Click the three-dot menu (⋮) → Delete
- Type-to-confirm: Enter project name to confirm deletion
- Click Delete Project (red button)
Confirmation Required:
- You must type the exact project name (case-sensitive)
- This prevents accidental deletions
API Method
curl -X DELETE https://app.oec.sh/api/v1/projects/{project-id} \
-H "Authorization: Bearer YOUR_TOKEN_HERE"Safety Checks
Permission Validation:
- Requires
org.projects.deletepermission - Typically restricted to Org Owner and Org Admin
- Project Admins cannot delete projects (org-level action)
Pre-deletion Checks:
- Verifies user is member of the organization
- Confirms project exists and is not already deleted
- Validates permissions before any deletion occurs
Resource Cleanup Order:
- Deployments deleted
- Addon selections deleted
- Project members removed
- Environments deleted (triggers container/database cleanup on servers)
- Project record deleted
Post-Deletion
Immediate Effects:
- Project no longer appears in project list
- All environment URLs become inaccessible (404)
- Webhook deliveries from Git provider fail (404)
- Quota resources released (CPU, RAM, disk counts reduced)
Audit Trail:
- Deletion logged to audit table with:
- User who performed deletion
- Timestamp
- Project name and ID
- Whether webhook was cleaned up
- Audit record persists even after project deletion
API Reference
Create Project
Endpoint: POST /api/v1/projects
Permission: org.projects.create
Rate Limit: 10 requests/minute per organization
Request Body
{
"name": "ACME ERP System",
"slug": "acme-erp",
"description": "Main ERP system for ACME Corporation",
"odoo_version": "19.0",
"organization_id": "550e8400-e29b-41d4-a716-446655440000",
"repository_url": "https://github.com/acme/odoo-custom.git",
"repository_provider": "github",
"image_config": {
"source_type": "docker_hub",
"image_name": "odoo",
"image_tag": null,
"registry_url": null,
"registry_credentials_id": null,
"digest": null
}
}Request Schema
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | - | Project display name (1-255 chars) |
slug | string | No | Auto-generated | URL-friendly identifier (1-100 chars, lowercase, alphanumeric + hyphens) |
description | string | No | null | Project description |
odoo_version | enum | Yes | - | Odoo version: "14.0", "15.0", "16.0", "17.0", "18.0", "19.0" |
organization_id | uuid | No | Auto-detected | Organization to create project in |
repository_url | string | No | null | Git repository URL (HTTPS or SSH) |
repository_provider | enum | No | Auto-detected | Git provider: "github", "gitlab", "bitbucket" |
image_config | object | No | Default Odoo image | Custom Docker image configuration |
Response (201 Created)
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "ACME ERP System",
"slug": "acme-erp",
"description": "Main ERP system for ACME Corporation",
"odoo_version": "19.0",
"organization_id": "550e8400-e29b-41d4-a716-446655440000",
"organization_name": "ACME Corporation",
"vm_id": null,
"status": "pending",
"domain": null,
"repository_url": "https://github.com/acme/odoo-custom.git",
"repository_provider": "github",
"webhook_secret": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"webhook_id": "123456789",
"settings": {},
"created_at": "2025-12-11T10:30:00Z",
"updated_at": "2025-12-11T10:30:00Z"
}Error Responses
403 Forbidden - Quota Exceeded:
{
"detail": "Quota exceeded: Your organization has reached the maximum number of projects (10). Upgrade your plan to create more projects."
}409 Conflict - Slug Already Exists:
{
"detail": "Project with slug 'acme-erp' already exists in this organization"
}400 Bad Request - Invalid Odoo Version:
{
"detail": "Odoo version '20.0' is not available. Please select an active version."
}List Projects
Endpoint: GET /api/v1/projects
Permission: Implicit (returns only projects user has access to)
Rate Limit: 100 requests/minute per user
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
organization_id | uuid | No | All orgs | Filter by organization |
status | enum | No | All statuses | Filter by status (PENDING, ACTIVE, DEPLOYING, ERROR, STOPPED) |
skip | integer | No | 0 | Number of projects to skip (pagination) |
limit | integer | No | 100 | Maximum projects to return (max: 100) |
Example Request
curl -X GET "https://app.oec.sh/api/v1/projects?organization_id=550e8400-e29b-41d4-a716-446655440000&status=ACTIVE&limit=50" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"Response (200 OK)
[
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "ACME ERP System",
"slug": "acme-erp",
"description": "Main ERP system for ACME Corporation",
"odoo_version": "19.0",
"organization_id": "550e8400-e29b-41d4-a716-446655440000",
"organization_name": "ACME Corporation",
"vm_id": null,
"status": "active",
"domain": null,
"repository_url": "https://github.com/acme/odoo-custom.git",
"repository_provider": "github",
"webhook_secret": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"webhook_id": "123456789",
"settings": {},
"created_at": "2025-12-11T10:30:00Z",
"updated_at": "2025-12-11T15:45:00Z"
}
]Get Project Details
Endpoint: GET /api/v1/projects/{project_id}
Permission: project.view
Rate Limit: 100 requests/minute per user
Path Parameters
| Parameter | Type | Description |
|---|---|---|
project_id | uuid | Unique project identifier |
Example Request
curl -X GET "https://app.oec.sh/api/v1/projects/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"Response (200 OK)
Same schema as List Projects response (single object, not array).
Error Responses
404 Not Found:
{
"detail": "Project not found"
}403 Forbidden:
{
"detail": "You don't have permission to view this project."
}Update Project
Endpoint: PATCH /api/v1/projects/{project_id}
Permission: org.projects.update
Rate Limit: 30 requests/minute per project
Request Body (Partial Update)
{
"name": "ACME ERP System v2",
"description": "Updated description",
"repository_url": "https://github.com/acme/odoo-custom-v2.git",
"repository_provider": "github",
"settings": {
"feature_flags": {
"enable_advanced_routing": true
}
}
}Editable Fields
| Field | Type | Description |
|---|---|---|
name | string | Project display name |
description | string | Project description |
repository_url | string | Git repository URL |
repository_provider | enum | Git provider (auto-detected from URL) |
settings | object | Custom project settings (JSONB) |
image_config | object | Custom Docker image configuration |
Non-editable Fields:
slug(immutable after creation)odoo_version(contact support for version upgrades)organization_id(projects cannot be transferred)created_at,updated_at(system-managed)
Response (200 OK)
Returns updated project object (same schema as Get Project Details).
Error Responses
403 Forbidden - No Permission:
{
"detail": "You don't have permission to update this project."
}Delete Project
Endpoint: DELETE /api/v1/projects/{project_id}
Permission: org.projects.delete
Rate Limit: 10 requests/minute per organization
Example Request
curl -X DELETE "https://app.oec.sh/api/v1/projects/123e4567-e89b-12d3-a456-426614174000" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"Response (200 OK)
{
"message": "Project deleted successfully"
}Error Responses
404 Not Found:
{
"detail": "Project not found"
}403 Forbidden:
{
"detail": "You don't have permission to delete this project."
}Regenerate Webhook Secret
Endpoint: POST /api/v1/projects/{project_id}/regenerate-webhook-secret
Permission: org.projects.update
Rate Limit: 5 requests/minute per project
Example Request
curl -X POST "https://app.oec.sh/api/v1/projects/123e4567-e89b-12d3-a456-426614174000/regenerate-webhook-secret" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"Response (200 OK)
{
"webhook_secret": "b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a1",
"webhook_url": "/api/v1/webhooks/github",
"message": "Webhook secret regenerated. Update your repository webhook settings with the new secret."
}Action Required: Update webhook secret in your Git provider settings within 24 hours to avoid deployment failures.
Project Settings
Webhook Configuration
Each project has a unique webhook secret for securing Git push event deliveries.
Webhook URL
GitHub:
https://app.oec.sh/api/v1/webhooks/githubGitLab:
https://app.oec.sh/api/v1/webhooks/gitlabWebhook Setup (Manual)
If webhook wasn't auto-registered during project creation:
GitHub:
- Go to your repository → Settings → Webhooks
- Click Add webhook
- Payload URL:
https://app.oec.sh/api/v1/webhooks/github - Content type:
application/json - Secret: Copy webhook secret from OEC.SH project settings
- Events: Select "Just the push event"
- Active: Check this box
- Click Add webhook
GitLab:
- Go to your repository → Settings → Webhooks
- URL:
https://app.oec.sh/api/v1/webhooks/gitlab - Secret Token: Copy webhook secret from OEC.SH project settings
- Trigger: Check "Push events"
- Click Add webhook
Webhook Behavior
Trigger Conditions:
- Git push to any branch tracked by an environment
- Example: Push to
main→ triggers deployment for all environments withgit_branch = "main"
Deployment Flow:
- Developer pushes code to GitHub/GitLab
- Git provider sends webhook event to OEC.SH
- OEC.SH validates webhook signature using project's
webhook_secret - OEC.SH finds all environments with matching branch and
auto_deploy = true - Deployment jobs queued for matching environments
- Deployments execute in parallel (one per environment)
Security:
- Webhook secret is unique per project (not per environment)
- HMAC-SHA256 signature validation prevents spoofed webhook deliveries
- Failed signature validation returns 401 Unauthorized
Project Status Lifecycle
Project status is automatically calculated based on environment statuses.
Status Calculation Logic
Priority (highest to lowest):
DEPLOYING- If any environment is deployingRUNNING- If any environment is runningERROR- If any environment has error statusSTOPPED- If all environments are stoppedPENDING- If no active environments exist
Status Update Triggers:
- Environment deployment starts → project status becomes
DEPLOYING - Environment deployment completes → project status recalculated
- Environment stopped → project status recalculated
- Environment deleted → project status recalculated
Manual Status Update: Project status cannot be set manually. It's always derived from environment states.
Permissions Deep Dive
Organization-Level Permissions
org.projects.create:
- Who has it: Org Owner, Org Admin
- Allows: Creating new projects in the organization
- Quota enforcement: Checks billing plan project limits
org.projects.list:
- Who has it: All organization members
- Allows: Viewing list of projects in the organization
- Note: Does not grant access to individual project details
org.projects.update:
- Who has it: Org Owner, Org Admin, Project Admin
- Allows: Editing project settings (name, description, git repo, image config)
- Restrictions: Cannot change slug or transfer to another organization
org.projects.delete:
- Who has it: Org Owner, Org Admin
- Allows: Permanently deleting projects
- Note: Project Admins cannot delete projects (prevents accidental loss)
Project-Level Permissions
project.view:
- Who has it: All project members (Admin, Developer, Viewer)
- Allows: Viewing project details, environments, deployments
- Note: Read-only access to project configuration
Project Member Roles:
- Admin: Full project management (equivalent to
org.projects.update) - Developer: Can deploy, manage environments, view logs
- Viewer: Read-only access to project and environments
Quota Management
Project Limits by Plan
| Plan | Max Projects | Max Environments | CPU Quota | RAM Quota | Disk Quota |
|---|---|---|---|---|---|
| Free | 1 | 2 | 2 cores | 4 GB | 20 GB |
| Starter | 5 | 10 | 8 cores | 16 GB | 100 GB |
| Professional | 15 | 30 | 24 cores | 64 GB | 500 GB |
| Business | 50 | 100 | 64 cores | 256 GB | 2 TB |
| Enterprise | Unlimited | Unlimited | Custom | Custom | Custom |
Quota Enforcement
Project Creation:
- Checks current project count vs plan limit
- Blocks creation if limit reached
- Error message includes upgrade instructions
Environment Deployment:
- Checks CPU, RAM, and disk quota before deployment
- Only active environments (
is_active = true) count toward quota - Stopped or deleted environments release quota immediately
Quota Calculation:
Used Quota = SUM(cpu_cores) FROM project_environments WHERE is_active = TRUEBest Practices:
- Delete unused environments to free quota
- Use
is_active = falsefor temporary environments instead of deletion - Monitor quota usage in Settings → Usage
Troubleshooting
"Quota exceeded" Error When Creating Project
Symptom: Error message "Your organization has reached the maximum number of projects"
Causes:
- Billing plan project limit reached
- Active projects count equals plan limit
Solutions:
- Delete unused projects: Go to Dashboard → Projects → Delete old/test projects
- Upgrade billing plan: Settings → Billing → Select higher plan
- Archive projects: Contact support to archive projects without deletion
Check Current Usage:
curl -X GET "https://app.oec.sh/api/v1/organizations/{org-id}/quota" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"Webhook Not Triggering Deployments
Symptom: Git push doesn't trigger auto-deployment
Diagnosis Checklist:
- Environment auto-deploy enabled?
- Go to environment settings → Enable "Auto-deploy on push"
- Branch matches?
- Environment
git_branchmust match the pushed branch - Example: Environment has
git_branch = "main"→ only pushes tomaintrigger deployment
- Environment
- Webhook registered?
- Check project settings → Webhook ID should not be null
- Check Git provider webhook settings → Recent deliveries show 200 OK
- Webhook secret correct?
- If deliveries show 401 Unauthorized → secret mismatch
- Regenerate secret in OEC.SH → Update in Git provider settings
- Repository URL matches?
- Webhook only works if project's
repository_urlmatches the Git repo
- Webhook only works if project's
Manual Webhook Testing:
- Go to GitHub → Settings → Webhooks → Click your webhook
- Scroll to Recent Deliveries
- Click a delivery → Redeliver to test
Logs:
# Check webhook delivery logs (portal admin only)
curl -X GET "https://app.oec.sh/api/v1/admin/webhook-logs?project_id={project-id}" \
-H "Authorization: Bearer YOUR_TOKEN_HERE"Project Shows "ERROR" Status
Symptom: Project status badge shows red "ERROR"
Cause: One or more environments have status = "error"
Diagnosis:
- Go to project detail page → Environments tab
- Find environments with red error badge
- Click environment → View Deployment Logs
Common Environment Errors:
- Docker image pull failed (check image name/tag)
- Database restore failed (check backup file integrity)
- Server connection lost (check server status in Settings → Servers)
- Resource quota exceeded (check organization quota)
- Odoo configuration error (check
odoo.confsettings)
Resolution:
- Fix the underlying issue (see environment documentation)
- Redeploy the environment
- Project status auto-updates to
RUNNINGonce environment recovers
Cannot Delete Project
Symptom: Delete button greyed out or returns 403 Forbidden
Causes:
- Insufficient permissions: Requires
org.projects.delete(Org Owner or Org Admin) - User is Project Admin only: Project Admins cannot delete projects
- Cross-org attempt: User is not member of project's organization
Solutions:
- Request deletion from Org Owner/Admin
- Check organization membership: Settings → Organizations → Verify active membership
- Contact support: For projects in organizations where you're the last member
Webhook Secret Compromised
Symptom: Unauthorized webhook deliveries or security audit flag
Immediate Actions:
- Regenerate webhook secret:
- Project settings → Regenerate Webhook Secret
- Update Git provider:
- GitHub/GitLab → Webhooks → Update secret field
- Disable auto-deploy temporarily:
- Environment settings → Turn off "Auto-deploy on push"
- Review audit logs:
- Settings → Audit Log → Filter by webhook events
Prevention:
- Never commit webhook secrets to Git repositories
- Use environment variables for webhook URLs in CI/CD
- Rotate secrets quarterly (set calendar reminder)
Advanced Use Cases
Multi-Region Deployment
Deploy different environments to servers in different geographic regions:
Setup:
- Add servers in different regions (e.g., US, EU, APAC)
- Settings → Servers → Add server in each region
- Create project with multiple environments
- Assign each environment to region-specific server
- Production → EU server (GDPR compliance)
- Staging → US server (closer to dev team)
- Development → APAC server (closer to QA team)
Benefits:
- Compliance with data residency requirements
- Reduced latency for users in different regions
- Isolated testing without affecting production region
Custom Odoo Image Workflow
Build and deploy custom Odoo images with pre-installed modules:
Workflow:
-
Create custom Docker image:
FROM odoo:19.0 USER root RUN apt-get update && apt-get install -y python3-pip COPY ./custom-addons /mnt/extra-addons RUN pip3 install -r /mnt/extra-addons/requirements.txt USER odoo -
Build and push to registry:
docker build -t registry.gitlab.com/mycompany/odoo-custom:19.0 . docker push registry.gitlab.com/mycompany/odoo-custom:19.0 -
Configure in OEC.SH:
- Edit project → Advanced Settings → Custom Docker Image
- Source Type:
gitlab_registry - Image Name:
mycompany/odoo-custom - Image Tag:
19.0 - Registry URL:
registry.gitlab.com - Registry Credentials: Select your GitLab token
-
Deploy environment:
- OEC.SH pulls from your private registry
- Uses stored credentials for authentication
Git Branch Strategy
Implement GitFlow with multiple environments:
Branch Mapping:
main→ Production environment (auto_deploy = false, manual deployments only)develop→ Staging environment (auto_deploy = true)feature/*→ Development environment (auto_deploy = true)
Setup:
- Create project with Git repository
- Create 3 environments:
- Production:
git_branch = "main",auto_deploy = false,env_type = production - Staging:
git_branch = "develop",auto_deploy = true,env_type = staging - Development:
git_branch = "develop",auto_deploy = true,env_type = development
- Production:
Workflow:
- Developer pushes to
feature/new-module→ No auto-deploy (branch doesn't match) - PR merged to
develop→ Staging + Development auto-deploy - Release branch merged to
main→ Manual deployment to Production (requires approval)
Best Practices
Project Naming Conventions
Recommended Pattern: {customer}-{purpose}-{version}
Examples:
acme-erp-v1globalcorp-crm-proddemo-ecommerce-2024
Benefits:
- Easy identification in project list
- Alphabetical sorting groups related projects
- Version tracking in project name
Environment Organization
Standard Setup (3 environments):
- Development:
env_type = development,git_branch = "develop", small resources (1 CPU, 2GB RAM) - Staging:
env_type = staging,git_branch = "develop", medium resources (2 CPU, 4GB RAM) - Production:
env_type = production,git_branch = "main", large resources (4+ CPU, 8+ GB RAM)
Advanced Setup (5+ environments):
- Add QA environment for automated testing
- Add Demo environment for customer presentations
- Add Hotfix environment for emergency production fixes
Resource Allocation Strategy
Development Environments:
- CPU: 1-2 cores
- RAM: 2-4 GB
- Disk: 10-20 GB
- Purpose: Rapid iteration, low cost
Staging Environments:
- CPU: 2-4 cores (same as production)
- RAM: 4-8 GB (50-75% of production)
- Disk: 20-50 GB
- Purpose: Realistic performance testing
Production Environments:
- CPU: 4-16 cores (based on user count)
- RAM: 8-32 GB (Odoo is memory-intensive)
- Disk: 50-500 GB (based on data volume)
- Purpose: Optimal end-user experience
Scaling Formula (for production):
- Small: 10-50 users → 4 CPU, 8 GB RAM
- Medium: 50-200 users → 8 CPU, 16 GB RAM
- Large: 200-500 users → 16 CPU, 32 GB RAM
- Enterprise: 500+ users → 32+ CPU, 64+ GB RAM
Security Best Practices
-
Least Privilege Access:
- Use Project Member roles instead of making everyone Org Admin
- Grant "Viewer" role for read-only access (auditors, clients)
-
Webhook Security:
- Rotate webhook secrets every 90 days
- Use different secrets for different projects
- Monitor webhook delivery failures in Git provider
-
Git Repository:
- Use private repositories for custom modules
- Enable branch protection for
mainbranch - Require pull request reviews before merging
-
Audit Logging:
- Regularly review Settings → Audit Log
- Set up alerts for project deletions
- Export audit logs monthly for compliance
Related Documentation
- Create Environment - Deploy your first environment
- Deploy Environment - Understanding the deployment process
- Clone Environment - Duplicate environments with data
- Backup & Restore - Protect your data
- Servers Management - Configure infrastructure
- Permissions System - RBAC and access control
- Billing & Quota - Understand resource limits
Support
Need help with projects?
- Documentation: docs.oec.sh (opens in a new tab)
- Community Forum: community.oec.sh (opens in a new tab)
- Email Support: support@oec.sh
- Live Chat: Available in dashboard (bottom-right icon)
Found a bug?
- GitHub Issues: github.com/oecsh/platform/issues (opens in a new tab)
- Priority Support: Enterprise customers have dedicated Slack channel