wip: cleanup, more docs

main
teutat3s 2023-06-12 15:28:17 +02:00
parent af3c949181
commit 232d6d3f41
Signed by: teutat3s
GPG Key ID: 4FA1D3FA524F22C1
10 changed files with 171 additions and 176 deletions

1
.envrc Normal file
View File

@ -0,0 +1 @@
use flake

1
.gitignore vendored
View File

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

View File

@ -1,10 +1,46 @@
# Erpnext on NixOS
### Cachix
Using the https://pub-solar.cachix.org binary cache:
```
cachix use pub-solar
```
Or manually add the following lines to your `~/.config/nix/nix.conf`:
```
substituters = https://cache.nixos.org/ https://pub-solar.cachix.org
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= pub-solar.cachix.org-1:ZicXIxKgdxMtgSJECWR8iihZxHRvu8ObL4n2cuBmtos=
```
Pushing to the https://pub-solar.cachix.org binary cache (in this example, we push the
package `run-erpnext` and its dependencies):
```
nix develop
nix build --json .#run-erpnext \
| jq -r '.[].outputs | to_entries[].value' \
| cachix push pub-solar
```
### NixOS VM
```
nix build '.#nixosConfigurations.test-vm.config.system.build.vm'
./result/bin/run-nixos-vm
# In the VM, use root & empty password to login
# Watch erpnext startup:
# journalctl -fu erpnext.service
# Open http://localhost:8081 in your browser
# User: Administrator
# Password: admin
```
### Docker
```
docker run -d --name erpnext-redis-socketio -p 12311:6379 redis:latest
docker run -d --name erpnext-redis-queue -p 6379:6379 redis:latest
docker run -d --name erpnext-db -p 3306:3306 -e MARIADB_ROOT_PASSWORD=password -e MARIADB_DATABASE=erpnext -e MARIADB_USER=erpnext -e MARIADB_PASSWORD=erpnext mariadb:latest --collation-server=utf8mb4_unicode_ci
nix build .#runErpNext
./result/bin/runErpNext
nix build .#run-erpnext
./result/bin/run-erpnext
# new terminal
nix shell nixpkgs#nginx
@ -13,3 +49,12 @@ nginx -c /tmp/erpnext/nginx-erpnext.conf -g "daemon off;"
# User: Administrator
# Password: admin
```
### Links:
- https://erpnext.com
- https://docs.erpnext.com/docs/v14/user/manual/en/setting-up
- https://discuss.frappe.io/t/installing-the-docker-image-on-a-local-machine-without-letsencrypt-so-we-can-access-it-with-http-localhost/87585/7
- https://github.com/frappe/frappe_docker/blob/main/images/production/Containerfile
- https://github.com/frappe/bench
- https://github.com/frappe/erpnext
- https://github.com/frappe/frappe

View File

@ -1,5 +1,28 @@
{
"nodes": {
"devshell": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1685972731,
"narHash": "sha256-VpwVUthxs3AFgvWxGTHu+KVDnS/zT3xkCtmjX2PjNQs=",
"owner": "numtide",
"repo": "devshell",
"rev": "6b2554d28d46bfa6e24b941e999a145760dad0e1",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1685655444,
@ -16,26 +39,10 @@
"type": "github"
}
},
"pip2nix": {
"flake": false,
"locked": {
"lastModified": 1681921436,
"narHash": "sha256-jrUOMhpOFxrgCXNgMWz475nKZdMiSQb0+nbaIqQORSM=",
"owner": "nix-community",
"repo": "pip2nix",
"rev": "2ad8bd4c841116a1b9ab7853a53ed2d38e0ab93f",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "pip2nix",
"type": "github"
}
},
"root": {
"inputs": {
"devshell": "devshell",
"nixpkgs": "nixpkgs",
"pip2nix": "pip2nix",
"systems": "systems"
}
},

View File

@ -2,42 +2,71 @@
description = "Dev Setup";
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, systems, pip2nix, ...}:
inputs.systems.url = "github:nix-systems/default";
inputs.devshell.url = "github:numtide/devshell";
inputs.devshell.inputs.nixpkgs.follows = "nixpkgs";
inputs.devshell.inputs.systems.follows = "systems";
outputs = {self, nixpkgs, systems, devshell }:
let
eachSystem = nixpkgs.lib.genAttrs (import systems);
pkgs = import nixpkgs {
system = "x86_64-linux";
overlays = [
(import ./python-overlay.nix)
(import ./overlay.nix)
];
};
# Nixpkgs instantiated for system types in nix-systems
nixpkgsFor = eachSystem (system:
import nixpkgs {
inherit system;
overlays = [
self.overlays.default
self.overlays.pythonOverlay
devshell.overlays.default
];
}
);
in
{
packages = eachSystem (system: {
devEnv = pkgs.buildEnv {
name = "erpnext-nix-dev-env";
paths = [
pkgs.dasel
overlays = {
default = (import ./overlay.nix);
pythonOverlay = (import ./python-overlay.nix);
};
devShells = eachSystem (system:
let
pkgs = nixpkgsFor.${system};
in
{
default = pkgs.devshell.mkShell {
# Add additional packages you'd like to be available in your devshell
# PATH here
devshell.packages = with pkgs; [
];
commands = [
{
help = pkgs.cachix.meta.description;
name = pkgs.cachix.pname;
package = pkgs.cachix;
}
];
bash.extra = ''
'';
};
inherit pkgs;
run-erpnext = pkgs.run-erpnext;
pip2nix = import "${pip2nix}/default.nix" { inherit pkgs; pythonPackages = "python310Packages"; };
erpnext = pkgs.python3-erpnext.pkgs.erpnext;
bench = pkgs.python3-erpnext.pkgs.bench;
pythonPkgs = pkgs.python3-erpnext.pkgs;
});
nixosConfigurations = {
packages = eachSystem (system:
let
pkgs = nixpkgsFor.${system};
in
{
run-erpnext = pkgs.run-erpnext;
erpnext = pkgs.python3.pkgs.erpnext;
bench = pkgs.python3.pkgs.bench;
});
nixosConfigurations =
let
system = "x86_64-linux";
pkgs = nixpkgsFor.${system};
in
{
test-vm = nixpkgs.lib.nixosSystem {
inherit pkgs;
system = "x86_64-linux";
inherit system pkgs;
modules = [./test-vm/configuration.nix];
};
};

View File

@ -1,7 +1,7 @@
self: super: {
run-erpnext = self.callPackage ./scripts/run-erpnext.nix {};
frappe-erpnext-assets = self.callPackage ./node/frappe-erpnext-assets.nix {};
erpnext-app = self.callPackage ./node/erpnext-app.nix {};
frappe-app = self.callPackage ./node/frappe-app.nix {};
erpnext-nginx-conf = self.callPackage ./nginx-erpnext-conf.nix {};
final: prev: {
run-erpnext = final.callPackage ./scripts/run-erpnext.nix {};
frappe-erpnext-assets = final.callPackage ./node/frappe-erpnext-assets.nix {};
erpnext-app = final.callPackage ./node/erpnext-app.nix {};
frappe-app = final.callPackage ./node/frappe-app.nix {};
erpnext-nginx-conf = final.callPackage ./nginx-erpnext-conf.nix {};
}

View File

@ -1,111 +1,50 @@
self: super: {
python3-erpnext = super.python3.override {
packageOverrides = pyself: pysuper: {
bench = pyself.callPackage ./python/bench.nix {};
erpnext = pyself.callPackage ./python/erpnext.nix {};
frappe = pyself.callPackage ./python/frappe.nix {};
final: prev: {
python3 = prev.python3.override {
packageOverrides = pyFinal: pyPrev: {
bench = pyFinal.callPackage ./python/bench.nix {};
erpnext = pyFinal.callPackage ./python/erpnext.nix {};
frappe = pyFinal.callPackage ./python/frappe.nix {};
email-reply-parser = pyself.callPackage ./python/email-reply-parser.nix {};
git-url-parse = pyself.callPackage ./python/git-url-parse.nix {};
gocardless-pro = pyself.callPackage ./python/gocardless-pro.nix {};
honcho = pyself.callPackage ./python/honcho.nix {};
jsonobject = pyself.callPackage ./python/jsonobject.nix {};
maxminddb-geolite2 = pyself.callPackage ./python/maxminddb-geolite2.nix {};
posthog = pyself.callPackage ./python/posthog.nix {};
psycopg2-binary = pyself.callPackage ./python/psycopg2-binary.nix {};
pypdf2 = pyself.callPackage ./python/pypdf2.nix {};
pypika = pyself.callPackage ./python/pypika.nix {};
python-youtube = pyself.callPackage ./python/python-youtube.nix {};
rauth = pyself.callPackage ./python/rauth.nix {};
redisearch = pyself.callPackage ./python/redisearch.nix {};
rejson = pyself.callPackage ./python/rejson.nix {};
taxjar = pyself.callPackage ./python/taxjar.nix {};
traceback-with-variables = pyself.callPackage ./python/traceback-with-variables.nix {};
email-reply-parser = pyFinal.callPackage ./python/email-reply-parser.nix {};
git-url-parse = pyFinal.callPackage ./python/git-url-parse.nix {};
gocardless-pro = pyFinal.callPackage ./python/gocardless-pro.nix {};
honcho = pyFinal.callPackage ./python/honcho.nix {};
jsonobject = pyFinal.callPackage ./python/jsonobject.nix {};
maxminddb-geolite2 = pyFinal.callPackage ./python/maxminddb-geolite2.nix {};
posthog = pyFinal.callPackage ./python/posthog.nix {};
psycopg2-binary = pyFinal.callPackage ./python/psycopg2-binary.nix {};
pypdf2 = pyFinal.callPackage ./python/pypdf2.nix {};
pypika = pyFinal.callPackage ./python/pypika.nix {};
python-youtube = pyFinal.callPackage ./python/python-youtube.nix {};
rauth = pyFinal.callPackage ./python/rauth.nix {};
redisearch = pyFinal.callPackage ./python/redisearch.nix {};
rejson = pyFinal.callPackage ./python/rejson.nix {};
taxjar = pyFinal.callPackage ./python/taxjar.nix {};
traceback-with-variables = pyFinal.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=";
# };
#}));
bleach = pysuper.bleach.overridePythonAttrs (oldAttrs: (rec {
bleach = pyPrev.bleach.overridePythonAttrs (oldAttrs: (rec {
version = "3.3.1";
src = pysuper.fetchPypi {
src = pyPrev.fetchPypi {
inherit version;
inherit (oldAttrs) pname;
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=";
# };
#}));
plaid-python = pysuper.plaid-python.overridePythonAttrs (oldAttrs: (rec {
plaid-python = pyPrev.plaid-python.overridePythonAttrs (oldAttrs: (rec {
version = "7.2.1";
src = pysuper.fetchPypi {
src = pyPrev.fetchPypi {
inherit version;
inherit (oldAttrs) pname;
sha256 = "sha256-ryrTJug3fIyG2XGE9gwL5BzXH1B1IB39szMcyF1N5RM=";
};
propagatedBuildInputs = [ pysuper.requests ];
checkInputs = [ pysuper.pytest ];
propagatedBuildInputs = [ pyPrev.requests ];
checkInputs = [ pyPrev.pytest ];
# Integration tests require API keys and internet access
checkPhase = "py.test -rxs ./tests/unit";
checkPhase = "pyPrev.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;
#}));
tweepy = pysuper.tweepy.overridePythonAttrs (oldAttrs: (rec {
tweepy = pyPrev.tweepy.overridePythonAttrs (oldAttrs: (rec {
version = "3.10.0";
src = pysuper.fetchPypi {
src = pyPrev.fetchPypi {
inherit version;
inherit (oldAttrs) pname;
sha256 = "sha256-duaVS4BspHDdqHf1fbh5L/8GoL66DtQ+/DgFdx458Go=";
@ -113,14 +52,6 @@ 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=";
# };
#}));
};
};
}

View File

@ -53,10 +53,4 @@ buildPythonPackage rec {
python-stdnum
frappe
];
#nativeCheckInputs = [
# bench
#];
#checkPhase = ''
# bench --site test_site run-tests --app erpnext
#'';
}

View File

@ -208,17 +208,4 @@ 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

@ -128,11 +128,11 @@
systemd.services.erpnext =
let
penv = pkgs.python3-erpnext.buildEnv.override {
penv = pkgs.python3.buildEnv.override {
extraLibs = [
pkgs.python3-erpnext.pkgs.frappe
pkgs.python3-erpnext.pkgs.erpnext
pkgs.python3-erpnext.pkgs.bench
pkgs.python3.pkgs.frappe
pkgs.python3.pkgs.erpnext
pkgs.python3.pkgs.bench
];
};
appsFile = pkgs.writeText "erpnext-apps.txt" ''
@ -166,7 +166,7 @@
packages = [ pkgs.mariadb-client pkgs.nodejs penv ];
};
script = ''
export PYTHON_PATH=${penv}/${pkgs.python3-erpnext.sitePackages}
export PYTHON_PATH=${penv}/${pkgs.python3.sitePackages}
export PATH="${pkgs.mariadb-client}/bin:${pkgs.nodejs}/bin:${penv}/bin:$PATH"
# Upstream initializes the DB with this command