Skip to content

Deployment Workflows

Development Environment

sequenceDiagram
    participant DEV as Developer
    participant OF as Odoofly CLI
    participant FS as Filesystem
    participant DC as Docker Compose
    participant O as Odoo Container
    participant P as PostgreSQL

    DEV->>OF: of project new --name app
    OF->>FS: Create project.yml + directory scaffold
    OF-->>DEV: Project created

    DEV->>OF: of env init main
    OF->>FS: Read project.yml
    OF->>FS: Scan addons/ for requirements.txt
    OF->>FS: Generate Dockerfile
    OF->>DC: docker compose build
    DC-->>OF: Image built
    OF-->>DEV: Environment initialized

    DEV->>OF: of env up main
    OF->>DC: docker compose up -d
    DC->>O: Start Odoo container (port 8069)
    DC->>P: Start PostgreSQL container
    O->>P: Connect to database
    OF-->>DEV: Environment running
    DEV->>OF: of env url main
    OF-->>DEV: http://localhost:{port}

Staging Environment (from Production)

sequenceDiagram
    participant DEV as Developer
    participant OF as Odoofly CLI
    participant FS as Filesystem
    participant DC as Docker Compose
    participant O as Odoo Container
    participant P as PostgreSQL

    DEV->>OF: of env new --staging --name staging_v2
    OF->>FS: Copy main/ volume references
    OF->>FS: Neutralize sensitive data
    OF->>FS: Generate unique port + env name
    OF->>DC: docker compose up (staging config)
    DC->>O: Start staging Odoo
    DC->>P: Start staging PostgreSQL
    Note over O,P: Uses cloned volumes from main with scrubbed emails & disabled crons
    OF-->>DEV: Staging ready
    DEV->>OF: of env url staging_v2
    OF-->>DEV: http://localhost:{unique_port}

Git Branching + Staging Workflow

# 1. Create a feature branch from main
git checkout main && git pull
git checkout -b feat_my_module
# ... make changes under addons/ ...
git add -A && git commit -m "feat: my module"
git push origin feat_my_module

# 2. Create a staging environment (clones main's data, anonymizes it)
of env new --staging --name feat_my_module

# 3. Start and work with the staging environment
of env up feat_my_module
of env url feat_my_module

# 4. When done: tear down
of env rm feat_my_module --yes
git branch -D feat_my_module

Keeping Staging Data Fresh

# Re-sync all databases from main to staging
of env staging refresh feat_my_module

# From a different source environment
of env staging refresh feat_my_module --from production

# Refresh and restart automatically
of env staging refresh feat_my_module --restart

Production Environment

flowchart LR
    USER["User"] <-->|HTTPS :443| T["Traefik\n(Let's Encrypt)"]
    T <-->|HTTP :80 to 443 redirect| W["Internet"]

    subgraph "Docker Network: traefik"
        T
        O1["Odoo Client A :8069"]
        O2["Odoo Client B :8069"]
    end

    T -->|Host: clientA.com| O1
    T -->|Host: clientB.com| O2
    O1 -->|traefik.enable=true| T
    O2 -->|traefik.enable=true| T
# Deploy the global reverse proxy
of proxy traefik --email admin@agency.com --yes
of proxy up

# Each production project auto-registers with Traefik
of project new --name clientA --production --domain clientA.com --websecure --yes
of env init main --up

Cloudflare Integration

websecure Traefik Cloudflare SSL/TLS
true Manages Let's Encrypt Full or Full (Strict)
false Direct HTTP Flexible