wip: use nixos-unstable

update frappe
update erpnext
refactor versions
main
teutat3s 2023-06-05 19:19:43 +02:00
parent 2bcd75eb09
commit cb9630c787
Signed by: teutat3s
GPG Key ID: 4FA1D3FA524F22C1
18 changed files with 346 additions and 314 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
result
*.qcow2

View File

@ -1,78 +1,23 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1682109806,
"narHash": "sha256-d9g7RKNShMLboTWwukM+RObDWWpHKaqTYXB48clBWXI=",
"lastModified": 1685655444,
"narHash": "sha256-6EujQNAeaUkWvpEZZcVF8qSfQrNVWFNNGbUJxv/A5a8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2362848adf8def2866fabbffc50462e929d7fffb",
"rev": "e635192892f5abbc2289eaac3a73cdb249abaefd",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1635350005,
"narHash": "sha256-tAMJnUwfaDEB2aa31jGcu7R7bzGELM9noc91L2PbVjg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1c1f5649bb9c1b0d98637c8c365228f57126f361",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-20.09",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"pip2nix": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_2"
},
"flake": false,
"locked": {
"lastModified": 1681921436,
"narHash": "sha256-jrUOMhpOFxrgCXNgMWz475nKZdMiSQb0+nbaIqQORSM=",
@ -89,9 +34,9 @@
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"pip2nix": "pip2nix"
"pip2nix": "pip2nix",
"systems": "systems"
}
},
"systems": {
@ -108,21 +53,6 @@
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View File

@ -1,23 +1,26 @@
{
description = "Dev Setup";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
inputs.systems.url = "github:nix-systems/default";
inputs.pip2nix = {
url = "github:nix-community/pip2nix";
flake = false;
};
outputs = {nixpkgs, flake-utils, pip2nix, ...}:
outputs = {nixpkgs, systems, pip2nix, ...}:
let
pkgs = system: import nixpkgs {
inherit system;
eachSystem = nixpkgs.lib.genAttrs (import systems);
pkgs = import nixpkgs {
system = "x86_64-linux";
overlays = [
(import ./python-overlay.nix)
(import ./overlay.nix)
];
};
packages = flake-utils.lib.eachDefaultSystem (system: rec {
in
{
packages = eachSystem (system: {
devEnv = pkgs.buildEnv {
name = "erpnext-nix-dev-env";
paths = [
@ -33,11 +36,10 @@
});
nixosConfigurations = {
test-vm = nixpkgs.lib.nixosSystem {
pkgs = pkgs "x86_64-linux";
inherit pkgs;
system = "x86_64-linux";
modules = [./test-vm/configuration.nix];
};
};
in {inherit packages nixosConfigurations;};
};
}

View File

@ -1,61 +0,0 @@
Babel 2.12.1
Click 8.1.3
filelock 3.8.0
filetype 1.2.0
GitPython 3.1.30
Jinja2 3.1.2
Pillow 9.3.0
PyJWT 2.4.0
PyPDF2 2.1.0
PyPika 0.48.9
PyQRCode 1.2.1
PyYAML 6.0
RestrictedPython 6.0
Werkzeug 2.2.2
Whoosh 2.7.4
beautifulsoup4 4.9.3
bleach-allowlist 1.0.3
bleach 3.3.0
chardet 4.0.0
croniter 1.3.5
cryptography 39.0.1
email-reply-parser 0.5.12
git-url-parse 1.2.2
gunicorn 20.1.0
html5lib 1.1
ipython 8.10.0
ldap3 2.9
markdown2 2.4.0
num2words 0.5.10
oauthlib 3.2.1
openpyxl 3.0.7
passlib 1.7.4
pdfkit 1.0.0
premailer 3.8.0
psutil 5.9.1
psycopg2-binary 2.9.1
pyOpenSSL 23.0.0
pycryptodome 3.10.1
pydantic 1.10.2
pyotp 2.6.0
python-dateutil 2.8.1
rauth 0.7.3
redis 4.5.4
hiredis 2.0.0
requests-oauthlib 1.3.0
requests 2.27.1
rq 1.11.1
semantic-version 2.10.0
sqlparse 0.4.1
tenacity 8.0.1
terminaltables 3.1.0
traceback-with-variables 2.0.4
xlrd 2.0.1
zxcvbn 4.4.28
markdownify 0.11.2
boto3 1.18.49
dropbox 11.7.0
google-api-python-client 2.2.0
google-auth-oauthlib 0.4.4
google-auth 1.29.0
posthog 3.0.1

View File

@ -7,7 +7,17 @@
, nodePackages
}:
let
src = import ../srcs/erpnext.nix {inherit fetchFromGitHub; };
pinData = import ../srcs/pin.nix;
inherit (pinData) erpnextVersion;
inherit (pinData.hashes) erpnextSrcHash;
src = fetchFromGitHub {
owner = "frappe";
repo = "erpnext";
rev = "v${erpnextVersion}";
hash = erpnextSrcHash;
};
offlineCache = fetchYarnDeps {
yarnLock = "${src}/yarn.lock";
sha256 = "sha256-Vho4BSbxcsVYExLvUaeoc3xIpbXoCUP/4jw4RwGnWGY=";

View File

@ -7,7 +7,17 @@
, nodePackages
}:
let
src = import ../srcs/frappe.nix {inherit fetchFromGitHub; };
pinData = import ../srcs/pin.nix;
inherit (pinData) frappeVersion;
inherit (pinData.hashes) frappeSrcHash;
src = fetchFromGitHub {
owner = "frappe";
repo = "frappe";
rev = "v${frappeVersion}";
hash = frappeSrcHash;
};
offlineCache = fetchYarnDeps {
yarnLock = "${src}/yarn.lock";
sha256 = "sha256-PBdMUz9gJIoQaqQYbdk+xnd8CyZPmdeyz/9WznCb4Ss=";

View File

@ -29,4 +29,6 @@ runCommand "frappe-erpnext-apps-sites" {buildInputs = [yarn]; } ''
mkdir -p $out/share/sites
cp -r sites/assets $out/share/sites/assets
ln -s ${frappe-app}/share/apps/frappe/node_modules $out/share/sites/assets/frappe/node_modules
ln -s ${erpnext-app}/share/apps/erpnext/node_modules $out/share/sites/assets/erpnext/node_modules
''

View File

@ -22,14 +22,14 @@ self: super: {
taxjar = pyself.callPackage ./python/taxjar.nix {};
traceback-with-variables = pyself.callPackage ./python/traceback-with-variables.nix {};
barcodenumber = pysuper.barcodenumber.overridePythonAttrs (oldAttrs: (rec {
version = "0.5.0";
src = pysuper.fetchPypi {
inherit version;
inherit (oldAttrs) pname;
sha256 = "sha256-VZfHLwSF9aDoy5L1x4O2mu8/f2ijYKgyjCrQ1KKY5Ho=";
};
}));
#barcodenumber = pysuper.barcodenumber.overridePythonAttrs (oldAttrs: (rec {
# version = "0.5.0";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-VZfHLwSF9aDoy5L1x4O2mu8/f2ijYKgyjCrQ1KKY5Ho=";
# };
#}));
bleach = pysuper.bleach.overridePythonAttrs (oldAttrs: (rec {
version = "3.3.1";
src = pysuper.fetchPypi {
@ -38,14 +38,14 @@ self: super: {
sha256 = "sha256-MGSDpal5VHQWCtV/zj3dG1BVHpge7Y4VpYLTTO8oqvo=";
};
}));
phonenumbers = pysuper.phonenumbers.overridePythonAttrs (oldAttrs: (rec {
version = "8.12.40";
src = pysuper.fetchPypi {
inherit version;
inherit (oldAttrs) pname;
sha256 = "sha256-APKVWkVrRY+barDSQykEnD5zWMRN/Bl5/kkIztQPHrg=";
};
}));
#phonenumbers = pysuper.phonenumbers.overridePythonAttrs (oldAttrs: (rec {
# version = "8.12.40";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-APKVWkVrRY+barDSQykEnD5zWMRN/Bl5/kkIztQPHrg=";
# };
#}));
plaid-python = pysuper.plaid-python.overridePythonAttrs (oldAttrs: (rec {
version = "7.2.1";
src = pysuper.fetchPypi {
@ -58,51 +58,51 @@ self: super: {
# Integration tests require API keys and internet access
checkPhase = "py.test -rxs ./tests/unit";
}));
pycountry = pysuper.pycountry.overridePythonAttrs (oldAttrs: (rec {
version = "20.7.3";
src = pysuper.fetchPypi {
inherit version;
inherit (oldAttrs) pname;
sha256 = "sha256-gQhKU9NFQ0TAKS3uvCD80KFIjBNtSQAxLL1GXPVSy0I=";
};
}));
pymysql = pysuper.pymysql.overridePythonAttrs (oldAttrs: (rec {
version = "1.0.3";
src = pysuper.fetchPypi {
inherit version;
inherit (oldAttrs) pname;
sha256 = "sha256-PdqUPvNpQGinXWnQcXVdvsrO4a35ofxbIGgw0rZ9Jeg=";
};
format = "pyproject";
buildInputs = [pysuper.setuptools];
}));
pypng = pysuper.pypng.overridePythonAttrs (oldAttrs: (rec {
version = "0.20220715.0";
src = pysuper.fetchPypi {
inherit version;
inherit (oldAttrs) pname;
sha256 = "sha256-c5xDO6lvB4MV3lTA25da7lN8vD4dCuTtmqsMoeQn4sE=";
};
}));
pytz = pysuper.pytz.overridePythonAttrs (oldAttrs: (rec {
version = "2022.1";
src = pysuper.fetchPypi {
inherit version;
inherit (oldAttrs) pname;
sha256 = "sha256-HnYOL+aoFjvAs9mhnE+ENCr6Cir/6/qoSwG5eKAuyqc=";
};
}));
redis = pysuper.redis.overridePythonAttrs (oldAttrs: (rec {
version = "3.5.3";
src = pysuper.fetchPypi {
inherit version;
inherit (oldAttrs) pname;
sha256 = "sha256-Dn4M/KhmDeqLfVzYxPbF4p4R8xFYwLCukaOX8A5aBaI=";
};
pythonImportsCheck = [];
# tests require a running redis
doCheck = false;
}));
#pycountry = pysuper.pycountry.overridePythonAttrs (oldAttrs: (rec {
# version = "20.7.3";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-gQhKU9NFQ0TAKS3uvCD80KFIjBNtSQAxLL1GXPVSy0I=";
# };
#}));
#pymysql = pysuper.pymysql.overridePythonAttrs (oldAttrs: (rec {
# version = "1.0.3";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-PdqUPvNpQGinXWnQcXVdvsrO4a35ofxbIGgw0rZ9Jeg=";
# };
# format = "pyproject";
# buildInputs = [pysuper.setuptools];
#}));
#pypng = pysuper.pypng.overridePythonAttrs (oldAttrs: (rec {
# version = "0.20220715.0";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-c5xDO6lvB4MV3lTA25da7lN8vD4dCuTtmqsMoeQn4sE=";
# };
#}));
#pytz = pysuper.pytz.overridePythonAttrs (oldAttrs: (rec {
# version = "2022.1";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-HnYOL+aoFjvAs9mhnE+ENCr6Cir/6/qoSwG5eKAuyqc=";
# };
#}));
#redis = pysuper.redis.overridePythonAttrs (oldAttrs: (rec {
# version = "3.5.3";
# src = pysuper.fetchPypi {
# inherit version;
# inherit (oldAttrs) pname;
# sha256 = "sha256-Dn4M/KhmDeqLfVzYxPbF4p4R8xFYwLCukaOX8A5aBaI=";
# };
# pythonImportsCheck = [];
# # tests require a running redis
# doCheck = false;
#}));
tweepy = pysuper.tweepy.overridePythonAttrs (oldAttrs: (rec {
version = "3.10.0";
src = pysuper.fetchPypi {
@ -113,14 +113,14 @@ self: super: {
doCheck = false;
pythonImportsCheck = [];
}));
unidecode = pysuper.unidecode.overridePythonAttrs (oldAttrs: (rec {
version = "1.2.0";
src = pysuper.fetchPypi {
inherit version;
pname = "Unidecode";
sha256 = "sha256-jXOpfTh6lWkiNE9rdCQ8LGdxWUZZd4dEstvarY9rcn0=";
};
}));
#unidecode = pysuper.unidecode.overridePythonAttrs (oldAttrs: (rec {
# version = "1.2.0";
# src = pysuper.fetchPypi {
# inherit version;
# pname = "Unidecode";
# sha256 = "sha256-jXOpfTh6lWkiNE9rdCQ8LGdxWUZZd4dEstvarY9rcn0=";
# };
#}));
};
};
}

View File

@ -15,16 +15,31 @@
, setuptools
, tomli
}:
let
pinData = import ../srcs/pin.nix;
inherit (pinData) benchVersion;
inherit (pinData.hashes) benchSrcHash;
in
buildPythonPackage rec {
pname = "frappe-bench";
version = "5.16.2";
src = fetchFromGitHub {
owner = "frappe";
repo = "bench";
rev = "v${benchVersion}";
hash = benchSrcHash;
};
format = "pyproject";
src = import ../srcs/bench.nix {inherit fetchFromGitHub; };
nativeBuildInputs = [ pythonRelaxDepsHook ];
pythonRelaxDeps = [ "jinja2" "python-crontab" "semantic-version" ];
buildInputs = [
hatchling
];
propagatedBuildInputs = [
click
gitpython

View File

@ -1,5 +1,6 @@
{ lib
, buildPythonPackage
, pythonRelaxDepsHook
, fetchFromGitHub
, taxjar
@ -13,12 +14,32 @@
, googlemaps
, python-stdnum
, frappe
, bench
}:
let
pinData = import ../srcs/pin.nix;
inherit (pinData) erpnextVersion;
inherit (pinData.hashes) erpnextSrcHash;
in
buildPythonPackage rec {
pname = "erpnext";
version = "14.24.3";
version = erpnextVersion;
src = fetchFromGitHub {
owner = "frappe";
repo = pname;
rev = "v${erpnextVersion}";
hash = erpnextSrcHash;
};
format = "flit";
src = import ../srcs/erpnext.nix {inherit fetchFromGitHub; };
nativeBuildInputs = [ pythonRelaxDepsHook ];
pythonRelaxDeps = [
"pycountry"
"Unidecode"
];
propagatedBuildInputs = [
taxjar
gocardless-pro
@ -32,4 +53,10 @@ buildPythonPackage rec {
python-stdnum
frappe
];
#nativeCheckInputs = [
# bench
#];
#checkPhase = ''
# bench --site test_site run-tests --app erpnext
#'';
}

View File

@ -1,6 +1,6 @@
{ lib
, buildPythonPackage
, fetchPypi
, pythonRelaxDepsHook
, fetchFromGitHub
# core dependencies
@ -47,8 +47,9 @@
, psutil
, psycopg2-binary
, pyasn1
, pyopenssl
, pycountry
, pycryptodome
, pyopenssl
, pyotp
, pypng
, python-dateutil
@ -69,8 +70,9 @@
, xlrd
, zxcvbn
, markdownify
, bench
# integration dependencie
# integration dependencies
, boto3
, dropbox
, google-api-python-client
@ -79,11 +81,56 @@
, google-auth
, posthog
}:
let
pinData = import ../srcs/pin.nix;
inherit (pinData) frappeVersion;
inherit (pinData.hashes) frappeSrcHash;
in
buildPythonPackage rec {
pname = "frappe";
version = "14.36.1";
version = frappeVersion;
src = fetchFromGitHub {
owner = pname;
repo = pname;
rev = "v${frappeVersion}";
hash = frappeSrcHash;
};
format = "flit";
src = import ../srcs/frappe.nix { inherit fetchFromGitHub; } ;
nativeBuildInputs = [ pythonRelaxDepsHook ];
pythonRelaxDeps = [
"Babel"
"beautifulsoup4"
"boto3"
"cairocffi"
"Click"
"cryptography"
"filelock"
"google-api-python-client"
"google-auth"
"hiredis"
"ipython"
"openpyxl"
"phonenumbers"
"Pillow"
"premailer"
"pyasn1"
"pycountry"
"pycryptodome"
"PyJWT"
"PyMySQL"
"pyOpenSSL"
"pyotp"
"pypng"
"pytz"
"redis"
"rq"
"tenacity"
"WeasyPrint"
];
propagatedBuildInputs = [
babel
click
@ -128,8 +175,9 @@ buildPythonPackage rec {
psutil
psycopg2-binary
pyasn1
pyopenssl
pycountry
pycryptodome
pyopenssl
pyotp
pypng
python-dateutil
@ -160,4 +208,17 @@ buildPythonPackage rec {
google-auth
posthog
];
#nativeCheckInputs = [
# bench
# redis
#];
#checkPhase = ''
# tmp=$(mktemp -d)
# cd $tmp
# bench -v init frappe-bench --skip-assets
# cd frappe-bench
# mkdir -p sites/test_site
# bench --site test_site run-tests --app frappe
#'';
}

View File

@ -1,9 +1,10 @@
{
buildPythonPackage,
fetchPypi,
redis,
rejson,
hiredis
{ buildPythonPackage
, fetchPypi
, pythonRelaxDepsHook
, unittestCheckHook
, redis
, rejson
, hiredis
}:
buildPythonPackage rec {
pname = "redisearch";
@ -12,9 +13,16 @@ buildPythonPackage rec {
inherit pname version;
sha256 = "sha256-V1rNWhOhB/8AXUVyoTa1A7Evpb8mr8N70R9qkj8exzw=";
};
nativeBuildInputs = [ pythonRelaxDepsHook ];
pythonRelaxDeps = [
"redis"
];
propagatedBuildInputs = [
redis
rejson
hiredis
];
nativeCheckInputs = [
unittestCheckHook
];
}

View File

@ -1,8 +1,9 @@
{
buildPythonPackage,
fetchPypi,
redis,
six
{ buildPythonPackage
, pythonRelaxDepsHook
, unittestCheckHook
, fetchPypi
, redis
, six
}:
buildPythonPackage rec {
pname = "rejson";
@ -11,8 +12,13 @@ buildPythonPackage rec {
inherit pname version;
sha256 = "sha256-vs3hNSAAUAi3ls5WyxKOsiUC18addIJv81HNQ79zvJc=";
};
nativeBuildInputs = [ pythonRelaxDepsHook ];
pythonRelaxDeps = [
"redis"
];
propagatedBuildInputs = [
redis
six
];
doCheck = false;
}

View File

@ -1,7 +0,0 @@
{fetchFromGitHub}:
fetchFromGitHub {
owner = "frappe";
repo = "bench";
rev = "v5.16.2";
sha256 = "sha256-SF/RwY54OKXTDIYz4LsQIR03QoCKPIGey60DO8TdonY=";
}

View File

@ -1,7 +0,0 @@
{fetchFromGitHub}:
fetchFromGitHub {
owner = "frappe";
repo = "erpnext";
rev = "v14.24.3";
sha256 = "sha256-zovdbpTp9fTpY7kAs4J8EiPh+EjqUOtVUk+rDYMfYDk=";
}

View File

@ -1,8 +0,0 @@
{fetchFromGitHub}:
fetchFromGitHub {
owner = "akshaymankar";
repo = "frappe";
rev = "d4d3cbc12d3e40f104500866a2bf468d128e2e32";
sha256 = "sha256-+z/IeK3bFGYxnvWCR6GTgik25lSReJvRCbV7MsoUA/g=";
}

10
srcs/pin.nix Normal file
View File

@ -0,0 +1,10 @@
{
frappeVersion = "14.37.0";
erpnextVersion = "14.26.0";
benchVersion = "5.16.2";
hashes = {
"benchSrcHash" = "sha256-SF/RwY54OKXTDIYz4LsQIR03QoCKPIGey60DO8TdonY=";
"erpnextSrcHash" = "sha256-hPOgHADkrylc6OCbDyXCQfSYe5wliIhNcXpLE0hxmJ0=";
"frappeSrcHash" = "sha256-f0BkNByKtqXaG6L4+llwy9kmI8gbjvZdKzkzrbA6PI4=";
};
}

View File

@ -64,69 +64,102 @@ with lib;
group = "erpnext";
isSystemUser = true;
};
#users = {
# users.${user} = {
# uid = 327;
# group = group;
# home = server.workDir;
# };
# groups.${group}.gid = 327;
#};
systemd.services.erpnext =
let
name = "worker1";
user = "erpnext";
group = "erpnext";
server = {
bind = "127.0.0.1:9090";
workDir = "/var/lib/erpnext";
};
in {
enable = true;
wantedBy = [ "multi-user.target" ];
after = [ "mysql.service" "redis.service" "redis-socketio.service" ];
description = "ERPNext";
environment =
let
penv = python3.buildEnv.override {
penv = pkgs.python3.buildEnv.override {
extraLibs = [
python3.pkgs.frappe
python3.pkgs.erpnext
python3.pkgs.bench
pkgs.python3.pkgs.frappe
pkgs.python3.pkgs.erpnext
pkgs.python3.pkgs.bench
];
};
in
{
enable = true;
wantedBy = [ "multi-user.target" ];
after = [ "mysql.service" "redis.service" "redis-socketio.service" ];
description = "ERPNext";
confinement = {
enable = true;
packages = [ ];
};
script = ''
export PYTHON_PATH=${penv}/${python3.sitePackages}
in {
PYTHONPATH = "${penv}/${pkgs.python3.sitePackages}/";
};
cat > /frappe-bench/sites/apps.txt <<EOF
frappe
erpnext
EOF
#confinement = {
# enable = true;
# packages = [ ];
#};
serviceConfig = {
#User = "erpnext";
#NoNewPrivileges = true;
Type = "simple";
BindReadOnlyPaths = [
"${pkgs.frappe-app}/share/apps/frappe:/frappe-bench/apps/frappe"
"${pkgs.erpnext-app}/share/apps/erpnext:/frappe-bench/apps/erpnext"
"${pkgs.frappe-erpnext-assets}/share/sites/assets:/frappe-bench/sites/assets"
# "${penv}:/frappe-bench/env"
];
ExecStartPre = pkgs.writeScript "erpnext-server.${name}-init" ''
#!/bin/sh
mkdir -p ${server.workDir}/sites
chown ${user}:${group} ${server.workDir}
cat >/frape-bench/sites/common_site_config.json <<EOF
{
"db_host": "localhost",
"db_port": 3306,
"db_name": "erpnext" ,
"db_password": "erpnext" ,
"redis_cache": "redis://localhost:6379?db=0",
"redis_queue": "redis://localhost:6379?db=1",
"redis_socketio": "redis://localhost:6379?db=2",
"socketio_port": 3000
}
EOF
cat > ${server.workDir}/sites/apps.txt <<EOF
frappe
erpnext
EOF
# Upstream initializes the DB with this command
# TODO: Make this idempotent
cd /frappe-bench/sites
bench new-site localhost --mariadb-root-password password --admin-password admin
bench --site localhost install-app erpnext
cat > ${server.workDir}/sites/common_site_config.json <<EOF
{
"db_host": "localhost",
"db_port": 3306,
"db_name": "erpnext" ,
"db_password": "erpnext" ,
"redis_cache": "redis://localhost:6379?db=0",
"redis_queue": "redis://localhost:6379?db=1",
"redis_socketio": "redis://localhost:6379?db=2",
"socketio_port": 12311
}
EOF
cd "${server.workDir}/sites"
# Upstream initializes the DB with this command
bench new-site localhost --mariadb-root-password password --admin-password admin
bench --site localhost install-app erpnext
node $tmp/apps/frappe/socketio.js &
'';
ExecStart = ''
${pkgs.python3Packages.gunicorn}/bin/gunicorn frappe.app:application --name ${name} \
--chdir="${server.workDir}/sites" \
--user ${user} \
--group ${group} \
--bind=${server.bind} \
--pid ${server.workDir}/gunicorn-${name}.pid \
--threads=4 \
--workers=2 \
--worker-class=gthread \
--worker-tmp-dir=/dev/shm \
--timeout=120 \
--preload
'';
};
};
echo "Workdir: $tmp"
# TODO: Run these as systemd units
node $tmp/apps/frappe/socketio.js &
gunicorn --chdir="$tmp/sites" --bind=0.0.0.0:9090 --threads=4 --workers=2 --worker-class=gthread --worker-tmp-dir=/dev/shm --timeout=120 --preload frappe.app:application
'';
serviceConfig = {
User = "erpnext";
NoNewPrivileges = true;
Type = "simple";
BindReadOnlyPaths = [
"${frappe-app}/share/apps/frappe:/frappe-bench/apps/frappe"
"${erpnext-app}/share/apps/erpnext:/frappe-bench/apps/erpnext"
"${frappe-erpnext-assets}/share/sites/assets:/frappe-bench/sites/assets"
# "${penv}:/frappe-bench/env"
];
};
};
system.stateVersion = "23.11";
};
}