In 2025, Agile Minds migrated its Odoo instance from Odoo Online (SaaS) to a self-hosted VPS at OVHcloud. This Odoo migration VPS experience report details the reasons for this migration, the architecture implemented, the problems encountered, and the complete step-by-step procedure. Whether you are considering an Odoo self-hosted guide for your own company or simply evaluating the feasibility of such a move, this article covers every aspect of the process based on real-world production experience. We wrote this guide because, when we started planning our own transition, we found very few comprehensive resources that walked through the entire process from start to finish with honest lessons learned. Our goal is to give you the roadmap we wish we had.
Why leave Odoo Online?
Odoo Online is an excellent solution for getting started quickly. But as your business grows and your needs become more complex, its limitations become apparent. For many SMEs, the tipping point comes when custom integrations, advanced automation, or third-party modules become critical to daily operations. At Agile Minds, we reached that point when we needed tight integration between Odoo and our n8n automation platform, as well as the ability to deploy AI-powered agents that interact directly with the ERP via JSON-RPC API calls. None of this was feasible within the constraints of the managed SaaS environment.
- Limited Control: no SSH access, no fine-grained server management, no custom cron jobs. This means you cannot tune PostgreSQL settings, adjust Odoo worker configurations, or run maintenance scripts on your own schedule. For a growing IT consultancy that relies on automation, this was a dealbreaker.
- Increasing Cost: the price per user quickly accumulates with growth. With Odoo Online, each additional user adds a fixed monthly fee, and as your team scales from 3 to 10 to 20 users, the cumulative cost can easily surpass the total cost of a self-hosted VPS including maintenance overhead.
- Custom Modules Impossible: Odoo Online does not accept uncertified third-party modules. If your business process requires a niche module from the Odoo App Store or a custom-developed module built specifically for your workflow, you simply cannot install it on Odoo Online. This is one of the most frequently cited reasons to migrate Odoo Online to a self-hosted environment.
- Restricted API Access: limitations on API calls and webhooks. Odoo Online imposes rate limits and restricts certain XML-RPC and JSON-RPC operations, which makes it difficult to build real-time integrations or event-driven automation workflows.
- Performance: shared server, no control over resources. Because Odoo Online runs on shared infrastructure, response times can vary depending on the load from other tenants. During peak hours, we occasionally experienced latency spikes that disrupted our daily operations.
- Data Sovereignty: data hosted outside your direct control. For European SMEs subject to GDPR, knowing exactly where your data resides and who can access it is not just a preference but a regulatory consideration. Self-hosting on a European VPS provider like OVHcloud ensures full GDPR compliance with data residency in the EU.
The Target Architecture
Here is the technical stack implemented at Agile Minds. Every component was chosen with a clear rationale, balancing stability, performance, and long-term maintainability. When planning your own Odoo self-hosted guide, the architecture decisions you make at this stage will define the reliability and scalability of your deployment for years to come. We recommend spending adequate time on this phase rather than rushing into installation.
| Component | Technical Choice | Justification |
|---|---|---|
| Host | OVHcloud VPS (Gravelines, France) | Proximity, GDPR, quality/price ratio |
| OS | Debian 12 (Bookworm) | Stability, LTS, large community |
| Database | PostgreSQL 18 | Recommended by Odoo, performance |
| Reverse proxy | Traefik v3 | Automatic SSL, dynamic routing |
| SSL | Let’s Encrypt (via Traefik) | Free, automatic renewal |
| Python | Python 3.12 (venv) | Dependency isolation |
| Backup | pg_dump + OVHcloud snapshots | Double security |
| Monitoring | Uptime Kuma | Real-time alerts |
A few notes on architecture decisions: we chose Traefik v3 over Nginx because of its native support for automatic Let’s Encrypt certificate provisioning and dynamic routing configuration. This eliminates the need for manual SSL renewal and simplifies adding new services behind the reverse proxy. For PostgreSQL, version 18 offers improved query planning and parallel query execution, which directly benefits Odoo’s heavier reporting operations. The combination of pg_dump for logical backups and OVHcloud snapshots for full-disk recovery gives us a two-tier backup strategy that covers both granular database restoration and complete disaster recovery scenarios.
Migration Procedure in 4 Phases
Phase 1: Server Preparation (Day 1-2)
The foundation of a successful Odoo migration VPS project starts with a properly secured and configured server. Do not underestimate this phase. Cutting corners here will create problems that are much harder to fix once Odoo is running in production with live data.
- Order an OVHcloud VPS (8 vCPU, 22 GB RAM, SSD NVMe). For most SMEs running Odoo with up to 20 concurrent users, this specification provides comfortable headroom. The NVMe storage is critical for database performance, as PostgreSQL benefits enormously from low-latency disk I/O.
- Install Debian 12 and secure the server (SSH keys, fail2ban, firewall). Disable password-based SSH authentication immediately. Configure UFW to allow only ports 22, 80, and 443. Install and configure fail2ban to automatically ban IPs after repeated failed login attempts.
- Install PostgreSQL 18 and configure access. Create a dedicated database user for Odoo with minimal required privileges. Configure
pg_hba.confto allow local socket connections only, preventing remote access to the database port. - Install Python dependencies (wkhtmltopdf, required libs). This is where many migrations hit their first snag. The wkhtmltopdf version available in standard Debian repositories is not the patched Qt version that Odoo requires for proper PDF generation. Always install the patched version directly from the official GitHub releases.
- Configure Traefik v3 with Let’s Encrypt. Set up the ACME challenge resolver and configure the entrypoints for HTTP and HTTPS with automatic redirect.
Phase 2: Odoo Installation (Day 3)
With the server prepared, the Odoo installation itself is relatively straightforward if you follow the official documentation. The key is to use a Python virtual environment to isolate Odoo’s dependencies from the system Python packages, preventing version conflicts that can cause subtle and hard-to-debug issues.
- Clone the Odoo 19 Enterprise repository from GitHub. Ensure you have valid Enterprise credentials configured in your Git authentication. The Enterprise repository includes all standard modules plus the Enterprise-only features.
- Create a dedicated Python virtual environment. Use
python3.12 -m venvto create an isolated environment. This is essential for reproducibility and makes future Odoo version upgrades significantly cleaner. - Install Python dependencies (
pip install -r requirements.txt). Watch for any compilation errors during this step, as they typically indicate missing system libraries (libxml2-dev, libxslt1-dev, libldap2-dev, libsasl2-dev are common requirements). - Configure the
odoo.conffile (ports, DB, workers, paths). This configuration file is the heart of your Odoo deployment. Pay special attention to thedb_host,db_port,db_user,db_password,addons_path, anddata_dirparameters. - Create the systemd service for Odoo. A properly configured systemd unit ensures Odoo starts automatically on boot, restarts on crash, and logs output to the system journal for easy debugging.
- Test startup on port 8069. Before configuring the reverse proxy, verify that Odoo starts correctly and you can access the web interface directly on port 8069. Check the logs for any warnings or errors during module loading.
Phase 3: Data Migration (Day 4-5)
This is the most critical phase of the entire Odoo migration VPS process. Your production data, including accounting records, customer contacts, inventory, and all transaction history, must be transferred intact. Plan for at least one full test migration before the actual go-live migration to identify any issues in advance.
- Export the database from Odoo Online (Database Manager menu). Navigate to the database manager at
/web/database/managerand create a full backup including the filestore. The resulting ZIP file contains both the PostgreSQL dump and all uploaded attachments. - Transfer the dump to the VPS via SCP. Use a secure transfer method. For large databases, consider compressing the dump further or using rsync with progress reporting to monitor the transfer.
- Restore the database in local PostgreSQL. Use
pg_restoreorpsqldepending on the dump format. Ensure the target database is created with the correct encoding (UTF-8) and owner. This step can take anywhere from a few minutes to several hours depending on the size of your database. - Verify data integrity (accounting, contacts, inventory). This is non-negotiable. Run through your critical business flows manually: check that accounting balances match, customer records are complete, product catalogs are intact, and historical orders display correctly.
- Update system parameters (URL, outgoing email, etc.). After restoring, the database still references the old Odoo Online URL. Update the
web.base.urlsystem parameter to reflect your new domain. Reconfigure outgoing mail servers with your SMTP credentials. - Install necessary custom modules. This is the moment of truth that justifies the entire migration. Install the custom and third-party modules that were impossible to deploy on Odoo Online, then test each one thoroughly.
Phase 4: Go-Live (Day 6)
The go-live day should be anticlimactic if you have done thorough preparation in the previous phases. Schedule it for a low-activity period, such as a weekend or holiday, to minimize disruption to your team. Communicate the migration timeline to all users in advance so they know to expect a brief period of unavailability.
- Configure DNS (odoo.agile-minds.be to VPS). Update the A record to point to your VPS IP address. Keep the TTL low (300 seconds) before the migration so DNS propagation happens quickly. Once everything is confirmed working, increase the TTL back to a standard value.
- Activate SSL via Traefik. With Traefik and Let’s Encrypt properly configured, SSL activation should be automatic once DNS points to the server. Verify that HTTPS works correctly and that HTTP-to-HTTPS redirect is functioning.
- Configure Odoo workers for performance. Set the number of workers based on your CPU count (a common formula is
workers = 2 * CPU + 1). Configurelimit_memory_hard,limit_memory_soft, andlimit_time_realto prevent runaway processes from consuming all server resources. - Set up automatic backups (cron pg_dump). Configure a daily cron job that creates a compressed PostgreSQL dump and rotates backups to keep the last 14 days. Store at least one weekly backup off-site for disaster recovery.
- Test all business flows. Run through a comprehensive checklist: create a sales order, confirm it, generate an invoice, process a payment, create a purchase order, receive goods, run key reports. Test the portal access for external users as well.
- Switch users. Notify your team that the new environment is live. Provide the new URL and ensure everyone can log in with their existing credentials. Monitor closely during the first 48 hours for any issues that only surface under normal usage patterns.
Problems Encountered and Solutions
No migration is without its challenges. Below are the most significant issues we encountered during our Odoo migration VPS project, along with the solutions we implemented. We share these openly because these are the kinds of problems that cost hours of debugging when you encounter them unprepared, and minutes to fix when you know what to look for.
| Problem | Cause | Solution |
|---|---|---|
| wkhtmltopdf error (empty PDFs) | Incompatible version in Debian repositories | Install patched version 0.12.6.1 from GitHub. The standard Debian package lacks the Qt patches that Odoo requires for proper PDF rendering. This is by far the most common issue reported in Odoo migration forums. |
| Extreme slowness at startup | workers = 0 (single-thread mode) | Configure workers = 4 and max_cron_threads = 2. Running Odoo with zero workers means all requests are handled in a single thread, which quickly becomes a bottleneck with even two concurrent users. |
| Broken CSS on the portal | Assets not regenerated after migration | Delete compiled assets and restart with -u base. After restoring a database from a different environment, Odoo’s static assets (CSS, JavaScript bundles) reference old paths. Running an update on the base module forces regeneration. |
| Outgoing emails blocked | Port 25 blocked by OVHcloud | Use port 587 with STARTTLS (Google Workspace). Most cloud providers block port 25 to prevent spam. Using the submission port 587 with proper TLS encryption is the standard solution and works with any modern mail provider. |
| Traefik timeout on large reports | Default timeout too short | Increase respondingTimeouts to 300s in Traefik. Some Odoo reports (especially large accounting exports or inventory valuations) can take over 60 seconds to generate. Without adjusting the reverse proxy timeout, users see a gateway error while the report is still processing. |
Before / After: The Comparison
After running our self-hosted Odoo instance for over a year in production, here is a concrete comparison between the two environments. These numbers reflect our actual experience with a team of 5 active users and approximately 15 custom or third-party modules installed on the self-hosted instance.
| Aspect | Odoo Online | Self-hosted VPS |
|---|---|---|
| Monthly Cost (5 users) | ~250 EUR/month | ~35 EUR/month (VPS) |
| Custom Modules | Impossible | Unlimited |
| Server Access | None | Full Root |
| Performance | Variable (shared) | Constant (dedicated) |
| API / Webhooks | Limited | Unlimited |
| Backups | Daily (Odoo manages) | Customizable (our control) |
| Average Response Time | ~800 ms | ~200 ms |
| Maintenance | Zero (Odoo manages) | Our responsibility |
The cost savings alone are significant: over 2,500 EUR per year for our configuration. But the real value lies in the freedom and control. Being able to install custom modules, run unrestricted API integrations, and tune the server for our specific workload has transformed how we use Odoo. The performance improvement, with average response times dropping from 800ms to 200ms, is immediately noticeable in daily use and has a positive impact on team productivity.
Our Verdict After 1 Year
The migration was Agile Minds’ best technical investment. The performance gain, the freedom to install custom modules (especially for n8n integration and AI agents), and the cost reduction largely justify the initial 6 days of effort. If you are considering whether to migrate Odoo Online to a self-hosted environment, the answer depends on your specific situation, but for any SME that needs custom modules, advanced API access, or tighter control over their infrastructure, the benefits are clear and measurable.
The ongoing maintenance overhead is real but manageable. Plan for approximately 2-4 hours per month for system updates, security patches, and Odoo minor version upgrades. Automating backups and monitoring (which we strongly recommend) reduces this further. The key is having someone on the team, or a trusted partner, with Linux system administration skills.
Tip: If you are an SME with fewer than 3 users and standard needs, stick with Odoo Online. Beyond that, a self-hosted migration is seriously worth considering. The break-even point in terms of cost alone is typically around 4-5 users, and the qualitative benefits in terms of flexibility and performance tip the scales even earlier for technically demanding use cases.
Patrick Impens · CEO Agile Minds SRL · agile-minds.be
Odoo maintenance and post-migration support.
Our Odoo support for your migration project.
Also read
Let's talk about your project
Book a meeting →