Documentation / Running Odoo
Managing Services
Start, stop, restart, and manage your Odoo services.
Once a service is created, you can manage its lifecycle directly from the calmo.cloud dashboard.
Starting and stopping #
Start a service #
If a service is stopped, open the Service menu at the top of the service page and click Start. The container will boot up and Odoo will become accessible at its URL.
Stop a service #
Open Service and click Stop to shut down a running service. This stops the container but preserves all data — the database, files, and configuration remain intact. You can start it again at any time.
Restart a service #
Open Service and click Restart to stop and immediately start the service. This is useful when:
- You've installed or updated an addon
- Odoo seems unresponsive
- You've changed configuration that requires a restart
A restart keeps the service's container, and with it the image the container was created from. A newly pulled image goes live with the next redeploy or start instead (see Updating the base image).
Stopping a service does not delete any data. Your database and files are safely preserved.
Deleting a service #
To permanently remove a service:
- Open the service you want to delete
- Open the ⋮ menu at the end of the page header and click Delete Odoo
- Confirm the deletion
Deleting a service permanently removes the container, database, and all associated files. Make sure you have a backup before deleting. This action cannot be undone.
Neutralizing a service #
The Neutralize action strips sensitive data from a service. This is useful when you want to create a safe demo or test copy of a production instance — it anonymizes data so real customer information isn't exposed.
Updating the base image #
Each Odoo service is built on a base image. Pulling the latest base image picks up security patches and Odoo updates without changing your service's configuration. calmo.cloud rebuilds the base images every evening (UTC) from the current Odoo and Odoo Enterprise sources, so a pull brings in what Odoo released up to that evening.
Image pull strategy #
The Image pull strategy setting on the service controls how the base image is kept up to date:
| Strategy | Behavior |
|---|---|
| Manual | The image is only pulled when you trigger it yourself (default) |
| Daily | The latest base image is pulled and the service image rebuilt every day |
| Weekly | The latest base image is pulled and the service image rebuilt every week |
| Monthly | The latest base image is pulled and the service image rebuilt every month |
| Quarterly | The latest base image is pulled and the service image rebuilt every three months |
Automatic pulls only run for running services and are checked once per day, at midnight UTC, a few hours after the evening's build. Every build counts as a newer image, so with Daily the service page asks for Upgrade all modules after nearly every pull (see After a newer image).
Pulling manually #
You can trigger a pull at any time, regardless of the strategy, unless the service is pinned to a daily image:
- On the service page, open Service and click Pull Image
- In the services list, open the row actions menu and click Pull Image
- To pull for several services at once, select them in the services list and use the Queue: Pull Image bulk action
Pulling only downloads the latest base image and rebuilds the service image; there is no downtime when pulling. The running container keeps using the old image until it is recreated: for example by a Redeploy, a Start, a restore, an addon update, or when you install or upgrade modules. A Restart keeps the container it has, and with it the old image.
Every pull is recorded in the service's Actions tab and timeline, and the Last image pull column in the services list shows when each service last pulled its image.
Which Odoo commit runs #
The Odoo source section of the service page shows the Odoo and Odoo Enterprise commits your Odoo runs, and when each was committed. The Odoo commit links to it on GitHub; the Odoo Enterprise repository is private, so its commit has no link. The services list has the same commits as the Odoo commit and Odoo Enterprise commit columns, hidden until you turn them on.
calmo.cloud reads the commits from the container every time it is brought up, and once a day. They change once a newer image has gone live, not when it was pulled. Until the container of a service has been read, the section shows Not known yet.
Switching to another daily image #
Every evening's image is kept, and a service offers those of the last 60 days, each with the day it was built and the Odoo and Odoo Enterprise commits it was built from. Only images built since calmo.cloud records their commits are offered: older ones were built for an earlier version of the platform. Pick one under the Odoo image setting on the service to pin the service to it, for example to go back to the previous day's Odoo while a fix lands.
The switch takes effect with the next redeploy: after saving, the page shows the Redeploy required notice, and View changes lists the Odoo image. The redeploy pulls the chosen image while the service still runs, then puts it live. With the Automatic redeploy strategy this happens on its own. If the image can be neither pulled nor found on the server, the redeploy stops before it takes the service down, and the service keeps running on the image it has; automatic redeploys try that image again an hour later, or right away once you choose another one.
A pinned service stays on its image: automatic pulls leave it out, and Pull Image refuses it. To go back, clear the Odoo image setting with the × next to the chosen image, so that it shows Latest image, and save. The next redeploy then pulls the latest image, and the image pull strategy applies again.
Like a pull onto a newer image, a switch can make the service page ask for Upgrade all modules (see After a newer image). Going back to an older image runs older Odoo code on a database the newer code may already have upgraded. Within one Odoo version that is usually fine; if pages or reports fail afterwards, run Upgrade all modules.
Copies, previews and agent copies made from a pinned service are pinned to the same image.
After a newer image #
When a pull rebuilt the service on a newer Odoo base image, the timeline notes that a newer Odoo image was built, and the service page shows Modules need an upgrade, as does the Modules tab. The new image brings new Odoo code, but your database is still the one its modules were last upgraded for. Once the container is recreated, Odoo runs the new code on it, and wherever that code expects changes to the database, pages or reports can fail until the modules catch up.
Click Upgrade all modules in that notice, or on the Modules tab. Odoo upgrades every installed module, so the database matches the new code, and the new image goes live at the same time. The service is stopped while Odoo works, which can take many minutes on a large database, and a live service is backed up first. See Upgrading all modules.
calmo.cloud never upgrades the modules on its own, also not after an automatic pull: the upgrade takes the service offline, so you choose when it happens. A pull that found no newer base image adds no notice, even when it rebuilt the Python packages your addons need.
The notice only covers pulls since calmo.cloud started tracking newer images. An image built before that, a copy, and a database restored onto a newer image don't show it, so a missing notice doesn't prove that the database matches the code. If pages or reports fail with an error such as column … does not exist after the image changed or after a restore, run Upgrade all modules anyway.
Through the API and AI assistants #
The REST API pulls the image with POST /api/service-odoo/{uuid}/pull-image, and an AI assistant can do the same. The service then reports modules_upgrade_due, which is true while the modules should catch up with a newer image, and odoo_commit_sha, odoo_commit_date, enterprise_commit_sha and enterprise_commit_date name the commits it runs (null while not known). Like the notice, false only covers the pulls calmo.cloud tracked; upgrading all modules is a module operation. Pulling needs the API token permission Start, stop and redeploy Odoo services. On an Odoo another team shares with yours, pulling needs the Operator role.
GET /api/service-odoo/{uuid}/odoo-images lists the daily images a service can switch to, with the Odoo and Odoo Enterprise commits of each. The service reports the image it is pinned to as odoo_image_tag, for example 19.0-20261023, or null for the latest image. Send a tag from that list as odoo_image_tag with PATCH /api/service-odoo/{uuid} to pin the service, or null to switch it back; a running service is redeployed right away. An AI assistant can do the same. Switching needs the API token permission Manage Odoo services.
Tuning performance #
The Performance section decides how much of its server an Odoo may use. It holds the settings people reach for most often:
| Setting | What it does |
|---|---|
| Workers | HTTP worker processes. Zero keeps Odoo in threaded mode, which suits small systems. |
| Cron threads | Processes reserved for scheduled actions. |
| Memory limit (soft) | A worker over this limit finishes its request and is then recycled. |
| Memory limit (hard) | A worker over this limit is killed at once. Sized for one heavy request rather than as a multiple of the soft limit: splitting a server between many workers makes each share small, and a share too small kills a large export or a grouped report outright. |
| CPU time limit | Processor time one request may spend. |
| Real time limit | Wall-clock time one request may take. Long imports and reports need room here. |
| Requests per worker | Requests a worker serves before it is recycled. |
| Database connections | Connections one Odoo process may open. |
How much a service is offered depends on what kind of service it is. A live system is sized for everything the server has left; a test or demo for around a third of it, and a copy, preview or agent copy for a fifth. A test copy sized like production takes the room production needs, on a server that exists for production — so the first service created no longer decides how much is left for the rest. It is a ceiling on the recommendation only: you can still set any value by hand. New copies, previews and agent copies of coding agents start with small settings of their own in threaded mode; test and demo copies start with the recommendation for their server.
On a server with monitoring enabled, Use recommended values fills the whole section from the hardware the server reports: one worker per half core plus one, two cron threads, and the memory that is actually left for this service — after the operating system's share, after what PostgreSQL reserves and after the other services on the same server have taken theirs. On a small server you may be offered fewer workers than the cores allow, because a worker with too little memory is recycled mid-request. The Database connections value is a slice of the connection limit the server's PostgreSQL accepts.
The block at the top of the section shows that split, so you can see what is left before you raise anything. Database Performance covers the other half of it: how the server's PostgreSQL is sized, and what happens when more is promised than the machine has. Treat the recommendation as a starting point and watch the server metrics afterwards.
These are ordinary Odoo settings and end up in the same configuration file as everything below, so they can also be set through the API as part of extra_config.
Changing them needs a redeploy, and more workers means more memory. Check the server's memory chart before raising them.
The section warns you, and opens by itself, when its settings would stop Odoo from working: a value that is not a whole number, or a job queue that may run as many jobs at once as Odoo has workers, which leaves no worker for the people using Odoo. Warnings never block saving. The API returns the same warnings as config_warnings.
Configuring Odoo settings #
The Extra Configuration section allows you to add custom Odoo configuration settings directly to your service. These settings are injected into the Odoo configuration file (.odoorc) when the service starts.
The Odoo configuration file is split into sections, and the Extra Configuration section shows one block per section:
- Odoo options — the settings Odoo reads for itself, such as
workersorlimit_time_real. This is the[options]section of the file. - Job queue — the settings the
queue_jobmodule reads, written to the[queue_job]section. - Other section — any other section a module expects, named by you.
Adding configuration #
- Open the service you want to configure
- Expand the Extra Configuration section (collapsed by default)
- Click Add section and pick the block you need
- Fill in the settings
- Save the changes
- Redeploy the service for the new settings to take effect: open Service and click Redeploy Service. With the Automatic redeploy strategy this happens on its own.
Common settings #
The settings under Performance have their own fields; the ones below are typed in as rows.
| Setting | Description | Example |
|---|---|---|
server_wide_modules |
Modules loaded for every database | base,web,queue_job |
db_maxconn |
Database connections per process | 64 |
Changes to configuration settings take effect on the next redeploy, not on a restart: a restart keeps the configuration the service was deployed with. After saving, the page shows a Redeploy required notice until you redeploy.
Avoid newline characters in configuration values — they are not supported and will cause validation errors.
Running the job queue #
Odoo's queue_job module runs long tasks in the background. It needs three things:
- The module has to be available — add the repository that provides it under Addons — and installed in the database.
- In Odoo options, list it in
server_wide_modules, for examplebase,web,queue_job. Under Performance, set Workers to at least2: the job runner needs a worker of its own, and with a single worker it would take the only one. - In the Job queue block, set Channels to the number of jobs that may run at the same time, for example
root:2, and set Host tolocalhost. Keep the channels below the number of workers. Half the workers is a good start. Use recommended values under Performance lowers the channels when the new worker count could not carry them.
root:0 switches the job runner off without removing the configuration.
The Job queue block shows a Queued jobs cannot run warning when something is missing: queue_job is not listed in server_wide_modules, the module is not in the synced module list, or it is not installed in the database. Install it from the Modules tab.
Configuring settings over the API #
The API writes the same settings as one map, where a key carries the section it belongs to:
{
"extra_config": {
"workers": "4",
"server_wide_modules": "base,web,queue_job",
"queue_job.channels": "root:2",
"queue_job.host": "localhost"
}
}
A key without a prefix belongs to the [options] section. Sending extra_config replaces the whole map, and a running service is redeployed when the settings change.
Viewing logs #
You can follow the Odoo logs live and read back through older ones directly from the service page. This is useful for debugging issues, monitoring startup behavior, or watching request activity.
How to view logs #
- Open a running service
- Click the View Logs button in the header
- A slide-over panel opens with the latest 100 lines and keeps streaming new ones
Logs are streamed live for up to 5 minutes per session. You can close the panel and reopen it at any time to start a new session.
Reading the logs #
- Log activity charts the loaded lines over time, coloured by level. Click a bar to show only the lines from that moment.
- The Error, Warning, Info and Debug buttons filter the lines by level. Errors are red and warnings yellow.
- Find in logs searches the loaded lines and highlights the matches.
- Wrap lines breaks long lines, such as tracebacks, instead of scrolling sideways.
- Scroll up to load older lines, 1,000 at a time, back to the oldest entries the server still keeps.
- Copy or download the visible lines, or switch to fullscreen.
The viewer remembers your colour, filter and follow settings in your browser.
The View Logs button is only available when the service is running. People from a team the service is shared with need at least the Viewer role.
Log history #
Log history is in early access and is being rolled out team by team. If you don't see a Log history tab in your server's settings, it isn't enabled for your team yet. Get in touch and we'll switch it on.
The server keeps only a limited amount of logs. With log history, the logs of every Odoo on a server are also sent to calmo.cloud's log storage, so older logs stay readable after the server has rotated them away. Open the server's settings, select the Log history tab and switch on Keep log history. You can switch it off again at any time. Provisioning templates have the same switch, so new servers keep their log history from the start.
The log viewer of each Odoo on that server then gets a time-range picker next to Live: the last hour, 24 hours, 3, 7 or 30 days, or a Custom range. The activity chart then covers the whole range, and you can drag across its bars to zoom in. Back to live returns to the stream.
How long logs are kept depends on the plan of the team that hosts the Odoo:
| Free | Starter | Pro | Agency |
|---|---|---|---|
| 1 day | 3 days | 7 days | 30 days |
Logs of a deleted Odoo are deleted with it.
Web terminal #
The Terminal tab of a running service opens a terminal in your browser. Choose what to open:
| Session | What it is |
|---|---|
| Shell | Bash inside the Odoo container, with psql and odoo shell at hand |
| Database (psql) | psql, connected to the service's database as its own user |
| Odoo shell | Python with an env for the service's database |
Each session opens in its own tab, and New session opens another one, up to five at a time. On startup, each session shows the service, its Odoo version and its database.
In the shell:
odoo shellneeds no extra options. It starts without a web server and without cron workers, so it does not compete with the running Odoo.calmo-storageshows the size of the database, the filestore and the data directory, the five largest tables and how much disk space is left.- Files outside
/home/odoo/dataare reset when the service is redeployed.
In the Odoo shell, changes are rolled back unless you call env.cr.commit(). Leave it with Ctrl+D. Characters typed with Option on a Mac or AltGr elsewhere, such as \, | or @ on a German keyboard, reach the terminal as typed.
A session closes after 10 minutes without input and after one hour at most. Click Reconnect to start it again. People from a team the service is shared with need the Developer role to open the terminal.
Viewing actions #
Every operation performed on a service is logged in the Actions tab. Each action shows:
- The operation that was performed
- Whether it succeeded or failed
- When it ran
- Detailed output (for troubleshooting)
This gives you a complete audit trail of everything that has happened to a service.
Webhooks #
Each service has a unique webhook token that allows external systems to send notifications to calmo.cloud. This is used for:
- Syncing the list of installed modules
- Tracking module upgrades
- Integration with CI/CD pipelines