Migrate from Another Odoo Host
Moving an existing Odoo database to Skysize comes down to three things: a clean backup of the old instance, a Skysize project that carries the same custom code, and a cut-over of your domain. This guide walks through the whole path and the checks that catch the most common import failures before they happen.
It applies to any source: another Odoo host, a server you manage yourself, or a local instance. Notes for specific hosts are at the end.
:::tip Migrating several databases? Each Odoo database becomes its own Skysize project. Go through this guide once per database, and rehearse with the smallest one first. :::
1. Take inventory of the old instance
Before exporting anything, write down:
- Odoo version and edition, for example 17.0 Enterprise. The import restores the database on the version it was made with. Upgrading to a newer Odoo version is a separate step, done after the migration.
- Custom and third-party modules: everything installed that is not part of standard Odoo, and where its source code lives. Open Apps, remove the Apps filter, and filter on Installed to list them. You will need the source in a Git repository.
- Python dependencies those modules require.
- Database and filestore size, to know whether the backup fits the browser upload limit on managed hosting (see Import an Existing Odoo Backup).
- Extra PostgreSQL users that connect directly to the database: BI tools such as Power BI or Metabase, replication users, reporting scripts, or a technical user created during an earlier migration. The import handles the traces they leave in the dump (see step 3). What you need to plan is a new way for them to reach the data after the move.
- Domain, outgoing email, and integrations: the domain users log in on, the SMTP server, external systems that call your Odoo (payment providers, webhooks, EDI), and systems Odoo calls that allow only known IP addresses.
2. Prepare the project on Skysize
- Push the custom modules to a Git repository with the module folders at the root. If they live in subfolders, see Organize Modules in Nested Directories. Add a
requirements.txtfor Python packages, see Install Python Packages. If the database has no custom code at all, create a project without a repository. - Create the project and set the Odoo version and edition to match the old instance. An Enterprise database needs an Enterprise branch.
- Let the first deployment finish. The empty database it creates is replaced by the import. What matters is that the build succeeds, which proves the modules and Python packages install correctly on the platform.
3. Export a clean backup
The import takes Odoo's native .zip backup: dump.sql, a filestore/ folder, and manifest.json. See Import an Existing Odoo Backup for the format and the size limit.
Where the backup comes from
-
Odoo's Database Manager (
/web/database/manager, then Backup in zip format) is the simplest source when it is enabled on the old host. -
Your host's own backup feature usually produces the same zip layout. Check the archive contains
dump.sqlat its root before uploading. -
A manual
pg_dumpwhen you have shell access to the old server. These flags keep the dump free of references to your old server's roles, although the import also tolerates dumps made without them:pg_dump --no-owner --no-privileges --format=p your_database > dump.sqlThen copy the filestore folder of that database (
<data_dir>/filestore/<database name>from the oldodoo.conf) next to it asfilestore/.
Ownership and privilege statements
A dump made without --no-owner or --no-privileges contains ALTER ... OWNER TO, GRANT, REVOKE and ALTER DEFAULT PRIVILEGES statements that name PostgreSQL roles from your old server, such as a Power BI reader or a technical user from an earlier migration. Odoo's Database Manager passes --no-owner but not --no-privileges, so its backups keep the GRANT lines whenever extra users had access to the database.
You do not need to clean these up. The import removes ownership and privilege statements on the fly while restoring, so a backup from any host imports as-is. After the import the database belongs to the branch's own role and no other role exists, so nothing is lost. The restore log shows how many lines were skipped.
4. Rehearse on a staging branch
Import the backup into a staging branch first, following Import an Existing Odoo Backup. A restore into a staging branch is neutralized automatically: outgoing mail servers and scheduled actions are disabled, so the rehearsal cannot send email or call live integrations.
Then check:
- Users can log in and the Apps list shows the same installed modules as the old instance.
- The runtime log has no missing module or module not found warnings, see View Logs.
- Attachments, product images and PDF reports open, which proves the filestore came through.
- Your custom workflows behave as before.
Fix any module or dependency problem in the repository now and redeploy. Repeat the import until the rehearsal is clean.
5. Cut over to production
- Lower the TTL of the DNS record for your domain a day ahead, so the switch propagates quickly.
- Announce a maintenance window. The old instance keeps serving until then.
- Stop writes on the old instance: stop the Odoo service, or block logins.
- Take a final backup as in step 3.
- Import it into the production branch. A production restore is not neutralized, the database comes back exactly as exported.
- Go through the post-import checks below.
- Point your domain at Skysize, see Add a Custom Domain.
- Keep the old instance stopped but intact for a few days before decommissioning it.
6. After the import
- Base URL: Odoo updates the
web.base.urlsystem parameter on the next administrator login, unlessweb.base.url.freezeis set. Check it under Settings → Technical → System Parameters, otherwise links in emails keep pointing at the old host. - Outgoing email: port 25 is blocked, use an encrypted SMTP relay on port 587 or 465, see Configure Outgoing Email (SMTP).
- IP allowlists: the address your Odoo connects from has changed. Update any bank, payment or API provider that filters on source IP.
- Inbound integrations: webhooks, payment provider return URLs, and the SSO or OAuth callback URLs must point at the new domain.
- Direct database access for BI tools: on managed hosting there is no direct PostgreSQL connection. Use Odoo's XML-RPC or JSON-RPC API, or a connector for your BI tool. On Bring Your Own Server projects, see Direct database access (read-only).
- Scheduled actions: on a production import they are active as soon as Odoo starts. Make sure nothing runs twice against an external system while the old instance is still up.
- Backups: automatic backups start on the first night. Check the Backups tab the next day, see Manage Backups.
Notes for specific sources
CloudPepper
CloudPepper runs Odoo on a server you own, so you can use Odoo's Database Manager or run pg_dump yourself as in step 3. Databases from these setups often have additional PostgreSQL users (a Power BI or reporting user, a technical user created for an earlier migration). Their backups contain GRANT statements for those users, which the import removes automatically, so the backup imports as-is. What those tools need is a new access path after the move, see step 6.
Odoo.sh
The Backups tab of your Odoo.sh project offers a download that includes the filestore. It is Odoo's native zip format, so it imports directly. Your custom code is already in the GitHub repository connected to Odoo.sh: connect the same repository to Skysize. If it uses submodules, see Include an External Repository (Submodules).
Odoo Online
Download a backup from the database manager on odoo.com (My databases, then Download). Odoo Online databases run the Enterprise edition without custom code, so a project without a repository with an Enterprise branch is all you need.
Self-managed server or local instance
Use the Database Manager if it is enabled, or pg_dump with the flags from step 3 plus the filestore folder from the data directory.