at master 4.8 kB view raw
1{ 2 config, 3 pkgs, 4 lib, 5 ... 6}: 7let 8 cfg = config.services.odoo; 9 format = pkgs.formats.ini { }; 10in 11{ 12 options = { 13 services.odoo = { 14 enable = lib.mkEnableOption "odoo, an open source ERP and CRM system"; 15 16 package = lib.mkPackageOption pkgs "odoo" { }; 17 18 addons = lib.mkOption { 19 type = with lib.types; listOf package; 20 default = [ ]; 21 example = lib.literalExpression "[ pkgs.odoo_enterprise ]"; 22 description = "Odoo addons."; 23 }; 24 25 autoInit = lib.mkEnableOption "automatically initialize the DB"; 26 27 autoInitExtraFlags = lib.mkOption { 28 type = with lib.types; listOf str; 29 default = [ ]; 30 example = 31 lib.literalExpression # nix 32 '' 33 [ "--without-demo=all" ] 34 ''; 35 description = "Extra flags passed to odoo when run for the first time by autoInit"; 36 }; 37 38 settings = lib.mkOption { 39 type = format.type; 40 default = { }; 41 description = '' 42 Odoo configuration settings. For more details see <https://www.odoo.com/documentation/15.0/administration/install/deploy.html> 43 ''; 44 example = lib.literalExpression '' 45 options = { 46 db_user = "odoo"; 47 db_password="odoo"; 48 }; 49 ''; 50 }; 51 52 domain = lib.mkOption { 53 type = with lib.types; nullOr str; 54 description = "Domain to host Odoo with nginx"; 55 default = null; 56 }; 57 }; 58 }; 59 60 config = lib.mkIf (cfg.enable) ( 61 let 62 cfgFile = format.generate "odoo.cfg" cfg.settings; 63 in 64 { 65 services.nginx = lib.mkIf (cfg.domain != null) { 66 upstreams = { 67 odoo.servers = { 68 "127.0.0.1:8069" = { }; 69 }; 70 71 odoochat.servers = { 72 "127.0.0.1:8072" = { }; 73 }; 74 }; 75 76 virtualHosts."${cfg.domain}" = { 77 extraConfig = '' 78 proxy_read_timeout 720s; 79 proxy_connect_timeout 720s; 80 proxy_send_timeout 720s; 81 82 proxy_set_header X-Forwarded-Host $host; 83 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 84 proxy_set_header X-Forwarded-Proto $scheme; 85 proxy_set_header X-Real-IP $remote_addr; 86 ''; 87 88 locations = { 89 "/longpolling" = { 90 proxyPass = "http://odoochat"; 91 }; 92 93 "/" = { 94 proxyPass = "http://odoo"; 95 extraConfig = '' 96 proxy_redirect off; 97 ''; 98 }; 99 }; 100 }; 101 }; 102 103 services.odoo.settings.options = { 104 data_dir = "/var/lib/private/odoo/data"; 105 proxy_mode = cfg.domain != null; 106 } 107 // (lib.optionalAttrs (cfg.addons != [ ]) { 108 addons_path = lib.concatMapStringsSep "," lib.escapeShellArg cfg.addons; 109 }); 110 111 users.users.odoo = { 112 isSystemUser = true; 113 group = "odoo"; 114 }; 115 users.groups.odoo = { }; 116 117 systemd.services.odoo = { 118 wantedBy = [ "multi-user.target" ]; 119 after = [ 120 "network.target" 121 "postgresql.target" 122 ]; 123 124 # pg_dump 125 path = [ config.services.postgresql.package ]; 126 127 requires = [ "postgresql.target" ]; 128 129 serviceConfig = { 130 ExecStart = "${cfg.package}/bin/odoo"; 131 ExecStartPre = pkgs.writeShellScript "odoo-start-pre.sh" ( 132 '' 133 set -euo pipefail 134 135 cd "$STATE_DIRECTORY" 136 137 # Auto-migrate old deployments 138 if [[ -d .local/share/Odoo ]]; then 139 echo "pre-start: migrating state directory from $STATE_DIRECTORY/.local/share/Odoo to $STATE_DIRECTORY/data" 140 mv .local/share/Odoo ./data 141 rmdir .local/share 142 rmdir .local 143 fi 144 '' 145 + (lib.optionalString cfg.autoInit '' 146 echo "pre-start: auto-init" 147 INITIALIZED="${cfg.settings.options.data_dir}/.odoo.initialized" 148 if [ ! -e "$INITIALIZED" ]; then 149 ${cfg.package}/bin/odoo --init=INIT --database=odoo --db_user=odoo --stop-after-init ${lib.concatStringsSep " " cfg.autoInitExtraFlags} 150 touch "$INITIALIZED" 151 fi 152 '') 153 + "echo pre-start: OK" 154 ); 155 DynamicUser = true; 156 User = "odoo"; 157 StateDirectory = "odoo"; 158 Environment = [ 159 "ODOO_RC=${cfgFile}" 160 ]; 161 }; 162 }; 163 164 services.postgresql = { 165 enable = true; 166 167 ensureDatabases = [ "odoo" ]; 168 ensureUsers = [ 169 { 170 name = "odoo"; 171 ensureDBOwnership = true; 172 } 173 ]; 174 }; 175 } 176 ); 177}