Skip to content

History

Omisen edited this page Aug 14, 2026 · 5 revisions

Historical note. Bash is mentioned here only — as the past, not as a usage guide.

The installer was originally written in Bash (installer.sh plus lib/*.sh modules, with a check_install.sh verification suite). Those versions are archived at the tags:

The Bash version was idempotent (run it again and carry on) but not reversible (undo and clean up): if a step failed, it could leave the system in an intermediate state.

The current version is a complete rewrite in Rust, born to add what Bash lacked: transactional rollback — either the installation succeeds, or the system goes back to exactly what it was. The compiler guarantees that no error branch is ignored; every step has snapshot/run/undo, and the rollback is proven by end-to-end tests.

The Bash files are no longer in the repository: they were removed when Rust became the source of truth. They remain recoverable from the git history and the tags above.

From 2.1.0 to 2.2.0

2.2.0 came out of a cold audit of the whole tree. There was a single theme: the promise “either it succeeds, or the system goes back to what it was” was not being kept in several places — and none of them showed up as an error.

The three things a user notices:

  • Ctrl-C rolls back instead of killing the process. Before, the installation was left half-done.
  • An interrupted installation resumes, without losing track of what it had already created. And a completed one is no longer overwritten: the uninstall manifest was the only thing making an instance removable, and a second sudo invok destroyed it silently.
  • /opt/odoo really disappears after a rollback. Before it always stayed: the lock and the log lived inside it and kept it occupied, so the undo meant to remove it could never fire.

Hence the three path moves (manifest to /var/lib, lock to /run, log to /var/log) and the renaming of --enable-ssl to --open-https-port — a flag that promised TLS without providing it. The legacy name and its .env key keep working.

If you are upgrading: the log has moved, and re-running the installer on an already-installed instance now fails on purpose (use rollback or --force). Instances installed with 2.1.0 remain uninstallable-by-command: the historical manifest path is still read.

From 2.2.0 to 2.3.0: the third family

Until then the installer spoke one language only. Fedora support was not added with an if next to every command, but by extracting two boundaries — “which commands install a package, and what is it called here” and “where do the files live, which concepts exist, who governs the firewall” — so that the steps stopped knowing which distribution they run on.

Three things that only showed up by actually running it, and that are worth more than the list of translated package names:

  • on Fedora the PostgreSQL cluster does not exist until you create it, so “install the package” is not enough: initialising is a mutation with an artifact of its own, and as such it has to be recorded and undoable;
  • SELinux denies the proxy to Odoo with a valid nginx -t and a successful reload: the symptom is a 502 and nothing in the configuration explains it;
  • from Fedora 43 the system python3 is newer than Odoo's pins, and no build flag works around a wheel that does not exist. Hence the rule that the installer chooses the interpreter instead of taking whatever is there, installing one the pins cover and removing it on rollback.

The full account: Multi-distribution support.

If you are upgrading from 2.2.0: no flag changes and no existing installation needs redoing. On Ubuntu and Debian the behaviour is identical; the difference only shows on Fedora, where the installer used to stop and now goes all the way through.

From 2.3.0 to 3.0.0: the name, and how you get the command

The project used to be called odoo-installer. From 3.0.0 it is called Invok, with the short alias vok — a /usr/bin/vok → /usr/bin/invok symlink created by the packages, not a second program.

The rule that decided every single occurrence, and that is worth knowing because it explains what changed and what did not: “Odoo” leaves the identifiers and stays in descriptive use. Out of the name of the crate, the binary, the packages and the bookkeeping paths (/var/lib/invok/state.json, /var/log/invok.log, /run/invok.lock). In, unchanged, all the artifacts that are Odoo's: /opt/odoo, the odoo user and database, odoo.conf, odoo18.service, the odoo helper command. A trademark is defended on identity, not on mention: taking “Odoo” out of the prose would cost discoverability without reducing exposure.

If you are upgrading from a 2.x: your instances stay uninstallable-by-command. The manifest of an installation made with 2.4.0 lives in /var/lib/odoo-installer/state.json, and that path is still read — together with the even older /opt/odoo/.installer-state.json. Dropping it would not leave “an instance to remove by hand”: it would leave an instance nobody can uninstall without guessing the names of its artifacts.

How you get the installer

Up to 2.3.0 there was one route: clone and compile. From 3.0.0 there are four wrappers, and three of them need no Rust.tar.gz (static musl, any distro), .deb, .rpm, each with its own sha256, plus cargo install invok for those who already have the toolchain.

Updates come from the Releases page, where every version stays with its checksums: you update by downloading again. There is no apt/dnf repository to add to the machine's sources.


Looking for how to use the current version: Home, Quick start, The rollback model.

Clone this wiki locally