Wolfgang Walther 41c5662cbe
nixos/postgresql: move postStart into separate unit
This avoids restarting the postgresql server, when only ensureDatabases
or ensureUsers have been changed. It will also allow to properly wait
for recovery to finish later.

To wait for "postgresql is ready" in other services, we now provide a
postgresql.target.

Resolves #400018

Co-authored-by: Marcel <me@m4rc3l.de>
2025-06-24 15:26:47 +02:00

179 lines
4.7 KiB
Nix

{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.odoo;
format = pkgs.formats.ini { };
in
{
options = {
services.odoo = {
enable = lib.mkEnableOption "odoo, an open source ERP and CRM system";
package = lib.mkPackageOption pkgs "odoo" { };
addons = lib.mkOption {
type = with lib.types; listOf package;
default = [ ];
example = lib.literalExpression "[ pkgs.odoo_enterprise ]";
description = "Odoo addons.";
};
autoInit = lib.mkEnableOption "automatically initialize the DB";
autoInitExtraFlags = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
example =
lib.literalExpression # nix
''
[ "--without-demo=all" ]
'';
description = "Extra flags passed to odoo when run for the first time by autoInit";
};
settings = lib.mkOption {
type = format.type;
default = { };
description = ''
Odoo configuration settings. For more details see <https://www.odoo.com/documentation/15.0/administration/install/deploy.html>
'';
example = lib.literalExpression ''
options = {
db_user = "odoo";
db_password="odoo";
};
'';
};
domain = lib.mkOption {
type = with lib.types; nullOr str;
description = "Domain to host Odoo with nginx";
default = null;
};
};
};
config = lib.mkIf (cfg.enable) (
let
cfgFile = format.generate "odoo.cfg" cfg.settings;
in
{
services.nginx = lib.mkIf (cfg.domain != null) {
upstreams = {
odoo.servers = {
"127.0.0.1:8069" = { };
};
odoochat.servers = {
"127.0.0.1:8072" = { };
};
};
virtualHosts."${cfg.domain}" = {
extraConfig = ''
proxy_read_timeout 720s;
proxy_connect_timeout 720s;
proxy_send_timeout 720s;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
'';
locations = {
"/longpolling" = {
proxyPass = "http://odoochat";
};
"/" = {
proxyPass = "http://odoo";
extraConfig = ''
proxy_redirect off;
'';
};
};
};
};
services.odoo.settings.options =
{
data_dir = "/var/lib/private/odoo/data";
proxy_mode = cfg.domain != null;
}
// (lib.optionalAttrs (cfg.addons != [ ]) {
addons_path = lib.concatMapStringsSep "," lib.escapeShellArg cfg.addons;
});
users.users.odoo = {
isSystemUser = true;
group = "odoo";
};
users.groups.odoo = { };
systemd.services.odoo = {
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"postgresql.target"
];
# pg_dump
path = [ config.services.postgresql.package ];
requires = [ "postgresql.target" ];
serviceConfig = {
ExecStart = "${cfg.package}/bin/odoo";
ExecStartPre = pkgs.writeShellScript "odoo-start-pre.sh" (
''
set -euo pipefail
cd "$STATE_DIRECTORY"
# Auto-migrate old deployments
if [[ -d .local/share/Odoo ]]; then
echo "pre-start: migrating state directory from $STATE_DIRECTORY/.local/share/Odoo to $STATE_DIRECTORY/data"
mv .local/share/Odoo ./data
rmdir .local/share
rmdir .local
fi
''
+ (lib.optionalString cfg.autoInit ''
echo "pre-start: auto-init"
INITIALIZED="${cfg.settings.options.data_dir}/.odoo.initialized"
if [ ! -e "$INITIALIZED" ]; then
${cfg.package}/bin/odoo --init=INIT --database=odoo --db_user=odoo --stop-after-init ${lib.concatStringsSep " " cfg.autoInitExtraFlags}
touch "$INITIALIZED"
fi
'')
+ "echo pre-start: OK"
);
DynamicUser = true;
User = "odoo";
StateDirectory = "odoo";
Environment = [
"ODOO_RC=${cfgFile}"
];
};
};
services.postgresql = {
enable = true;
ensureDatabases = [ "odoo" ];
ensureUsers = [
{
name = "odoo";
ensureDBOwnership = true;
}
];
};
}
);
}